summaryrefslogtreecommitdiff
path: root/implementation
diff options
context:
space:
mode:
Diffstat (limited to 'implementation')
-rw-r--r--implementation/configuration/include/configuration.hpp89
-rw-r--r--implementation/configuration/include/configuration_impl.hpp117
-rw-r--r--implementation/configuration/include/internal.hpp.in105
-rw-r--r--implementation/configuration/include/service.hpp4
-rw-r--r--implementation/configuration/include/servicegroup.hpp27
-rw-r--r--implementation/configuration/src/configuration.cpp9
-rw-r--r--implementation/configuration/src/configuration_impl.cpp737
-rw-r--r--implementation/endpoints/include/buffer.hpp3
-rw-r--r--implementation/endpoints/include/client_endpoint_impl.hpp18
-rw-r--r--implementation/endpoints/include/endpoint.hpp4
-rw-r--r--implementation/endpoints/include/endpoint_definition.hpp14
-rw-r--r--implementation/endpoints/include/endpoint_host.hpp2
-rw-r--r--implementation/endpoints/include/endpoint_impl.hpp16
-rw-r--r--implementation/endpoints/include/local_client_endpoint_impl.hpp124
-rw-r--r--implementation/endpoints/include/local_server_endpoint_impl.hpp211
-rw-r--r--implementation/endpoints/include/server_endpoint_impl.hpp13
-rw-r--r--implementation/endpoints/include/tcp_client_endpoint_impl.hpp13
-rw-r--r--implementation/endpoints/include/tcp_server_endpoint_impl.hpp24
-rw-r--r--implementation/endpoints/include/udp_client_endpoint_impl.hpp11
-rw-r--r--implementation/endpoints/include/udp_server_endpoint_impl.hpp10
-rw-r--r--implementation/endpoints/include/virtual_server_endpoint_impl.hpp62
-rw-r--r--implementation/endpoints/src/client_endpoint_impl.cpp67
-rw-r--r--implementation/endpoints/src/endpoint_definition.cpp33
-rw-r--r--implementation/endpoints/src/endpoint_impl.cpp33
-rw-r--r--implementation/endpoints/src/local_client_endpoint_impl.cpp77
-rw-r--r--implementation/endpoints/src/local_server_endpoint_impl.cpp528
-rw-r--r--implementation/endpoints/src/server_endpoint_impl.cpp81
-rw-r--r--implementation/endpoints/src/tcp_client_endpoint_impl.cpp109
-rw-r--r--implementation/endpoints/src/tcp_server_endpoint_impl.cpp585
-rw-r--r--implementation/endpoints/src/udp_client_endpoint_impl.cpp101
-rw-r--r--implementation/endpoints/src/udp_server_endpoint_impl.cpp505
-rw-r--r--implementation/endpoints/src/virtual_server_endpoint_impl.cpp114
-rw-r--r--implementation/logging/include/logger.hpp48
-rw-r--r--implementation/logging/include/logger_impl.hpp6
-rw-r--r--implementation/logging/src/logger_impl.cpp16
-rw-r--r--implementation/message/include/message_header_impl.hpp6
-rw-r--r--implementation/message/src/deserializer.cpp202
-rw-r--r--implementation/message/src/message_base_impl.cpp46
-rw-r--r--implementation/message/src/message_header_impl.cpp87
-rw-r--r--implementation/message/src/message_impl.cpp26
-rw-r--r--implementation/message/src/payload_impl.cpp42
-rw-r--r--implementation/message/src/serializer.cpp128
-rw-r--r--implementation/routing/include/event.hpp9
-rw-r--r--implementation/routing/include/eventgroupinfo.hpp5
-rw-r--r--implementation/routing/include/routing_manager.hpp13
-rw-r--r--implementation/routing/include/routing_manager_host.hpp2
-rw-r--r--implementation/routing/include/routing_manager_impl.hpp107
-rw-r--r--implementation/routing/include/routing_manager_proxy.hpp70
-rw-r--r--implementation/routing/include/routing_manager_stub.hpp10
-rw-r--r--implementation/routing/include/routing_manager_stub_host.hpp18
-rw-r--r--implementation/routing/include/servicegroup.hpp41
-rw-r--r--implementation/routing/include/serviceinfo.hpp6
-rw-r--r--implementation/routing/src/event.cpp116
-rw-r--r--implementation/routing/src/eventgroupinfo.cpp65
-rw-r--r--implementation/routing/src/routing_manager_impl.cpp1520
-rw-r--r--implementation/routing/src/routing_manager_proxy.cpp401
-rw-r--r--implementation/routing/src/routing_manager_stub.cpp740
-rw-r--r--implementation/routing/src/servicegroup.cpp70
-rw-r--r--implementation/routing/src/serviceinfo.cpp9
-rw-r--r--implementation/runtime/include/application_impl.hpp53
-rw-r--r--implementation/runtime/include/runtime_impl.hpp11
-rw-r--r--implementation/runtime/src/application_impl.cpp311
-rw-r--r--implementation/runtime/src/runtime_impl.cpp20
-rw-r--r--implementation/service_discovery/include/defines.hpp19
-rwxr-xr-ximplementation/service_discovery/include/entry_impl.hpp8
-rw-r--r--implementation/service_discovery/include/enumeration_types.hpp7
-rw-r--r--implementation/service_discovery/include/ip_option_impl.hpp41
-rw-r--r--implementation/service_discovery/include/ipv4_option_impl.hpp17
-rw-r--r--implementation/service_discovery/include/ipv6_option_impl.hpp19
-rwxr-xr-ximplementation/service_discovery/include/message_impl.hpp2
-rw-r--r--implementation/service_discovery/include/service_discovery.hpp7
-rw-r--r--implementation/service_discovery/include/service_discovery_fsm.hpp11
-rw-r--r--implementation/service_discovery/include/service_discovery_host.hpp16
-rw-r--r--implementation/service_discovery/include/service_discovery_impl.hpp56
-rw-r--r--implementation/service_discovery/include/subscription.hpp5
-rwxr-xr-ximplementation/service_discovery/src/configuration_option_impl.cpp8
-rwxr-xr-ximplementation/service_discovery/src/entry_impl.cpp25
-rwxr-xr-ximplementation/service_discovery/src/eventgroupentry_impl.cpp7
-rw-r--r--implementation/service_discovery/src/ip_option_impl.cpp59
-rw-r--r--implementation/service_discovery/src/ipv4_option_impl.cpp46
-rwxr-xr-ximplementation/service_discovery/src/ipv6_option_impl.cpp43
-rwxr-xr-ximplementation/service_discovery/src/message_impl.cpp44
-rwxr-xr-ximplementation/service_discovery/src/option_impl.cpp21
-rw-r--r--implementation/service_discovery/src/service_discovery_fsm.cpp99
-rw-r--r--implementation/service_discovery/src/service_discovery_impl.cpp816
-rw-r--r--implementation/service_discovery/src/subscription.cpp10
-rw-r--r--implementation/utility/include/byteorder.hpp42
-rw-r--r--implementation/utility/include/utility.hpp13
-rw-r--r--implementation/utility/src/utility.cpp88
89 files changed, 5953 insertions, 3626 deletions
diff --git a/implementation/configuration/include/configuration.hpp b/implementation/configuration/include/configuration.hpp
new file mode 100644
index 0000000..2f106ee
--- /dev/null
+++ b/implementation/configuration/include/configuration.hpp
@@ -0,0 +1,89 @@
+// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef VSOMEIP_CONFIGURATION_HPP
+#define VSOMEIP_CONFIGURATION_HPP
+
+#include <map>
+#include <memory>
+#include <set>
+#include <string>
+
+#include <boost/asio/ip/address.hpp>
+#include <boost/log/trivial.hpp>
+
+#include <vsomeip/export.hpp>
+#include <vsomeip/defines.hpp>
+#include <vsomeip/primitive_types.hpp>
+
+#include "internal.hpp"
+
+namespace vsomeip {
+
+class event;
+
+class VSOMEIP_EXPORT configuration {
+public:
+ static std::shared_ptr<configuration> get(
+ const std::set<std::string> &_input = std::set<std::string>());
+ static void reset();
+ virtual ~configuration() {}
+
+ virtual const boost::asio::ip::address & get_unicast_address() const = 0;
+ virtual bool is_v4() const = 0;
+ virtual bool is_v6() const = 0;
+
+ virtual bool has_console_log() const = 0;
+ virtual bool has_file_log() const = 0;
+ virtual bool has_dlt_log() const = 0;
+ virtual const std::string & get_logfile() const = 0;
+ virtual boost::log::trivial::severity_level get_loglevel() const = 0;
+
+ virtual const std::string & get_routing_host() const = 0;
+
+ virtual std::string get_unicast_address(service_t _service,
+ instance_t _instance) const = 0;
+ virtual std::string get_multicast_address(service_t _service,
+ instance_t _instance) const = 0;
+ virtual uint16_t get_multicast_port(service_t _service,
+ instance_t _instance) const = 0;
+ virtual uint16_t get_multicast_group(service_t _service,
+ instance_t _instance) const = 0;
+ virtual uint16_t get_reliable_port(service_t _service,
+ instance_t _instance) const = 0;
+ virtual bool is_someip(service_t _service, instance_t _instance) const = 0;
+ virtual bool has_enabled_magic_cookies(std::string _address,
+ uint16_t _port) const = 0;
+ virtual uint16_t get_unreliable_port(service_t _service,
+ instance_t _instance) const = 0;
+
+ virtual std::set<std::pair<service_t, instance_t> > get_remote_services() const = 0;
+
+ virtual client_t get_id(const std::string &_name) const = 0;
+ virtual std::size_t get_num_dispatchers(const std::string &_name) const = 0;
+
+ virtual std::uint32_t get_max_message_size_local() const = 0;
+ virtual std::uint32_t get_message_size_reliable(const std::string& _address,
+ std::uint16_t _port) const = 0;
+
+ // Service Discovery configuration
+ virtual bool is_sd_enabled() const = 0;
+
+ virtual const std::string & get_sd_multicast() const = 0;
+ virtual uint16_t get_sd_port() const = 0;
+ virtual const std::string & get_sd_protocol() const = 0;
+
+ virtual int32_t get_sd_initial_delay_min() const = 0;
+ virtual int32_t get_sd_initial_delay_max() const = 0;
+ virtual int32_t get_sd_repetitions_base_delay() const = 0;
+ virtual uint8_t get_sd_repetitions_max() const = 0;
+ virtual ttl_t get_sd_ttl() const = 0;
+ virtual int32_t get_sd_cyclic_offer_delay() const = 0;
+ virtual int32_t get_sd_request_response_delay() const = 0;
+};
+
+} // namespace vsomeip
+
+#endif // VSOMEIP_CONFIGURATION_HPP
diff --git a/implementation/configuration/include/configuration_impl.hpp b/implementation/configuration/include/configuration_impl.hpp
index 8a57633..04f4a22 100644
--- a/implementation/configuration/include/configuration_impl.hpp
+++ b/implementation/configuration/include/configuration_impl.hpp
@@ -9,10 +9,11 @@
#include <map>
#include <memory>
#include <mutex>
+#include <vector>
#include <boost/property_tree/ptree.hpp>
-#include <vsomeip/configuration.hpp>
+#include "configuration.hpp"
namespace vsomeip {
namespace cfg {
@@ -20,16 +21,20 @@ namespace cfg {
struct service;
struct servicegroup;
-class configuration_impl: public configuration {
+class VSOMEIP_EXPORT configuration_impl: public configuration {
public:
- static configuration * get(const std::string &_path);
+ static std::shared_ptr<configuration> get(
+ const std::set<std::string> &_input);
+ static void reset();
configuration_impl();
+ configuration_impl(const configuration_impl &_cfg);
virtual ~configuration_impl();
- bool load(const std::string &_path);
+ void load(const boost::property_tree::ptree &_tree);
+ void load_log(const std::vector<boost::property_tree::ptree> &_trees);
- const boost::asio::ip::address & get_unicast() const;
+ const boost::asio::ip::address & get_unicast_address() const;
bool is_v4() const;
bool is_v6() const;
@@ -39,18 +44,7 @@ public:
const std::string & get_logfile() const;
boost::log::trivial::severity_level get_loglevel() const;
- std::string get_group(service_t _service, instance_t _instance) const;
- std::set<std::string> get_servicegroups() const;
-
- bool is_local_servicegroup(const std::string &_name) const;
- int32_t get_min_initial_delay(const std::string &_name) const;
- int32_t get_max_initial_delay(const std::string &_name) const;
- int32_t get_repetition_base_delay(const std::string &_name) const;
- uint8_t get_repetition_max(const std::string &_name) const;
- int32_t get_cyclic_offer_delay(const std::string &_name) const;
- int32_t get_cyclic_request_delay(const std::string &_name) const;
-
- std::string get_unicast(service_t _service, instance_t _instance) const;
+ std::string get_unicast_address(service_t _service, instance_t _instance) const;
std::string get_multicast_address(service_t _service,
instance_t _instance) const;
uint16_t get_multicast_port(service_t _service,
@@ -63,56 +57,65 @@ public:
uint16_t get_unreliable_port(service_t _service,
instance_t _instance) const;
- const std::string & get_routing_host() const;
+ bool is_someip(service_t _service, instance_t _instance) const;
- bool is_service_discovery_enabled() const;
- const std::string & get_service_discovery_multicast() const;
- uint16_t get_service_discovery_port() const;
- const std::string & get_service_discovery_protocol() const;
+ 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;
std::set<std::pair<service_t, instance_t> > get_remote_services() const;
- std::map<service_t,
- std::map<instance_t,
- std::map<eventgroup_t,
- std::set<event_t> > > > get_eventgroups() const;
- std::map<service_t,
- std::map<instance_t,
- std::set<event_t> > > get_events() const;
- void set_event(std::shared_ptr<event> &_event) const;
+ std::uint32_t get_max_message_size_local() const;
+ 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;
private:
- bool get_someip_configuration(boost::property_tree::ptree &_tree);
- bool get_logging_configuration(boost::property_tree::ptree &_tree);
- bool get_services_configuration(boost::property_tree::ptree &_tree);
- bool get_routing_configuration(boost::property_tree::ptree &_tree);
- bool get_service_discovery_configuration(
- boost::property_tree::ptree &_tree);
- bool get_applications_configuration(boost::property_tree::ptree &_tree);
-
- bool get_servicegroup_configuration(
- const boost::property_tree::ptree &_tree);
- bool get_delays_configuration(std::shared_ptr<servicegroup> &_group,
+ void get_logging_configuration(const boost::property_tree::ptree &_tree);
+
+ void get_someip_configuration(const boost::property_tree::ptree &_tree);
+ void get_services_configuration(const boost::property_tree::ptree &_tree);
+ void get_payload_sizes_configuration(const boost::property_tree::ptree &_tree);
+ void get_routing_configuration(const boost::property_tree::ptree &_tree);
+ void get_service_discovery_configuration(
const boost::property_tree::ptree &_tree);
- bool get_service_configuration(std::shared_ptr<servicegroup> &_group,
+ void get_applications_configuration(const boost::property_tree::ptree &_tree);
+
+ void get_servicegroup_configuration(
const boost::property_tree::ptree &_tree);
- bool get_event_configuration(std::shared_ptr<service> &_service,
+ void get_delays_configuration(const boost::property_tree::ptree &_tree);
+ void get_service_configuration(const boost::property_tree::ptree &_tree,
+ const std::string &_unicast_address);
+ void get_event_configuration(std::shared_ptr<service> &_service,
const boost::property_tree::ptree &_tree);
- bool get_eventgroup_configuration(std::shared_ptr<service> &_service,
+ void get_eventgroup_configuration(std::shared_ptr<service> &_service,
const boost::property_tree::ptree &_tree);
- bool get_application_configuration(
+ void get_application_configuration(
const boost::property_tree::ptree &_tree);
servicegroup * find_servicegroup(const std::string &_name) const;
service * find_service(service_t _service, instance_t _instance) const;
private:
- static std::map<std::string, configuration *> the_configurations;
+ static std::shared_ptr<configuration_impl> the_configuration;
static std::mutex mutex_;
+protected:
// Configuration data
boost::asio::ip::address unicast_;
@@ -122,21 +125,31 @@ private:
std::string logfile_;
boost::log::trivial::severity_level loglevel_;
- std::map<std::string, std::shared_ptr<servicegroup> > servicegroups_;
+ std::map<std::string, std::pair<client_t, std::size_t>> applications_;
+
std::map<service_t,
std::map<instance_t,
std::shared_ptr<service> > > services_;
std::string routing_host_;
- bool is_service_discovery_enabled_;
- std::string service_discovery_multicast_;
- uint16_t service_discovery_port_;
- std::string service_discovery_protocol_;
+ bool is_sd_enabled_;
+ std::string sd_protocol_;
+ std::string sd_multicast_;
+ uint16_t sd_port_;
- std::map<std::string, std::pair<client_t, std::size_t>> applications_;
+ int32_t sd_initial_delay_min_;
+ int32_t sd_initial_delay_max_;
+ int32_t sd_repetitions_base_delay_;
+ uint8_t sd_repetitions_max_;
+ ttl_t sd_ttl_;
+ int32_t sd_cyclic_offer_delay_;
+ int32_t sd_request_response_delay_;
std::map<std::string, std::set<uint16_t> > magic_cookies_;
+
+ std::map<std::string, std::map<std::uint16_t, std::uint32_t>> message_sizes_;
+ std::uint32_t max_configured_message_size_;
};
} // namespace cfg
diff --git a/implementation/configuration/include/internal.hpp.in b/implementation/configuration/include/internal.hpp.in
index 4038b55..3700a89 100644
--- a/implementation/configuration/include/internal.hpp.in
+++ b/implementation/configuration/include/internal.hpp.in
@@ -8,53 +8,88 @@
#include <cstdint>
-namespace vsomeip {
+#define VSOMEIP_ENV_APPLICATION_NAME "VSOMEIP_APPLICATION_NAME"
+#define VSOMEIP_ENV_CONFIGURATION "VSOMEIP_CONFIGURATION"
+#define VSOMEIP_ENV_CONFIGURATION_MODULE "VSOMEIP_CONFIGURATION_MODULE"
+
+#define VSOMEIP_DEFAULT_CONFIGURATION_FILE "/etc/vsomeip.json"
+#define VSOMEIP_LOCAL_CONFIGURATION_FILE "./vsomeip.json"
+
+#define VSOMEIP_DEFAULT_CONFIGURATION_FOLDER "/etc/vsomeip"
+#define VSOMEIP_LOCAL_CONFIGURATION_FOLDER "./vsomeip"
+
+#define VSOMEIP_BASE_PATH "/tmp/vsomeip-"
+
+#define VSOMEIP_SD_LIBRARY "libvsomeip-sd.so.@VSOMEIP_MAJOR_VERSION@"
+#define VSOMEIP_SD_RUNTIME_SYMBOL VSOMEIP_SD_RUNTIME
+#define VSOMEIP_SD_RUNTIME_SYMBOL_STRING "VSOMEIP_SD_RUNTIME"
+
+#define VSOMEIP_ROUTING "@VSOMEIP_ROUTING@"
+#define VSOMEIP_ROUTING_CLIENT 0
-#define VSOMEIP_SD_LIBRARY "libvsomeip-sd.so.@VSOMEIP_MAJOR_VERSION@"
-#define VSOMEIP_SD_RUNTIME_SYMBOL VSOMEIP_SD_RUNTIME
-#define VSOMEIP_SD_RUNTIME_SYMBOL_STRING "VSOMEIP_SD_RUNTIME"
+#ifdef WIN32
+#define VSOMEIP_INTERNAL_BASE_PORT 51234
+#endif
-#define VSOMEIP_ROUTING_CLIENT 0
+#define VSOMEIP_UNICAST_ADDRESS "@VSOMEIP_UNICAST_ADDRESS@"
-#define VSOMEIP_DEFAULT_CONNECT_TIMEOUT 100
-#define VSOMEIP_DEFAULT_FLUSH_TIMEOUT 1000
+#define VSOMEIP_DEFAULT_CONNECT_TIMEOUT 100
+#define VSOMEIP_DEFAULT_FLUSH_TIMEOUT 1000
-#define VSOMEIP_DEFAULT_WATCHDOG_CYCLE 1000
-#define VSOMEIP_DEFAULT_WATCHDOG_TIMEOUT 1000
-#define VSOMEIP_DEFAULT_MAX_MISSING_PONGS 3
+#define VSOMEIP_DEFAULT_WATCHDOG_CYCLE 5000
+#define VSOMEIP_DEFAULT_WATCHDOG_TIMEOUT 5000
+#define VSOMEIP_DEFAULT_MAX_MISSING_PONGS 3
-#define VSOMEIP_INVALID_PORT 0xFFFF
+#define VSOMEIP_COMMAND_HEADER_SIZE 7
-#define VSOMEIP_COMMAND_HEADER_SIZE 7
+#define VSOMEIP_COMMAND_TYPE_POS 0
+#define VSOMEIP_COMMAND_CLIENT_POS 1
+#define VSOMEIP_COMMAND_SIZE_POS_MIN 3
+#define VSOMEIP_COMMAND_SIZE_POS_MAX 5
+#define VSOMEIP_COMMAND_PAYLOAD_POS 7
-#define VSOMEIP_COMMAND_TYPE_POS 0
-#define VSOMEIP_COMMAND_CLIENT_POS 1
-#define VSOMEIP_COMMAND_SIZE_POS_MIN 3
-#define VSOMEIP_COMMAND_SIZE_POS_MAX 5
-#define VSOMEIP_COMMAND_PAYLOAD_POS 7
+#define VSOMEIP_REGISTER_APPLICATION 0x00
+#define VSOMEIP_DEREGISTER_APPLICATION 0x01
+#define VSOMEIP_APPLICATION_LOST 0x02
+#define VSOMEIP_ROUTING_INFO 0x03
-#define VSOMEIP_REGISTER_APPLICATION 0x00
-#define VSOMEIP_DEREGISTER_APPLICATION 0x01
-#define VSOMEIP_APPLICATION_LOST 0x02
-#define VSOMEIP_ROUTING_INFO 0x03
+#define VSOMEIP_PING 0x0E
+#define VSOMEIP_PONG 0x0F
-#define VSOMEIP_PING 0x0E
-#define VSOMEIP_PONG 0x0F
+#define VSOMEIP_OFFER_SERVICE 0x10
+#define VSOMEIP_STOP_OFFER_SERVICE 0x11
+#define VSOMEIP_SUBSCRIBE 0x12
+#define VSOMEIP_UNSUBSCRIBE 0x13
+#define VSOMEIP_REQUEST_SERVICE 0x14
+#define VSOMEIP_RELEASE_SERVICE 0x15
-#define VSOMEIP_OFFER_SERVICE 0x10
-#define VSOMEIP_STOP_OFFER_SERVICE 0x11
-#define VSOMEIP_SUBSCRIBE 0x12
-#define VSOMEIP_UNSUBSCRIBE 0x13
-#define VSOMEIP_REQUEST_SERVICE 0x14
+#define VSOMEIP_SEND 0x17
+#define VSOMEIP_NOTIFY 0x18
-#define VSOMEIP_SEND 0x17
-#define VSOMEIP_SET 0x18
+#define VSOMEIP_REGISTER_EVENT 0x19
+#define VSOMEIP_UNREGISTER_EVENT 0x1A
+
+#define VSOMEIP_OFFER_SERVICE_COMMAND_SIZE 20
+#define VSOMEIP_REQUEST_SERVICE_COMMAND_SIZE 21
+#define VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE 11
+#define VSOMEIP_SUBSCRIBE_COMMAND_SIZE 18
+#define VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE 13
+#define VSOMEIP_REGISTER_EVENT_COMMAND_SIZE 15
+#define VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE 13
+
+#include <mutex>
+
+#define VSOMEIP_DATA_ID 0x677D
+#define VSOMEIP_SHM_NAME "/vsomeip"
+#define VSOMEIP_DIAGNOSIS_ADDRESS @VSOMEIP_DIAGNOSIS_ADDRESS@
+
+namespace vsomeip {
-#define VSOMEIP_OFFER_SERVICE_COMMAND_SIZE 20
-#define VSOMEIP_REQUEST_SERVICE_COMMAND_SIZE 21
-#define VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE 11
-#define VSOMEIP_SUBSCRIBE_COMMAND_SIZE 18
-#define VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE 13
+struct configuration_data_t {
+ std::mutex mutex_;
+ unsigned short next_client_id_;
+ unsigned short ref_;
+};
} // namespace vsomeip
diff --git a/implementation/configuration/include/service.hpp b/implementation/configuration/include/service.hpp
index 067dc41..bbe235e 100644
--- a/implementation/configuration/include/service.hpp
+++ b/implementation/configuration/include/service.hpp
@@ -20,6 +20,8 @@ struct service {
service_t service_;
instance_t instance_;
+ std::string unicast_address_;
+
uint16_t reliable_;
uint16_t unreliable_;
@@ -27,7 +29,7 @@ struct service {
uint16_t multicast_port_;
eventgroup_t multicast_group_;
- bool use_magic_cookies_;
+ std::string protocol_;
std::shared_ptr<servicegroup> group_;
std::map<event_t, std::shared_ptr<event> > events_;
diff --git a/implementation/configuration/include/servicegroup.hpp b/implementation/configuration/include/servicegroup.hpp
deleted file mode 100644
index e44d79f..0000000
--- a/implementation/configuration/include/servicegroup.hpp
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef VSOMEIP_CFG_SERVICEGROUP_HPP
-#define VSOMEIP_CFG_SERVICEGROUP_HPP
-
-namespace vsomeip {
-namespace cfg {
-
-struct servicegroup {
- std::string name_; // Name of the ServiceGroup
- std::string unicast_; // either "local" or an IP address
-
- uint32_t min_initial_delay_;
- uint32_t max_initial_delay_;
- uint32_t repetition_base_delay_;
- uint32_t cyclic_offer_delay_;
- uint32_t cyclic_request_delay_;
- uint8_t repetition_max_;
-};
-
-} // namespace cfg
-} // namespace vsomeip
-
-#endif // VSOMEIP_CFG_SERVICEGROUP_HPP
diff --git a/implementation/configuration/src/configuration.cpp b/implementation/configuration/src/configuration.cpp
index 9a11b22..9bc90d4 100644
--- a/implementation/configuration/src/configuration.cpp
+++ b/implementation/configuration/src/configuration.cpp
@@ -7,8 +7,13 @@
namespace vsomeip {
-configuration * configuration::get(const std::string &_path) {
- return cfg::configuration_impl::get(_path);
+std::shared_ptr<configuration> configuration::get(
+ const std::set<std::string> &_input) {
+ return cfg::configuration_impl::get(_input);
+}
+
+void configuration::reset() {
+ cfg::configuration_impl::reset();
}
} // namespace vsomeip
diff --git a/implementation/configuration/src/configuration_impl.cpp b/implementation/configuration/src/configuration_impl.cpp
index 591a3dc..66a1219 100644
--- a/implementation/configuration/src/configuration_impl.cpp
+++ b/implementation/configuration/src/configuration_impl.cpp
@@ -4,12 +4,17 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <fstream>
-#include <map>
+#include <set>
#include <sstream>
#define WIN32_LEAN_AND_MEAN
+#if defined ( WIN32 )
+#define __func__ __FUNCTION__
+#endif
+
#include <boost/algorithm/string.hpp>
+#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
#include <boost/property_tree/json_parser.hpp>
@@ -18,102 +23,162 @@
#include "../include/configuration_impl.hpp"
#include "../include/event.hpp"
#include "../include/eventgroup.hpp"
-#include "../include/servicegroup.hpp"
#include "../include/service.hpp"
+#include "../include/internal.hpp"
#include "../../logging/include/logger_impl.hpp"
#include "../../routing/include/event.hpp"
#include "../../service_discovery/include/defines.hpp"
+#include "../../utility/include/utility.hpp"
namespace vsomeip {
namespace cfg {
-std::map<std::string, configuration *> configuration_impl::the_configurations;
+std::shared_ptr<configuration_impl> configuration_impl::the_configuration;
std::mutex configuration_impl::mutex_;
-configuration * configuration_impl::get(const std::string &_path) {
- configuration *its_configuration(0);
-
- bool is_freshly_loaded(false);
- {
- std::lock_guard<std::mutex> its_lock(mutex_);
-
- auto found_configuration = the_configurations.find(_path);
- if (found_configuration != the_configurations.end()) {
- its_configuration = found_configuration->second;
- } else {
- its_configuration = new configuration_impl;
- if (its_configuration->load(_path)) {
- the_configurations[_path] = its_configuration;
- is_freshly_loaded = true;
- } else {
- delete its_configuration;
- its_configuration = 0;
+std::shared_ptr<configuration> configuration_impl::get(
+ const std::set<std::string> &_input) {
+ std::shared_ptr<configuration> its_configuration;
+ std::lock_guard<std::mutex> its_lock(mutex_);
+
+ if (!the_configuration) {
+ the_configuration = std::make_shared<configuration_impl>();
+ std::vector<boost::property_tree::ptree> its_tree_set;
+
+ // Load logger configuration first
+ for (auto i : _input) {
+ if (utility::is_file(i)) {
+ boost::property_tree::ptree its_tree;
+ try {
+ boost::property_tree::json_parser::read_json(i, its_tree);
+ its_tree_set.push_back(its_tree);
+ }
+ catch (...) {
+ }
+ } else if (utility::is_folder(i)) {
+ boost::filesystem::path its_path(i);
+ for (auto j = boost::filesystem::directory_iterator(its_path);
+ j != boost::filesystem::directory_iterator();
+ j++) {
+ auto its_file_path = j->path();
+ if (!boost::filesystem::is_directory(its_file_path)) {
+ std::string its_name = its_file_path.string();
+ boost::property_tree::ptree its_tree;
+ try {
+ boost::property_tree::json_parser::read_json(its_name, its_tree);
+ its_tree_set.push_back(its_tree);
+ }
+ catch (...) {
+ }
+ }
+ }
}
}
+
+ // Load log configuration
+ the_configuration->load_log(its_tree_set);
+
+ // Load other configuration parts
+ for (auto t : its_tree_set)
+ the_configuration->load(t);
}
- if (is_freshly_loaded)
- logger_impl::init(_path);
+ return the_configuration;
+}
- return its_configuration;
+void configuration_impl::reset() {
+ the_configuration.reset();
}
configuration_impl::configuration_impl() :
- has_console_log_(true), has_file_log_(false), has_dlt_log_(false), logfile_(
- "/tmp/vsomeip.log"), loglevel_(
- boost::log::trivial::severity_level::info), routing_host_(
- "vsomeipd"), is_service_discovery_enabled_(false) {
+ has_console_log_(true),
+ has_file_log_(false),
+ has_dlt_log_(false),
+ logfile_("/tmp/vsomeip.log"),
+ loglevel_(boost::log::trivial::severity_level::info),
+ is_sd_enabled_(VSOMEIP_SD_DEFAULT_ENABLED),
+ sd_protocol_(VSOMEIP_SD_DEFAULT_PROTOCOL),
+ sd_multicast_(VSOMEIP_SD_DEFAULT_MULTICAST),
+ sd_port_(VSOMEIP_SD_DEFAULT_PORT),
+ sd_initial_delay_min_(VSOMEIP_SD_DEFAULT_INITIAL_DELAY_MIN),
+ sd_initial_delay_max_(VSOMEIP_SD_DEFAULT_INITIAL_DELAY_MAX),
+ sd_repetitions_base_delay_(VSOMEIP_SD_DEFAULT_REPETITIONS_BASE_DELAY),
+ sd_repetitions_max_(VSOMEIP_SD_DEFAULT_REPETITIONS_MAX),
+ sd_ttl_(VSOMEIP_SD_DEFAULT_TTL),
+ sd_cyclic_offer_delay_(VSOMEIP_SD_DEFAULT_CYCLIC_OFFER_DELAY),
+ sd_request_response_delay_(VSOMEIP_SD_DEFAULT_REQUEST_RESPONSE_DELAY),
+ max_configured_message_size_(0) {
- unicast_ = unicast_.from_string("127.0.0.1");
+ unicast_ = unicast_.from_string(VSOMEIP_UNICAST_ADDRESS);
}
-configuration_impl::~configuration_impl() {
+configuration_impl::configuration_impl(const configuration_impl &_other) :
+ max_configured_message_size_(0) {
+
+ applications_.insert(_other.applications_.begin(), _other.applications_.end());
+ services_.insert(_other.services_.begin(), _other.services_.end());
+
+ unicast_ = _other.unicast_;
+
+ has_console_log_ = _other.has_console_log_;
+ has_file_log_ = _other.has_file_log_;
+ has_dlt_log_ = _other.has_dlt_log_;
+ logfile_ = _other.logfile_;
+
+ loglevel_ = _other.loglevel_;
+
+ routing_host_ = _other.routing_host_;
+
+ is_sd_enabled_ = _other.is_sd_enabled_;
+ sd_multicast_ = _other.sd_multicast_;
+ sd_port_ = _other.sd_port_;
+ sd_protocol_ = _other.sd_protocol_;
+
+ sd_initial_delay_min_ = _other.sd_initial_delay_min_;
+ sd_initial_delay_max_ = _other.sd_initial_delay_max_;
+ sd_repetitions_base_delay_= _other.sd_repetitions_base_delay_;
+ sd_repetitions_max_ = _other.sd_repetitions_max_;
+ sd_ttl_ = _other.sd_ttl_;
+ sd_cyclic_offer_delay_= _other.sd_cyclic_offer_delay_;
+ sd_request_response_delay_= _other.sd_request_response_delay_;
+
+ magic_cookies_.insert(_other.magic_cookies_.begin(), _other.magic_cookies_.end());
}
-bool configuration_impl::load(const std::string &_path) {
- bool is_loaded(true);
- boost::property_tree::ptree its_tree;
+configuration_impl::~configuration_impl() {
+}
+void configuration_impl::load(const boost::property_tree::ptree &_tree) {
try {
- boost::property_tree::json_parser::read_json(_path, its_tree);
-
// Read the configuration data
- is_loaded = get_someip_configuration(its_tree);
- is_loaded = get_logging_configuration(its_tree);
- is_loaded = is_loaded && get_services_configuration(its_tree);
- is_loaded = is_loaded && get_routing_configuration(its_tree);
- is_loaded = is_loaded && get_service_discovery_configuration(its_tree);
- is_loaded = is_loaded && get_applications_configuration(its_tree);
+ get_someip_configuration(_tree);
+ get_services_configuration(_tree);
+ get_payload_sizes_configuration(_tree);
+ get_routing_configuration(_tree);
+ get_service_discovery_configuration(_tree);
+ get_applications_configuration(_tree);
} catch (std::exception &e) {
- std::cerr << e.what() << std::endl;
- is_loaded = false;
}
-
- return is_loaded;
}
-bool configuration_impl::get_someip_configuration(
- boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
- try {
- std::string its_value = _tree.get<std::string>("unicast");
- unicast_ = unicast_.from_string(its_value);
- } catch (...) {
- is_loaded = false;
- }
- return is_loaded;
+void configuration_impl::load_log(const std::vector<boost::property_tree::ptree> &_trees) {
+ // Read the logger configuration(s)
+ for (auto t : _trees)
+ get_logging_configuration(t);
+
+ // Initialize logger
+ logger_impl::init(the_configuration);
}
-bool configuration_impl::get_logging_configuration(
- boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
+void configuration_impl::get_logging_configuration(
+ const boost::property_tree::ptree &_tree) {
try {
auto its_logging = _tree.get_child("logging");
for (auto i = its_logging.begin(); i != its_logging.end(); ++i) {
std::string its_key(i->first);
if (its_key == "console") {
- std::string its_value(i->second.data());
- has_console_log_ = (its_value == "true");
+ std::string its_value(i->second.data());
+ has_console_log_ = (its_value == "true");
} else if (its_key == "file") {
for (auto j : i->second) {
std::string its_sub_key(j.first);
@@ -129,127 +194,187 @@ bool configuration_impl::get_logging_configuration(
has_dlt_log_ = (its_value == "true");
} else if (its_key == "level") {
std::string its_value(i->second.data());
- loglevel_ = (its_value == "trace" ?
- boost::log::trivial::severity_level::trace :
- (its_value == "debug" ?
- boost::log::trivial::severity_level::debug :
- (its_value == "info" ?
- boost::log::trivial::severity_level::info :
- (its_value == "warning" ?
- boost::log::trivial::severity_level::warning :
- (its_value == "error" ?
- boost::log::trivial::severity_level::error :
- (its_value == "fatal" ?
- boost::log::trivial::severity_level::fatal :
- boost::log::trivial::severity_level::info))))));
+ loglevel_
+ = (its_value == "trace" ?
+ boost::log::trivial::severity_level::trace :
+ (its_value == "debug" ?
+ boost::log::trivial::severity_level::debug :
+ (its_value == "info" ?
+ boost::log::trivial::severity_level::info :
+ (its_value == "warning" ?
+ boost::log::trivial::severity_level::warning :
+ (its_value == "error" ?
+ boost::log::trivial::severity_level::error :
+ (its_value == "fatal" ?
+ boost::log::trivial::severity_level::fatal :
+ boost::log::trivial::severity_level::info))))));
}
}
} catch (...) {
- is_loaded = false;
}
- return is_loaded;
}
-bool configuration_impl::get_services_configuration(
- boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
+void configuration_impl::get_someip_configuration(
+ const boost::property_tree::ptree &_tree) {
try {
- auto its_services = _tree.get_child("servicegroups");
+ std::string its_value = _tree.get<std::string>("unicast");
+ unicast_ = unicast_.from_string(its_value);
+ } catch (...) {
+ }
+}
+
+void configuration_impl::get_services_configuration(
+ const boost::property_tree::ptree &_tree) {
+ try {
+ auto its_services = _tree.get_child("services");
for (auto i = its_services.begin(); i != its_services.end(); ++i)
- is_loaded = is_loaded && get_servicegroup_configuration(i->second);
+ get_service_configuration(i->second, "");
} catch (...) {
- // This section is optional!
+ try {
+ auto its_servicegroups = _tree.get_child("servicegroups");
+ for (auto i = its_servicegroups.begin(); i != its_servicegroups.end(); ++i)
+ get_servicegroup_configuration(i->second);
+ } catch (...) {
+ // intentionally left empty!
+ }
}
- return is_loaded;
}
-bool configuration_impl::get_servicegroup_configuration(
+void configuration_impl::get_payload_sizes_configuration(
const boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
+ const std::string payload_sizes("payload-sizes");
try {
- std::shared_ptr<servicegroup> its_servicegroup(
- std::make_shared<servicegroup>());
- its_servicegroup->unicast_ = "local"; // Default
+ if (_tree.get_child_optional(payload_sizes)) {
+ const std::string unicast("unicast");
+ const std::string ports("ports");
+ const std::string port("port");
+ const std::string max_payload_size("max-payload-size");
+ auto its_ps = _tree.get_child(payload_sizes);
+ for (auto i = its_ps.begin(); i != its_ps.end(); ++i) {
+ if (!i->second.get_child_optional(unicast)
+ || !i->second.get_child_optional(ports)) {
+ continue;
+ }
+ std::string its_unicast(i->second.get_child(unicast).data());
+ for (auto j = i->second.get_child(ports).begin();
+ j != i->second.get_child(ports).end(); ++j) {
+
+ if (!j->second.get_child_optional(port)
+ || !j->second.get_child_optional(max_payload_size)) {
+ continue;
+ }
+
+ std::uint16_t its_port = ILLEGAL_PORT;
+ std::uint32_t its_message_size = 0;
+
+ try {
+ std::string p(j->second.get_child(port).data());
+ its_port = static_cast<std::uint16_t>(std::stoul(p.c_str(),
+ NULL, 10));
+ std::string s(j->second.get_child(max_payload_size).data());
+ // add 16 Byte for the SOME/IP header
+ its_message_size = static_cast<std::uint32_t>(std::stoul(
+ s.c_str(),
+ NULL, 10) + 16);
+ } catch (const std::exception &e) {
+ VSOMEIP_ERROR << __func__ << ":" << e.what();
+ }
+
+ if (its_port == ILLEGAL_PORT || its_message_size == 0) {
+ continue;
+ }
+ if(max_configured_message_size_ < its_message_size) {
+ max_configured_message_size_ = its_message_size;
+ }
+
+ message_sizes_[its_unicast][its_port] = its_message_size;
+ }
+ }
+ }
+ } catch (...) {
+ }
+}
+
+void configuration_impl::get_servicegroup_configuration(
+ const boost::property_tree::ptree &_tree) {
+ try {
+ std::string its_unicast_address("local");
+
for (auto i = _tree.begin(); i != _tree.end(); ++i) {
std::string its_key(i->first);
- if (its_key == "name") {
- its_servicegroup->name_ = i->second.data();
- } else if (its_key == "unicast") {
- its_servicegroup->unicast_ = i->second.data();
- } else if (its_key == "delays") {
- is_loaded = is_loaded
- && get_delays_configuration(its_servicegroup,
- i->second);
+ if (its_key == "unicast") {
+ its_unicast_address = i->second.data();
+ break;
+ }
+ }
+
+ for (auto i = _tree.begin(); i != _tree.end(); ++i) {
+ std::string its_key(i->first);
+ if (its_key == "delays") {
+ get_delays_configuration(i->second);
} else if (its_key == "services") {
for (auto j = i->second.begin(); j != i->second.end(); ++j)
- is_loaded = is_loaded
- && get_service_configuration(its_servicegroup,
- j->second);
+ get_service_configuration(j->second, its_unicast_address);
}
}
- servicegroups_[its_servicegroup->name_] = its_servicegroup;
} catch (...) {
- is_loaded = false;
}
- return is_loaded;
}
-bool configuration_impl::get_delays_configuration(
- std::shared_ptr<servicegroup> &_group,
+void configuration_impl::get_delays_configuration(
const boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
try {
std::stringstream its_converter;
for (auto i = _tree.begin(); i != _tree.end(); ++i) {
std::string its_key(i->first);
if (its_key == "initial") {
- _group->min_initial_delay_ = i->second.get<uint32_t>("minimum");
- _group->max_initial_delay_ = i->second.get<uint32_t>("maximum");
+ sd_initial_delay_min_ = i->second.get<uint32_t>("minimum");
+ sd_initial_delay_max_ = i->second.get<uint32_t>("maximum");
} else if (its_key == "repetition-base") {
its_converter << std::dec << i->second.data();
- its_converter >> _group->repetition_base_delay_;
+ its_converter >> sd_repetitions_base_delay_;
} else if (its_key == "repetition-max") {
int tmp_repetition_max;
its_converter << std::dec << i->second.data();
its_converter >> tmp_repetition_max;
- _group->repetition_max_ = tmp_repetition_max;
+ sd_repetitions_max_ = uint8_t(tmp_repetition_max);
} else if (its_key == "cyclic-offer") {
its_converter << std::dec << i->second.data();
- its_converter >> _group->cyclic_offer_delay_;
+ its_converter >> sd_cyclic_offer_delay_;
} else if (its_key == "cyclic-request") {
its_converter << std::dec << i->second.data();
- its_converter >> _group->cyclic_request_delay_;
+ its_converter >> sd_request_response_delay_;
}
its_converter.str("");
its_converter.clear();
}
} catch (...) {
- is_loaded = false;
}
- return is_loaded;
}
-bool configuration_impl::get_service_configuration(
- std::shared_ptr<servicegroup> &_group,
- const boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
+void configuration_impl::get_service_configuration(
+ const boost::property_tree::ptree &_tree,
+ const std::string &_unicast_address) {
try {
+ bool is_loaded(true);
bool use_magic_cookies(false);
std::shared_ptr<service> its_service(std::make_shared<service>());
its_service->reliable_ = its_service->unreliable_ = ILLEGAL_PORT;
- its_service->use_magic_cookies_ = false;
- its_service->group_ = _group;
+ its_service->unicast_address_ = _unicast_address;
its_service->multicast_address_ = "";
its_service->multicast_port_ = ILLEGAL_PORT;
its_service->multicast_group_ = 0xFFFF; // TODO: use symbolic constant
+ its_service->protocol_ = "someip";
for (auto i = _tree.begin(); i != _tree.end(); ++i) {
std::string its_key(i->first);
std::string its_value(i->second.data());
std::stringstream its_converter;
- if (its_key == "reliable") {
+ if (its_key == "unicast") {
+ its_service->unicast_address_ = its_value;
+ } else if (its_key == "reliable") {
try {
its_value = i->second.get_child("port").data();
its_converter << its_value;
@@ -259,8 +384,8 @@ bool configuration_impl::get_service_configuration(
its_converter >> its_service->reliable_;
}
try {
- its_value =
- i->second.get_child("enable-magic-cookies").data();
+ its_value
+ = i->second.get_child("enable-magic-cookies").data();
use_magic_cookies = ("true" == its_value);
} catch (...) {
@@ -277,6 +402,8 @@ bool configuration_impl::get_service_configuration(
its_converter >> its_service->multicast_port_;
} catch (...) {
}
+ } else if (its_key == "protocol") {
+ its_service->protocol_ = its_value;
} else if (its_key == "events") {
get_event_configuration(its_service, i->second);
} else if (its_key == "eventgroups") {
@@ -309,24 +436,18 @@ bool configuration_impl::get_service_configuration(
if (is_loaded) {
services_[its_service->service_][its_service->instance_] =
its_service;
- }
-
- if (use_magic_cookies) {
- std::string its_unicast(_group->unicast_);
- if (its_unicast == "local")
- its_unicast = unicast_.to_string();
- magic_cookies_[its_unicast].insert(its_service->reliable_);
+ if (use_magic_cookies) {
+ magic_cookies_[its_service->unicast_address_].insert(
+ its_service->reliable_);
+ }
}
} catch (...) {
- is_loaded = false;
}
- return is_loaded;
}
-bool configuration_impl::get_event_configuration(
+void configuration_impl::get_event_configuration(
std::shared_ptr<service> &_service,
const boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
for (auto i = _tree.begin(); i != _tree.end(); ++i) {
event_t its_event_id(0);
bool its_is_field(false);
@@ -361,12 +482,11 @@ bool configuration_impl::get_event_configuration(
}
}
}
- return is_loaded;
}
-bool configuration_impl::get_eventgroup_configuration(
+
+void configuration_impl::get_eventgroup_configuration(
std::shared_ptr<service> &_service,
const boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
bool is_multicast;
for (auto i = _tree.begin(); i != _tree.end(); ++i) {
is_multicast = false;
@@ -423,68 +543,80 @@ bool configuration_impl::get_eventgroup_configuration(
_service->eventgroups_[its_eventgroup->id_] = its_eventgroup;
}
}
- return is_loaded;
}
-bool configuration_impl::get_routing_configuration(
- boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
+void configuration_impl::get_routing_configuration(
+ const boost::property_tree::ptree &_tree) {
try {
auto its_routing = _tree.get_child("routing");
routing_host_ = its_routing.data();
} catch (...) {
- is_loaded = false;
}
- return is_loaded;
}
-bool configuration_impl::get_service_discovery_configuration(
- boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
+void configuration_impl::get_service_discovery_configuration(
+ const boost::property_tree::ptree &_tree) {
try {
auto its_service_discovery = _tree.get_child("service-discovery");
for (auto i = its_service_discovery.begin();
i != its_service_discovery.end(); ++i) {
std::string its_key(i->first);
std::string its_value(i->second.data());
+ std::stringstream its_converter;
if (its_key == "enable") {
- is_service_discovery_enabled_ = (its_value == "true");
+ is_sd_enabled_ = (its_value == "true");
} else if (its_key == "multicast") {
- service_discovery_multicast_ = its_value;
+ sd_multicast_ = its_value;
} else if (its_key == "port") {
- std::stringstream its_converter;
its_converter << its_value;
- its_converter >> service_discovery_port_;
+ its_converter >> sd_port_;
} else if (its_key == "protocol") {
- service_discovery_protocol_ = its_value;
+ sd_protocol_ = its_value;
+ } else if (its_key == "initial_delay_min") {
+ its_converter << its_value;
+ its_converter >> sd_initial_delay_min_;
+ } else if (its_key == "initial_delay_max") {
+ its_converter << its_value;
+ its_converter >> sd_initial_delay_max_;
+ } else if (its_key == "repetitions_base_delay") {
+ its_converter << its_value;
+ its_converter >> sd_repetitions_base_delay_;
+ } else if (its_key == "repetitions_max") {
+ int tmp;
+ its_converter << its_value;
+ its_converter >> tmp;
+ sd_repetitions_max_ = (uint8_t)tmp;
+ } else if (its_key == "ttl") {
+ its_converter << its_value;
+ its_converter >> sd_ttl_;
+ } else if (its_key == "cyclic_offer_delay") {
+ its_converter << its_value;
+ its_converter >> sd_cyclic_offer_delay_;
+ } else if (its_key == "request_response_delay") {
+ its_converter << its_value;
+ its_converter >> sd_request_response_delay_;
}
}
} catch (...) {
- is_loaded = false;
}
-
- return is_loaded;
}
-bool configuration_impl::get_applications_configuration(
- boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
+void configuration_impl::get_applications_configuration(
+ const boost::property_tree::ptree &_tree) {
try {
std::stringstream its_converter;
auto its_applications = _tree.get_child("applications");
- for (auto i = its_applications.begin(); i != its_applications.end();
- ++i)
- is_loaded = is_loaded && get_application_configuration(i->second);
+ for (auto i = its_applications.begin();
+ i != its_applications.end();
+ ++i) {
+ get_application_configuration(i->second);
+ }
} catch (...) {
- is_loaded = false;
}
-
- return is_loaded;
}
-bool configuration_impl::get_application_configuration(
+void configuration_impl::get_application_configuration(
const boost::property_tree::ptree &_tree) {
- bool is_loaded(true);
std::string its_name("");
client_t its_id;
std::size_t its_num_dispatchers(0);
@@ -513,11 +645,10 @@ bool configuration_impl::get_application_configuration(
if (its_name != "" && its_id != 0) {
applications_[its_name] = {its_id, its_num_dispatchers};
}
- return is_loaded;
}
// Public interface
-const boost::asio::ip::address & configuration_impl::get_unicast() const {
+const boost::asio::ip::address & configuration_impl::get_unicast_address() const {
return unicast_;
}
@@ -549,107 +680,18 @@ boost::log::trivial::severity_level configuration_impl::get_loglevel() const {
return loglevel_;
}
-std::set<std::string> configuration_impl::get_servicegroups() const {
- std::set<std::string> its_keys;
- for (auto i : servicegroups_)
- its_keys.insert(i.first);
- return its_keys;
-}
-
-bool configuration_impl::is_local_servicegroup(const std::string &_name) const {
- bool is_local(false);
-
- servicegroup *its_servicegroup = find_servicegroup(_name);
- if (its_servicegroup) {
- is_local = (its_servicegroup->unicast_ == "local"
- || its_servicegroup->unicast_ == get_unicast().to_string());
- }
-
- return is_local;
-}
-
-int32_t configuration_impl::get_min_initial_delay(
- const std::string &_name) const {
- int32_t its_delay = 0;
-
- servicegroup *its_servicegroup = find_servicegroup(_name);
- if (its_servicegroup)
- its_delay = its_servicegroup->min_initial_delay_;
-
- return its_delay;
-}
-
-int32_t configuration_impl::get_max_initial_delay(
- const std::string &_name) const {
- int32_t its_delay = 0;
-
- servicegroup *its_servicegroup = find_servicegroup(_name);
- if (its_servicegroup)
- its_delay = its_servicegroup->max_initial_delay_;
-
- return its_delay;
-}
-
-int32_t configuration_impl::get_repetition_base_delay(
- const std::string &_name) const {
- int32_t its_delay = 0;
-
- servicegroup *its_servicegroup = find_servicegroup(_name);
- if (its_servicegroup)
- its_delay = its_servicegroup->repetition_base_delay_;
-
- return its_delay;
-}
-
-uint8_t configuration_impl::get_repetition_max(const std::string &_name) const {
- uint8_t its_max = 0;
-
- servicegroup *its_servicegroup = find_servicegroup(_name);
- if (its_servicegroup)
- its_max = its_servicegroup->repetition_max_;
-
- return its_max;
-}
-
-int32_t configuration_impl::get_cyclic_offer_delay(
- const std::string &_name) const {
- uint32_t its_delay = 0;
-
- servicegroup *its_servicegroup = find_servicegroup(_name);
- if (its_servicegroup)
- its_delay = its_servicegroup->cyclic_offer_delay_;
-
- return its_delay;
-}
-
-int32_t configuration_impl::get_cyclic_request_delay(
- const std::string &_name) const {
- uint32_t its_delay = 0;
-
- servicegroup *its_servicegroup = find_servicegroup(_name);
- if (its_servicegroup)
- its_delay = its_servicegroup->cyclic_request_delay_;
-
- return its_delay;
-}
-
-std::string configuration_impl::get_group(service_t _service,
+std::string configuration_impl::get_unicast_address(service_t _service,
instance_t _instance) const {
- std::string its_group("default");
+ std::string its_unicast_address("");
service *its_service = find_service(_service, _instance);
- if (nullptr != its_service) {
- its_group = its_service->group_->name_;
+ if (its_service) {
+ its_unicast_address = its_service->unicast_address_;
}
- return its_group;
-}
-std::string configuration_impl::get_unicast(service_t _service,
- instance_t _instance) const {
- std::string its_unicast("");
- service *its_service = find_service(_service, _instance);
- if (its_service)
- its_unicast = its_service->group_->unicast_;
- return its_unicast;
+ if (its_unicast_address == "local" || its_unicast_address == "") {
+ its_unicast_address = get_unicast_address().to_string();
+ }
+ return its_unicast_address;
}
std::string configuration_impl::get_multicast_address(service_t _service,
@@ -681,8 +723,7 @@ uint16_t configuration_impl::get_multicast_group(service_t _service,
uint16_t configuration_impl::get_reliable_port(service_t _service,
instance_t _instance) const {
- uint16_t its_reliable = ILLEGAL_PORT;
-
+ uint16_t its_reliable(ILLEGAL_PORT);
service *its_service = find_service(_service, _instance);
if (its_service)
its_reliable = its_service->reliable_;
@@ -690,6 +731,15 @@ uint16_t configuration_impl::get_reliable_port(service_t _service,
return its_reliable;
}
+bool configuration_impl::is_someip(service_t _service,
+ instance_t _instance) const {
+ service *its_service = find_service(_service, _instance);
+ if (its_service)
+ return (its_service->protocol_ == "someip");
+ return true; // we need to explicitely configure a service to
+ // be something else than SOME/IP
+}
+
bool configuration_impl::has_enabled_magic_cookies(std::string _address,
uint16_t _port) const {
bool has_enabled(false);
@@ -718,24 +768,6 @@ const std::string & configuration_impl::get_routing_host() const {
return routing_host_;
}
-bool configuration_impl::is_service_discovery_enabled() const {
- return is_service_discovery_enabled_;
-}
-
-const std::string &
-configuration_impl::get_service_discovery_protocol() const {
- return service_discovery_protocol_;
-}
-
-const std::string &
-configuration_impl::get_service_discovery_multicast() const {
- return service_discovery_multicast_;
-}
-
-uint16_t configuration_impl::get_service_discovery_port() const {
- return service_discovery_port_;
-}
-
client_t configuration_impl::get_id(const std::string &_name) const {
client_t its_client = 0;
@@ -764,76 +796,13 @@ configuration_impl::get_remote_services() const {
std::set<std::pair<service_t, instance_t> > its_remote_services;
for (auto i : services_) {
for (auto j : i.second) {
- if (j.second->group_->unicast_ != "local")
+ if (j.second->unicast_address_ != "local" && j.second->unicast_address_ != "")
its_remote_services.insert(std::make_pair(i.first, j.first));
}
}
return its_remote_services;
}
-std::map<service_t,
- std::map<instance_t, std::map<eventgroup_t, std::set<event_t> > > >
-configuration_impl::get_eventgroups() const {
- std::map<service_t,
- std::map<instance_t,
- std::map<eventgroup_t, std::set<event_t> > > > its_eventgroups;
- for (auto i : services_) {
- for (auto j : i.second) {
- if (j.second->group_->unicast_ == "local") {
- for (auto k : j.second->eventgroups_) {
- for (auto l : k.second->events_) {
- its_eventgroups[i.first][j.first]
- [k.second->id_].insert(l->id_);
- }
- }
- }
- }
- }
- return its_eventgroups;
-}
-
-std::map<service_t, std::map<instance_t, std::set<event_t> > >
-configuration_impl::get_events() const {
- std::map<service_t, std::map<instance_t, std::set<event_t> > > its_events;
- for (auto i : services_) {
- for (auto j : i.second) {
- if (j.second->group_->unicast_ == "local") {
- for (auto k : j.second->events_) {
- its_events[i.first][j.first].insert(k.first);
- }
- }
- }
- }
- return its_events;
-}
-
-void configuration_impl::set_event(
- std::shared_ptr<vsomeip::event> &_event) const {
- auto found_service = services_.find(_event->get_service());
- if (found_service != services_.end()) {
- auto found_instance = found_service->second.find(
- _event->get_instance());
- if (found_instance != found_service->second.end()) {
- auto found_event = found_instance->second->events_.find(
- _event->get_event());
- if (found_event != found_instance->second->events_.end()) {
- _event->set_field(found_event->second->is_field_);
- _event->set_reliable(found_event->second->is_reliable_);
- }
- }
- }
-}
-
-servicegroup *configuration_impl::find_servicegroup(
- const std::string &_name) const {
- servicegroup *its_servicegroup(0);
- auto find_servicegroup = servicegroups_.find(_name);
- if (find_servicegroup != servicegroups_.end()) {
- its_servicegroup = find_servicegroup->second.get();
- }
- return its_servicegroup;
-}
-
service *configuration_impl::find_service(service_t _service,
instance_t _instance) const {
service *its_service(0);
@@ -847,5 +816,81 @@ service *configuration_impl::find_service(service_t _service,
return its_service;
}
+std::uint32_t configuration_impl::get_max_message_size_local() const {
+ uint32_t its_max_message_size = VSOMEIP_MAX_LOCAL_MESSAGE_SIZE;
+ if (VSOMEIP_MAX_TCP_MESSAGE_SIZE > its_max_message_size) {
+ its_max_message_size = VSOMEIP_MAX_TCP_MESSAGE_SIZE;
+ }
+ if (VSOMEIP_MAX_UDP_MESSAGE_SIZE > its_max_message_size) {
+ its_max_message_size = VSOMEIP_MAX_UDP_MESSAGE_SIZE;
+ }
+ if(its_max_message_size < max_configured_message_size_) {
+ its_max_message_size = max_configured_message_size_;
+ }
+
+ // add sizes of the the routing_manager_proxy's messages
+ // to the routing_manager stub
+ return std::uint32_t(its_max_message_size
+ + VSOMEIP_COMMAND_HEADER_SIZE + sizeof(instance_t)
+ + sizeof(bool) + sizeof(bool));
+}
+
+std::uint32_t configuration_impl::get_message_size_reliable(
+ const std::string& _address, std::uint16_t _port) const {
+ auto its_address = message_sizes_.find(_address);
+ if(its_address != message_sizes_.end()) {
+ auto its_port = its_address->second.find(_port);
+ if(its_port != its_address->second.end()) {
+ return its_port->second;
+ }
+ }
+ return VSOMEIP_MAX_TCP_MESSAGE_SIZE;
+}
+
+// Service Discovery configuration
+bool configuration_impl::is_sd_enabled() const {
+ return is_sd_enabled_;
+}
+
+const std::string & configuration_impl::get_sd_multicast() const {
+ return sd_multicast_;
+}
+
+uint16_t configuration_impl::get_sd_port() const {
+ return sd_port_;
+}
+
+const std::string & configuration_impl::get_sd_protocol() const {
+ return sd_protocol_;
+}
+
+int32_t configuration_impl::get_sd_initial_delay_min() const {
+ return sd_initial_delay_min_;
+}
+
+int32_t configuration_impl::get_sd_initial_delay_max() const {
+ return sd_initial_delay_max_;
+}
+
+int32_t configuration_impl::get_sd_repetitions_base_delay() const {
+ return sd_repetitions_base_delay_;
+}
+
+uint8_t configuration_impl::get_sd_repetitions_max() const {
+ return sd_repetitions_max_;
+}
+
+ttl_t configuration_impl::get_sd_ttl() const {
+ return sd_ttl_;
+}
+
+int32_t configuration_impl::get_sd_cyclic_offer_delay() const {
+ return sd_cyclic_offer_delay_;
+}
+
+int32_t configuration_impl::get_sd_request_response_delay() const {
+ return sd_request_response_delay_;
+}
+
} // namespace config
} // namespace vsomeip
diff --git a/implementation/endpoints/include/buffer.hpp b/implementation/endpoints/include/buffer.hpp
index f76c8d1..5641117 100644
--- a/implementation/endpoints/include/buffer.hpp
+++ b/implementation/endpoints/include/buffer.hpp
@@ -14,8 +14,7 @@
namespace vsomeip {
-typedef std::array<byte_t, VSOMEIP_PACKET_SIZE> packet_buffer_t;
-typedef std::shared_ptr<packet_buffer_t> packet_buffer_ptr_t;
+typedef std::vector<byte_t> receive_buffer_t;
typedef std::vector<byte_t> message_buffer_t;
typedef std::shared_ptr<message_buffer_t> message_buffer_ptr_t;
diff --git a/implementation/endpoints/include/client_endpoint_impl.hpp b/implementation/endpoints/include/client_endpoint_impl.hpp
index 0be6616..29f42a3 100644
--- a/implementation/endpoints/include/client_endpoint_impl.hpp
+++ b/implementation/endpoints/include/client_endpoint_impl.hpp
@@ -6,6 +6,7 @@
#ifndef VSOMEIP_CLIENT_ENDPOINT_IMPL_HPP
#define VSOMEIP_CLIENT_ENDPOINT_IMPL_HPP
+#include <condition_variable>
#include <deque>
#include <mutex>
#include <vector>
@@ -32,7 +33,8 @@ public:
typedef typename Protocol::endpoint endpoint_type;
client_endpoint_impl(std::shared_ptr<endpoint_host> _host,
- endpoint_type _remote, boost::asio::io_service &_io);
+ endpoint_type _remote, boost::asio::io_service &_io,
+ std::uint32_t _max_message_size);
virtual ~client_endpoint_impl();
bool send(const uint8_t *_data, uint32_t _size, bool _flush);bool send_to(
@@ -49,8 +51,7 @@ public:
public:
void connect_cbk(boost::system::error_code const &_error);
void wait_connect_cbk(boost::system::error_code const &_error);
- void send_cbk(message_buffer_ptr_t _buffer,
- boost::system::error_code const &_error, std::size_t _bytes);
+ void send_cbk(boost::system::error_code const &_error, std::size_t _bytes);
void flush_cbk(boost::system::error_code const &_error);
public:
@@ -58,24 +59,21 @@ public:
virtual void receive() = 0;
protected:
- virtual void send_queued(message_buffer_ptr_t) = 0;
+ virtual void send_queued() = 0;
socket_type socket_;
endpoint_type remote_;
boost::asio::system_timer flush_timer_;
boost::asio::system_timer connect_timer_;
- uint32_t connect_timeout_;bool is_connected_;
+ uint32_t connect_timeout_;
+ bool is_connected_;
// send data
message_buffer_ptr_t packetizer_;
-
- // receive data
- message_buffer_t message_;
+ std::deque<message_buffer_ptr_t> queue_;
std::mutex mutex_;
-
- uint32_t queued_;
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/endpoint.hpp b/implementation/endpoints/include/endpoint.hpp
index 49688ef..6acf164 100644
--- a/implementation/endpoints/include/endpoint.hpp
+++ b/implementation/endpoints/include/endpoint.hpp
@@ -42,6 +42,10 @@ public:
virtual unsigned short get_remote_port() const = 0;
virtual bool is_reliable() const = 0;
virtual bool is_local() const = 0;
+
+ virtual void increment_use_count() = 0;
+ virtual void decrement_use_count() = 0;
+ virtual uint32_t get_use_count() = 0;
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/endpoint_definition.hpp b/implementation/endpoints/include/endpoint_definition.hpp
index 30f53fd..d7fb3a2 100644
--- a/implementation/endpoints/include/endpoint_definition.hpp
+++ b/implementation/endpoints/include/endpoint_definition.hpp
@@ -6,6 +6,9 @@
#ifndef VSOMEIP_ENDPOINT_DEFINITION_HPP
#define VSOMEIP_ENDPOINT_DEFINITION_HPP
+#include <map>
+#include <memory>
+
#include <boost/asio/ip/address.hpp>
#include <vsomeip/export.hpp>
@@ -14,8 +17,7 @@ namespace vsomeip {
class endpoint_definition {
public:
- VSOMEIP_EXPORT endpoint_definition();
- VSOMEIP_EXPORT endpoint_definition(
+ VSOMEIP_EXPORT static std::shared_ptr<endpoint_definition> get(
const boost::asio::ip::address &_address,
uint16_t _port, bool _is_reliable);
@@ -31,11 +33,19 @@ public:
VSOMEIP_EXPORT bool is_reliable() const;
VSOMEIP_EXPORT void set_reliable(bool _is_reliable);
+ VSOMEIP_EXPORT endpoint_definition(
+ const boost::asio::ip::address &_address,
+ uint16_t _port, bool _is_reliable);
private:
boost::asio::ip::address address_;
uint16_t port_;
uint16_t remote_port_;
bool is_reliable_;
+
+ static std::map<boost::asio::ip::address,
+ std::map<uint16_t,
+ std::map<bool,
+ std::shared_ptr<endpoint_definition> > > > definitions_;
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/endpoint_host.hpp b/implementation/endpoints/include/endpoint_host.hpp
index af0c9b1..d526ab4 100644
--- a/implementation/endpoints/include/endpoint_host.hpp
+++ b/implementation/endpoints/include/endpoint_host.hpp
@@ -22,6 +22,8 @@ public:
virtual void on_disconnect(std::shared_ptr<endpoint> _endpoint) = 0;
virtual void on_message(const byte_t *_data, length_t _length,
endpoint *_receiver) = 0;
+ virtual void on_error(const byte_t *_data, length_t _length,
+ endpoint *_receiver) = 0;
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/endpoint_impl.hpp b/implementation/endpoints/include/endpoint_impl.hpp
index 5c6fe39..5d8350a 100644
--- a/implementation/endpoints/include/endpoint_impl.hpp
+++ b/implementation/endpoints/include/endpoint_impl.hpp
@@ -23,7 +23,8 @@ template<int MaxBufferSize>
class endpoint_impl: public endpoint {
public:
endpoint_impl(std::shared_ptr<endpoint_host> _adapter,
- boost::asio::io_service &_io);
+ boost::asio::io_service &_io,
+ std::uint32_t _max_message_size);
virtual ~endpoint_impl();
void enable_magic_cookies();
@@ -45,6 +46,10 @@ public:
unsigned short get_remote_port() const;
bool is_reliable() const;
+ void increment_use_count();
+ void decrement_use_count();
+ uint32_t get_use_count();
+
public:
// required
virtual bool is_client() const = 0;
@@ -53,7 +58,7 @@ public:
protected:
virtual bool is_magic_cookie() const;
- uint32_t find_magic_cookie(message_buffer_t &_buffer);
+ uint32_t find_magic_cookie(byte_t *_buffer, size_t _size);
protected:
// Reference to service context
@@ -62,10 +67,15 @@ protected:
// Reference to host
std::weak_ptr<endpoint_host> host_;
- bool is_supporting_magic_cookies_;bool has_enabled_magic_cookies_;
+ bool is_supporting_magic_cookies_;
+ bool has_enabled_magic_cookies_;
// Filter configuration
std::map<service_t, uint8_t> opened_;
+
+ std::uint32_t max_message_size_;
+
+ uint32_t use_count_;
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/local_client_endpoint_impl.hpp b/implementation/endpoints/include/local_client_endpoint_impl.hpp
index 9891ae4..97f01ce 100644
--- a/implementation/endpoints/include/local_client_endpoint_impl.hpp
+++ b/implementation/endpoints/include/local_client_endpoint_impl.hpp
@@ -1,59 +1,65 @@
-// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef VSOMEIP_LOCAL_CLIENT_ENDPOINT_IMPL_HPP
-#define VSOMEIP_LOCAL_CLIENT_ENDPOINT_IMPL_HPP
-
-#include <boost/asio/io_service.hpp>
-#include <boost/asio/local/stream_protocol.hpp>
-
-#ifdef WIN32
-#include <boost/asio/ip/tcp.hpp>
-#endif
-
-#include <vsomeip/defines.hpp>
-
-#include "client_endpoint_impl.hpp"
-
-namespace vsomeip {
-
-#ifdef WIN32
-typedef client_endpoint_impl<boost::asio::ip::tcp,
- VSOMEIP_MAX_TCP_MESSAGE_SIZE > local_client_endpoint_base_impl;
-#else
-typedef client_endpoint_impl<boost::asio::local::stream_protocol,
- VSOMEIP_MAX_LOCAL_MESSAGE_SIZE> local_client_endpoint_base_impl;
-#endif
-
-class local_client_endpoint_impl: public local_client_endpoint_base_impl {
-public:
- local_client_endpoint_impl(std::shared_ptr<endpoint_host> _host,
- endpoint_type _local,
- boost::asio::io_service &_io);
-
- virtual ~local_client_endpoint_impl();
-
- void start();
-
- void send_queued(message_buffer_ptr_t _data);
-
- bool is_local() const;
-
-private:
- void send_magic_cookie();
-
- void connect();
- void receive();
-
- void send_tag_cbk(boost::system::error_code const &_error,
- std::size_t _bytes);
- void receive_cbk(packet_buffer_ptr_t _buffer,
- boost::system::error_code const &_error,
- std::size_t _bytes);
-};
-
-} // namespace vsomeip
-
-#endif // VSOMEIP_LOCAL_CLIENT_ENDPOINT_IMPL_HPP
+// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef VSOMEIP_LOCAL_CLIENT_ENDPOINT_IMPL_HPP
+#define VSOMEIP_LOCAL_CLIENT_ENDPOINT_IMPL_HPP
+
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/local/stream_protocol.hpp>
+
+#ifdef WIN32
+#include <boost/asio/ip/tcp.hpp>
+#endif
+
+#include <vsomeip/defines.hpp>
+
+#include "client_endpoint_impl.hpp"
+
+namespace vsomeip {
+
+#ifdef WIN32
+typedef client_endpoint_impl<boost::asio::ip::tcp,
+ VSOMEIP_MAX_TCP_MESSAGE_SIZE > local_client_endpoint_base_impl;
+#else
+typedef client_endpoint_impl<boost::asio::local::stream_protocol,
+ VSOMEIP_MAX_LOCAL_MESSAGE_SIZE> local_client_endpoint_base_impl;
+#endif
+
+class local_client_endpoint_impl: public local_client_endpoint_base_impl {
+public:
+ local_client_endpoint_impl(std::shared_ptr<endpoint_host> _host,
+ endpoint_type _local,
+ boost::asio::io_service &_io,
+ std::uint32_t _max_message_size);
+
+ virtual ~local_client_endpoint_impl();
+
+ void start();
+
+ bool is_local() const;
+
+private:
+ void send_queued();
+
+ void send_start_tag();
+ void send_queued_data();
+ void send_end_tag();
+
+ void send_magic_cookie();
+
+ void connect();
+ void receive();
+
+ void send_start_tag_cbk(boost::system::error_code const &_error,
+ std::size_t _bytes);
+ void send_queued_data_cbk(boost::system::error_code const &_error,
+ std::size_t _bytes);
+ void receive_cbk(boost::system::error_code const &_error,
+ std::size_t _bytes);
+};
+
+} // namespace vsomeip
+
+#endif // VSOMEIP_LOCAL_CLIENT_ENDPOINT_IMPL_HPP
diff --git a/implementation/endpoints/include/local_server_endpoint_impl.hpp b/implementation/endpoints/include/local_server_endpoint_impl.hpp
index a47858a..626b30e 100644
--- a/implementation/endpoints/include/local_server_endpoint_impl.hpp
+++ b/implementation/endpoints/include/local_server_endpoint_impl.hpp
@@ -1,104 +1,107 @@
-// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef VSOMEIP_LOCAL_SERVER_ENDPOINT_IMPL_HPP
-#define VSOMEIP_LOCAL_SERVER_ENDPOINT_IMPL_HPP
-
-#include <map>
-
-#include <boost/asio/io_service.hpp>
-#include <boost/asio/local/stream_protocol.hpp>
-#include <boost/enable_shared_from_this.hpp>
-
-#ifdef WIN32
-#include <boost/asio/ip/tcp.hpp>
-#endif
-
-#include <vsomeip/defines.hpp>
-
-#include "buffer.hpp"
-#include "server_endpoint_impl.hpp"
-
-namespace vsomeip {
-
-#ifdef WIN32
-typedef server_endpoint_impl<boost::asio::ip::tcp,
- VSOMEIP_MAX_TCP_MESSAGE_SIZE > local_server_endpoint_base_impl;
-#else
-typedef server_endpoint_impl<boost::asio::local::stream_protocol,
- VSOMEIP_MAX_LOCAL_MESSAGE_SIZE> local_server_endpoint_base_impl;
-#endif
-
-class local_server_endpoint_impl: public local_server_endpoint_base_impl {
-
-public:
- local_server_endpoint_impl(std::shared_ptr<endpoint_host> _host,
- endpoint_type _local,
- boost::asio::io_service &_io);
- virtual ~local_server_endpoint_impl();
-
- void start();
- void stop();
-
- void restart();
- void receive();
-
- bool send_to(const std::shared_ptr<endpoint_definition>,
- const byte_t *_data, uint32_t _size, bool _flush);
- void send_queued(endpoint_type _target, message_buffer_ptr_t _data);
-
- endpoint_type get_remote() const;
- bool get_multicast(service_t, event_t, endpoint_type &) const;
-
- bool is_local() const;
-
-private:
- class connection: public boost::enable_shared_from_this<connection> {
-
- public:
- typedef boost::shared_ptr<connection> ptr;
-
- static ptr create(local_server_endpoint_impl *_server);
- socket_type & get_socket();
-
- void start();
-
- void send_queued(message_buffer_ptr_t _data);
-
- private:
- connection(local_server_endpoint_impl *_owner);
-
- void send_magic_cookie();
-
- local_server_endpoint_impl::socket_type socket_;
- local_server_endpoint_impl *server_;
-
- // the current message
- message_buffer_t message_;
-
- private:
- void receive_cbk(packet_buffer_ptr_t _buffer,
- boost::system::error_code const &_error,
- std::size_t _bytes);
- };
-
-#ifdef WIN32
- boost::asio::ip::tcp::acceptor acceptor_;
-#else
- boost::asio::local::stream_protocol::acceptor acceptor_;
-#endif
-
- std::map<endpoint_type, connection::ptr> connections_;
- connection *current_;
-
-private:
- void remove_connection(connection *_connection);
- void accept_cbk(connection::ptr _connection,
- boost::system::error_code const &_error);
-};
-
-} // namespace vsomeip
-
-#endif // VSOMEIP_LOCAL_SERVER_ENDPOINT_IMPL_HPP
+// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef VSOMEIP_LOCAL_SERVER_ENDPOINT_IMPL_HPP
+#define VSOMEIP_LOCAL_SERVER_ENDPOINT_IMPL_HPP
+
+#include <map>
+
+#include <boost/asio/io_service.hpp>
+#include <boost/asio/local/stream_protocol.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+#ifdef WIN32
+#include <boost/asio/ip/tcp.hpp>
+#endif
+
+#include <vsomeip/defines.hpp>
+
+#include "buffer.hpp"
+#include "server_endpoint_impl.hpp"
+
+namespace vsomeip {
+
+#ifdef WIN32
+typedef server_endpoint_impl<boost::asio::ip::tcp,
+ VSOMEIP_MAX_TCP_MESSAGE_SIZE > local_server_endpoint_base_impl;
+#else
+typedef server_endpoint_impl<boost::asio::local::stream_protocol,
+ VSOMEIP_MAX_LOCAL_MESSAGE_SIZE> local_server_endpoint_base_impl;
+#endif
+
+class local_server_endpoint_impl: public local_server_endpoint_base_impl {
+
+public:
+ local_server_endpoint_impl(std::shared_ptr<endpoint_host> _host,
+ endpoint_type _local,
+ boost::asio::io_service &_io,
+ std::uint32_t _max_message_size);
+ virtual ~local_server_endpoint_impl();
+
+ void start();
+ void stop();
+
+ void restart();
+ void receive();
+
+ bool send_to(const std::shared_ptr<endpoint_definition>,
+ const byte_t *_data, uint32_t _size, bool _flush);
+ void send_queued(queue_iterator_type _queue_iterator);
+
+ endpoint_type get_remote() const;
+ bool get_multicast(service_t, event_t, endpoint_type &) const;
+
+ bool is_local() const;
+
+private:
+ class connection: public boost::enable_shared_from_this<connection> {
+
+ public:
+ typedef boost::shared_ptr<connection> ptr;
+
+ static ptr create(local_server_endpoint_impl *_server,
+ std::uint32_t _max_message_size);
+ socket_type & get_socket();
+
+ void start();
+
+ void send_queued(queue_iterator_type _queue_iterator);
+
+ private:
+ connection(local_server_endpoint_impl *_owner, std::uint32_t _max_message_size);
+
+ void send_magic_cookie();
+
+ local_server_endpoint_impl::socket_type socket_;
+ local_server_endpoint_impl *server_;
+
+ uint32_t max_message_size_;
+
+ receive_buffer_t recv_buffer_;
+ size_t recv_buffer_size_;
+
+ private:
+ void receive_cbk(boost::system::error_code const &_error,
+ std::size_t _bytes);
+ };
+
+#ifdef WIN32
+ boost::asio::ip::tcp::acceptor acceptor_;
+#else
+ boost::asio::local::stream_protocol::acceptor acceptor_;
+#endif
+
+ std::map<endpoint_type, connection::ptr> connections_;
+ connection *current_;
+
+private:
+ void remove_connection(connection *_connection);
+ void accept_cbk(connection::ptr _connection,
+ boost::system::error_code const &_error);
+};
+
+} // namespace vsomeip
+
+#endif // VSOMEIP_LOCAL_SERVER_ENDPOINT_IMPL_HPP
diff --git a/implementation/endpoints/include/server_endpoint_impl.hpp b/implementation/endpoints/include/server_endpoint_impl.hpp
index eca9c5a..c51cb49 100644
--- a/implementation/endpoints/include/server_endpoint_impl.hpp
+++ b/implementation/endpoints/include/server_endpoint_impl.hpp
@@ -6,6 +6,7 @@
#ifndef VSOMEIP_SERVER_IMPL_HPP
#define VSOMEIP_SERVER_IMPL_HPP
+#include <deque>
#include <map>
#include <memory>
#include <mutex>
@@ -28,9 +29,12 @@ public:
typedef typename Protocol::socket socket_type;
typedef typename Protocol::endpoint endpoint_type;
typedef boost::array<uint8_t, MaxBufferSize> buffer_type;
+ typedef typename std::map<endpoint_type, std::deque<message_buffer_ptr_t> > queue_type;
+ typedef typename queue_type::iterator queue_iterator_type;
server_endpoint_impl(std::shared_ptr<endpoint_host> _host,
- endpoint_type _local, boost::asio::io_service &_io);
+ endpoint_type _local, boost::asio::io_service &_io,
+ std::uint32_t _max_message_size);
bool is_client() const;
bool is_connected() const;
@@ -40,7 +44,7 @@ public:
public:
void connect_cbk(boost::system::error_code const &_error);
- void send_cbk(message_buffer_ptr_t _buffer,
+ void send_cbk(queue_iterator_type _queue_iterator,
boost::system::error_code const &_error, std::size_t _bytes);
void flush_cbk(endpoint_type _target,
const boost::system::error_code &_error);
@@ -48,8 +52,7 @@ public:
public:
virtual bool send_intern(endpoint_type _target, const byte_t *_data,
uint32_t _port, bool _flush);
- virtual void send_queued(endpoint_type _target,
- message_buffer_ptr_t _buffer) = 0;
+ virtual void send_queued(queue_iterator_type _queue_iterator) = 0;
virtual endpoint_type get_remote() const = 0;
virtual bool get_multicast(service_t _service, event_t _event,
@@ -57,6 +60,8 @@ public:
protected:
std::map<endpoint_type, message_buffer_ptr_t> packetizer_;
+ queue_type queues_;
+
std::map<client_t, std::map<session_t, endpoint_type> > clients_;
boost::asio::system_timer flush_timer_;
diff --git a/implementation/endpoints/include/tcp_client_endpoint_impl.hpp b/implementation/endpoints/include/tcp_client_endpoint_impl.hpp
index 3bb7f26..e5bf987 100644
--- a/implementation/endpoints/include/tcp_client_endpoint_impl.hpp
+++ b/implementation/endpoints/include/tcp_client_endpoint_impl.hpp
@@ -20,11 +20,11 @@ class tcp_client_endpoint_impl: public tcp_client_endpoint_base_impl {
public:
tcp_client_endpoint_impl(std::shared_ptr<endpoint_host> _host,
endpoint_type _local,
- boost::asio::io_service &_io);
+ boost::asio::io_service &_io,
+ std::uint32_t _max_message_size);
virtual ~tcp_client_endpoint_impl();
void start();
- void send_queued(message_buffer_ptr_t _buffer);
bool get_remote_address(boost::asio::ip::address &_address) const;
unsigned short get_local_port() const;
@@ -33,15 +33,18 @@ public:
bool is_local() const;
private:
- bool is_magic_cookie() const;
+ void send_queued();
+ bool is_magic_cookie(size_t _offset) const;
void send_magic_cookie(message_buffer_ptr_t &_buffer);
- void receive_cbk(packet_buffer_ptr_t _buffer,
- boost::system::error_code const &_error,
+ void receive_cbk(boost::system::error_code const &_error,
std::size_t _bytes);
void connect();
void receive();
+
+ receive_buffer_t recv_buffer_;
+ size_t recv_buffer_size_;
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp
index 10d52e6..57f0566 100644
--- a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp
+++ b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp
@@ -24,7 +24,8 @@ class tcp_server_endpoint_impl: public tcp_server_endpoint_base_impl {
public:
tcp_server_endpoint_impl(std::shared_ptr<endpoint_host> _host,
endpoint_type _local,
- boost::asio::io_service &_io);
+ boost::asio::io_service &_io,
+ std::uint32_t _max_message_size);
virtual ~tcp_server_endpoint_impl();
void start();
@@ -32,7 +33,7 @@ public:
bool send_to(const std::shared_ptr<endpoint_definition> _target,
const byte_t *_data, uint32_t _size, bool _flush);
- void send_queued(endpoint_type _target, message_buffer_ptr_t _buffer);
+ void send_queued(queue_iterator_type _queue_iterator);
endpoint_type get_remote() const;
bool get_multicast(service_t, event_t, endpoint_type &) const;
@@ -54,30 +55,35 @@ private:
public:
typedef boost::shared_ptr<connection> ptr;
- static ptr create(tcp_server_endpoint_impl *_server);
+ static ptr create(tcp_server_endpoint_impl *_server,
+ std::uint32_t _max_message_size);
socket_type & get_socket();
void start();
void stop();
+ void receive();
client_t get_client(endpoint_type _endpoint_type);
- void send_queued(message_buffer_ptr_t _buffer);
+ void send_queued(queue_iterator_type _queue_iterator);
private:
- connection(tcp_server_endpoint_impl *_owner);
+ connection(tcp_server_endpoint_impl *_owner, std::uint32_t _max_message_size);
void send_magic_cookie(message_buffer_ptr_t &_buffer);
tcp_server_endpoint_impl::socket_type socket_;
tcp_server_endpoint_impl *server_;
- message_buffer_t message_;
+ uint32_t max_message_size_;
+
+ receive_buffer_t recv_buffer_;
+ size_t recv_buffer_size_;
private:
- bool is_magic_cookie() const;
- void receive_cbk(packet_buffer_ptr_t _buffer,
- boost::system::error_code const &_error,
+ bool is_magic_cookie(size_t _offset) const;
+ void receive_cbk(boost::system::error_code const &_error,
std::size_t _bytes);
+ std::mutex stop_mutex_;
};
boost::asio::ip::tcp::acceptor acceptor_;
diff --git a/implementation/endpoints/include/udp_client_endpoint_impl.hpp b/implementation/endpoints/include/udp_client_endpoint_impl.hpp
index 0b20600..4a51db6 100644
--- a/implementation/endpoints/include/udp_client_endpoint_impl.hpp
+++ b/implementation/endpoints/include/udp_client_endpoint_impl.hpp
@@ -31,13 +31,8 @@ public:
virtual ~udp_client_endpoint_impl();
void start();
- void send_queued(message_buffer_ptr_t _buffer);
- void join(const std::string &_address);
- void leave(const std::string &_address);
-
- void receive_cbk(packet_buffer_ptr_t _buffer,
- boost::system::error_code const &_error,
+ void receive_cbk(boost::system::error_code const &_error,
std::size_t _bytes);
bool get_remote_address(boost::asio::ip::address &_address) const;
@@ -46,8 +41,12 @@ public:
bool is_local() const;
private:
+ void send_queued();
void connect();
void receive();
+
+ receive_buffer_t recv_buffer_;
+ size_t recv_buffer_size_;
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/udp_server_endpoint_impl.hpp b/implementation/endpoints/include/udp_server_endpoint_impl.hpp
index 4c7beaf..d7e2b62 100644
--- a/implementation/endpoints/include/udp_server_endpoint_impl.hpp
+++ b/implementation/endpoints/include/udp_server_endpoint_impl.hpp
@@ -33,7 +33,7 @@ public:
bool send_to(const std::shared_ptr<endpoint_definition> _target,
const byte_t *_data, uint32_t _size, bool _flush);
- void send_queued(endpoint_type _target, message_buffer_ptr_t _buffer);
+ void send_queued(queue_iterator_type _queue_iterator);
endpoint_type get_remote() const;
bool get_multicast(service_t _service, event_t _event,
@@ -51,8 +51,7 @@ public:
client_t get_client(std::shared_ptr<endpoint_definition> _endpoint);
public:
- void receive_cbk(packet_buffer_ptr_t _buffer,
- boost::system::error_code const &_error,
+ void receive_cbk(boost::system::error_code const &_error,
std::size_t _size);
private:
@@ -62,7 +61,10 @@ private:
socket_type socket_;
endpoint_type remote_;
std::map<service_t, std::map<instance_t, endpoint_type> > multicasts_;
- message_buffer_t message_;
+
+ receive_buffer_t recv_buffer_;
+ size_t recv_buffer_size_;
+ std::mutex stop_mutex_;
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/virtual_server_endpoint_impl.hpp b/implementation/endpoints/include/virtual_server_endpoint_impl.hpp
new file mode 100644
index 0000000..12484f5
--- /dev/null
+++ b/implementation/endpoints/include/virtual_server_endpoint_impl.hpp
@@ -0,0 +1,62 @@
+// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef VSOMEIP_VIRTUAL_SERVER_ENDPOINT_IMPL_HPP
+#define VSOMEIP_VIRTUAL_SERVER_ENDPOINT_IMPL_HPP
+
+#include <vsomeip/primitive_types.hpp>
+
+#include "../include/endpoint.hpp"
+
+namespace vsomeip {
+
+class virtual_server_endpoint_impl : public endpoint {
+public:
+ virtual_server_endpoint_impl(
+ const std::string &_address,
+ uint16_t _port,
+ bool _reliable);
+
+ virtual ~virtual_server_endpoint_impl();
+
+ void start();
+ void stop();
+
+ bool is_connected() const;
+
+ bool send(const byte_t *_data, uint32_t _size, bool _flush);
+ bool send_to(const std::shared_ptr<endpoint_definition> _target,
+ const byte_t *_data, uint32_t _size, bool _flush);
+ void enable_magic_cookies();
+ void receive();
+
+ void join(const std::string &_address);
+ void leave(const std::string &_address);
+
+ void add_multicast(service_t _service, event_t _event,
+ const std::string &_address, uint16_t _port);
+ void remove_multicast(service_t _service, event_t _event);
+
+ bool get_remote_address(boost::asio::ip::address &_address) const;
+ unsigned short get_local_port() const;
+ unsigned short get_remote_port() const;
+ bool is_reliable() const;
+ bool is_local() const;
+
+ void increment_use_count();
+ void decrement_use_count();
+ uint32_t get_use_count();
+
+private:
+ std::string address_;
+ uint16_t port_;
+ bool reliable_;
+
+ uint32_t use_count_;
+};
+
+} // namespace vsomeip
+
+#endif // VSOMEIP_VIRTUAL_SERVER_ENDPOINT_IMPL_HPP
diff --git a/implementation/endpoints/src/client_endpoint_impl.cpp b/implementation/endpoints/src/client_endpoint_impl.cpp
index 5c2e399..6ed812a 100644
--- a/implementation/endpoints/src/client_endpoint_impl.cpp
+++ b/implementation/endpoints/src/client_endpoint_impl.cpp
@@ -6,6 +6,7 @@
#include <chrono>
#include <iomanip>
#include <sstream>
+#include <thread>
#include <boost/asio/buffer.hpp>
#include <boost/asio/ip/tcp.hpp>
@@ -13,11 +14,11 @@
#include <boost/asio/local/stream_protocol.hpp>
#include <vsomeip/defines.hpp>
-#include <vsomeip/logger.hpp>
#include "../include/client_endpoint_impl.hpp"
#include "../include/endpoint_host.hpp"
#include "../../configuration/include/internal.hpp"
+#include "../../logging/include/logger.hpp"
#include "../../utility/include/utility.hpp"
namespace vsomeip {
@@ -25,12 +26,13 @@ namespace vsomeip {
template<typename Protocol, int MaxBufferSize>
client_endpoint_impl<Protocol, MaxBufferSize>::client_endpoint_impl(
std::shared_ptr<endpoint_host> _host, endpoint_type _remote,
- boost::asio::io_service &_io)
- : endpoint_impl<MaxBufferSize>(_host, _io), socket_(_io),
- connect_timer_(_io), flush_timer_(_io), remote_(_remote),
- packetizer_(std::make_shared<message_buffer_t>()),
+ boost::asio::io_service &_io, std::uint32_t _max_message_size)
+ : endpoint_impl<MaxBufferSize>(_host, _io, _max_message_size),
+ socket_(_io), remote_(_remote),
+ flush_timer_(_io), connect_timer_(_io),
connect_timeout_(VSOMEIP_DEFAULT_CONNECT_TIMEOUT), // TODO: use config variable
- is_connected_(false) {
+ is_connected_(false),
+ packetizer_(std::make_shared<message_buffer_t>()) {
}
template<typename Protocol, int MaxBufferSize>
@@ -63,6 +65,11 @@ template<typename Protocol, int MaxBufferSize>
bool client_endpoint_impl<Protocol, MaxBufferSize>::send_to(
const std::shared_ptr<endpoint_definition> _target, const byte_t *_data,
uint32_t _size, bool _flush) {
+ (void)_target;
+ (void)_data;
+ (void)_size;
+ (void)_flush;
+
VSOMEIP_ERROR<< "Clients endpoints must not be used to "
<< "send to explicitely specified targets";
return false;
@@ -72,6 +79,7 @@ template<typename Protocol, int MaxBufferSize>
bool client_endpoint_impl<Protocol, MaxBufferSize>::send(const uint8_t *_data,
uint32_t _size, bool _flush) {
std::lock_guard<std::mutex> its_lock(mutex_);
+ bool is_flushing(false);
#if 0
std::stringstream msg;
msg << "cei::send: ";
@@ -80,8 +88,10 @@ bool client_endpoint_impl<Protocol, MaxBufferSize>::send(const uint8_t *_data,
<< (int)_data[i] << " ";
VSOMEIP_DEBUG << msg.str();
#endif
- if (packetizer_->size() + _size > MaxBufferSize) {
- send_queued(packetizer_);
+
+ if (packetizer_->size() + _size > endpoint_impl<MaxBufferSize>::max_message_size_) {
+ queue_.push_back(packetizer_);
+ is_flushing = true;
packetizer_ = std::make_shared<message_buffer_t>();
}
@@ -89,15 +99,22 @@ bool client_endpoint_impl<Protocol, MaxBufferSize>::send(const uint8_t *_data,
if (_flush) {
flush_timer_.cancel();
- send_queued(packetizer_);
+ queue_.push_back(packetizer_);
+ is_flushing = true;
packetizer_ = std::make_shared<message_buffer_t>();
} else {
flush_timer_.expires_from_now(
std::chrono::milliseconds(VSOMEIP_DEFAULT_FLUSH_TIMEOUT)); // TODO: use config variable
flush_timer_.async_wait(
- std::bind(
- &client_endpoint_impl<Protocol, MaxBufferSize>::flush_cbk,
- this->shared_from_this(), std::placeholders::_1));
+ std::bind(
+ &client_endpoint_impl<
+ Protocol, MaxBufferSize>::flush_cbk,
+ this->shared_from_this(),
+ std::placeholders::_1));
+ }
+
+ if (is_flushing && queue_.size() == 1) { // no writing in progress
+ send_queued();
}
return (true);
@@ -108,8 +125,12 @@ bool client_endpoint_impl<Protocol, MaxBufferSize>::flush() {
bool is_successful(true);
if (!packetizer_->empty()) {
- send_queued(packetizer_);
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ queue_.push_back(packetizer_);
packetizer_ = std::make_shared<message_buffer_t>();
+ if (queue_.size() == 1) { // no writing in progress
+ send_queued();
+ }
} else {
is_successful = false;
}
@@ -163,17 +184,15 @@ void client_endpoint_impl<Protocol, MaxBufferSize>::wait_connect_cbk(
template<typename Protocol, int MaxBufferSize>
void client_endpoint_impl<Protocol, MaxBufferSize>::send_cbk(
- message_buffer_ptr_t _buffer, boost::system::error_code const &_error,
- std::size_t _bytes) {
-#if 0
- std::stringstream msg;
- msg << "cei<" << this << ">::scb (" << _error.message() << "): ";
- for (std::size_t i = 0; i < _data->size(); ++i)
- msg << std::hex << std::setw(2) << std::setfill('0')
- << (int)(*_buffer)[i] << " ";
- VSOMEIP_DEBUG << msg.str();
-#endif
- if (_error == boost::asio::error::broken_pipe) {
+ boost::system::error_code const &_error, std::size_t _bytes) {
+ (void)_bytes;
+ if (!_error) {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ queue_.pop_front();
+ if (queue_.size() > 0) {
+ send_queued();
+ }
+ } else if (_error == boost::asio::error::broken_pipe) {
is_connected_ = false;
socket_.close();
connect();
diff --git a/implementation/endpoints/src/endpoint_definition.cpp b/implementation/endpoints/src/endpoint_definition.cpp
index 9a4caea..d748aa3 100644
--- a/implementation/endpoints/src/endpoint_definition.cpp
+++ b/implementation/endpoints/src/endpoint_definition.cpp
@@ -9,14 +9,41 @@
namespace vsomeip {
-endpoint_definition::endpoint_definition()
- : port_(ILLEGAL_PORT) {
+std::map<boost::asio::ip::address,
+ std::map<uint16_t,
+ std::map<bool, std::shared_ptr<endpoint_definition> > > >
+endpoint_definition::definitions_;
+
+std::shared_ptr<endpoint_definition>
+endpoint_definition::get(const boost::asio::ip::address &_address,
+ uint16_t _port, bool _is_reliable) {
+
+ std::shared_ptr<endpoint_definition> its_result;
+
+ auto find_address = definitions_.find(_address);
+ if (find_address != definitions_.end()) {
+ auto find_port = find_address->second.find(_port);
+ if (find_port != find_address->second.end()) {
+ auto found_reliable = find_port->second.find(_is_reliable);
+ if (found_reliable != find_port->second.end()) {
+ its_result = found_reliable->second;
+ }
+ }
+ }
+
+ if (!its_result) {
+ its_result = std::make_shared<endpoint_definition>(
+ _address, _port, _is_reliable);
+ definitions_[_address][_port][_is_reliable] = its_result;
+ }
+ return its_result;
}
endpoint_definition::endpoint_definition(
const boost::asio::ip::address &_address, uint16_t _port,
bool _is_reliable)
- : address_(_address), port_(_port), is_reliable_(_is_reliable), remote_port_(_port) {
+ : address_(_address), port_(_port), remote_port_(_port),
+ is_reliable_(_is_reliable) {
}
const boost::asio::ip::address & endpoint_definition::get_address() const {
diff --git a/implementation/endpoints/src/endpoint_impl.cpp b/implementation/endpoints/src/endpoint_impl.cpp
index e7ffffa..5b0e088 100644
--- a/implementation/endpoints/src/endpoint_impl.cpp
+++ b/implementation/endpoints/src/endpoint_impl.cpp
@@ -5,20 +5,22 @@
#include <vsomeip/constants.hpp>
#include <vsomeip/defines.hpp>
-#include <vsomeip/logger.hpp>
#include "../include/endpoint_host.hpp"
#include "../include/endpoint_impl.hpp"
+#include "../../logging/include/logger.hpp"
namespace vsomeip {
template<int MaxBufferSize>
endpoint_impl<MaxBufferSize>::endpoint_impl(
- std::shared_ptr<endpoint_host> _host, boost::asio::io_service &_io)
- : host_(_host),
- service_(_io),
+ std::shared_ptr<endpoint_host> _host, boost::asio::io_service &_io,
+ std::uint32_t _max_message_size)
+ : service_(_io),
+ host_(_host),
is_supporting_magic_cookies_(false),
- has_enabled_magic_cookies_(false) {
+ has_enabled_magic_cookies_(false),
+ max_message_size_(_max_message_size) {
}
template<int MaxBufferSize>
@@ -37,7 +39,7 @@ bool endpoint_impl<MaxBufferSize>::is_magic_cookie() const {
template<int MaxBufferSize>
uint32_t endpoint_impl<MaxBufferSize>::find_magic_cookie(
- message_buffer_t &_buffer) {
+ byte_t *_buffer, size_t _size) {
bool is_found(false);
uint32_t its_offset = 0xFFFFFFFF;
if (has_enabled_magic_cookies_) {
@@ -57,7 +59,7 @@ uint32_t endpoint_impl<MaxBufferSize>::find_magic_cookie(
do {
its_offset++; // --> first loop has "its_offset = 0"
- if (_buffer.size() > its_offset + 16) {
+ if (_size > its_offset + 16) {
is_found = (_buffer[its_offset] == 0xFF
&& _buffer[its_offset + 1] == 0xFF
&& _buffer[its_offset + 2] == its_cookie_identifier
@@ -104,6 +106,7 @@ void endpoint_impl<MaxBufferSize>::remove_multicast(service_t, event_t) {
template<int MaxBufferSize>
bool endpoint_impl<MaxBufferSize>::get_remote_address(
boost::asio::ip::address &_address) const {
+ (void)_address;
return false;
}
@@ -122,6 +125,22 @@ bool endpoint_impl<MaxBufferSize>::is_reliable() const {
return false;
}
+template<int MaxBufferSize>
+void endpoint_impl<MaxBufferSize>::increment_use_count() {
+ use_count_++;
+}
+
+template<int MaxBufferSize>
+void endpoint_impl<MaxBufferSize>::decrement_use_count() {
+ if (use_count_ > 0)
+ use_count_--;
+}
+
+template<int MaxBufferSize>
+uint32_t endpoint_impl<MaxBufferSize>::get_use_count() {
+ return use_count_;
+}
+
// Instantiate template
template class endpoint_impl< VSOMEIP_MAX_LOCAL_MESSAGE_SIZE> ;
template class endpoint_impl< VSOMEIP_MAX_TCP_MESSAGE_SIZE> ;
diff --git a/implementation/endpoints/src/local_client_endpoint_impl.cpp b/implementation/endpoints/src/local_client_endpoint_impl.cpp
index b465baa..323c414 100644
--- a/implementation/endpoints/src/local_client_endpoint_impl.cpp
+++ b/implementation/endpoints/src/local_client_endpoint_impl.cpp
@@ -9,17 +9,17 @@
#include <boost/asio/write.hpp>
#include <vsomeip/defines.hpp>
-#include <vsomeip/logger.hpp>
#include "../include/endpoint_host.hpp"
#include "../include/local_client_endpoint_impl.hpp"
+#include "../../logging/include/logger.hpp"
namespace vsomeip {
local_client_endpoint_impl::local_client_endpoint_impl(
std::shared_ptr< endpoint_host > _host, endpoint_type _remote,
- boost::asio::io_service &_io)
- : local_client_endpoint_base_impl(_host, _remote, _io) {
+ boost::asio::io_service &_io, std::uint32_t _max_message_size)
+ : local_client_endpoint_base_impl(_host, _remote, _io, _max_message_size) {
is_supporting_magic_cookies_ = false;
}
@@ -49,34 +49,22 @@ void local_client_endpoint_impl::connect() {
}
void local_client_endpoint_impl::receive() {
- packet_buffer_ptr_t its_buffer
- = std::make_shared< packet_buffer_t >();
+ receive_buffer_t its_buffer(VSOMEIP_MAX_LOCAL_MESSAGE_SIZE , 0);
socket_.async_receive(
- boost::asio::buffer(*its_buffer),
+ boost::asio::buffer(its_buffer),
std::bind(
&local_client_endpoint_impl::receive_cbk,
std::dynamic_pointer_cast<
local_client_endpoint_impl
>(shared_from_this()),
- its_buffer,
std::placeholders::_1,
std::placeholders::_2
)
);
}
-void local_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) {
-#if 0
- std::stringstream msg;
- msg << "lce<" << this << ">::sq: ";
- for (std::size_t i = 0; i < _buffer->size(); i++)
- msg << std::setw(2) << std::setfill('0') << std::hex
- << (int)(*_buffer)[i] << " ";
- VSOMEIP_DEBUG << msg.str();
-#endif
-
+void local_client_endpoint_impl::send_queued() {
static byte_t its_start_tag[] = { 0x67, 0x37, 0x6D, 0x07 };
- static byte_t its_end_tag[] = { 0x07, 0x6D, 0x37, 0x67 };
boost::asio::async_write(
socket_,
@@ -85,7 +73,7 @@ void local_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) {
sizeof(its_start_tag)
),
std::bind(
- &local_client_endpoint_impl::send_tag_cbk,
+ &local_client_endpoint_impl::send_start_tag_cbk,
std::dynamic_pointer_cast<
local_client_endpoint_impl
>(shared_from_this()),
@@ -93,18 +81,36 @@ void local_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) {
std::placeholders::_2
)
);
+}
+
+void local_client_endpoint_impl::send_queued_data() {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ message_buffer_ptr_t its_buffer = queue_.front();
+ #if 0
+ std::stringstream msg;
+ msg << "lce<" << this << ">::sq: ";
+ for (std::size_t i = 0; i < its_buffer->size(); i++)
+ msg << std::setw(2) << std::setfill('0') << std::hex
+ << (int)(*its_buffer)[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
+ #endif
boost::asio::async_write(
socket_,
- boost::asio::buffer(*_buffer),
+ boost::asio::buffer(*its_buffer),
std::bind(
- &client_endpoint_impl::send_cbk,
- this->shared_from_this(),
- _buffer,
+ &local_client_endpoint_impl::send_queued_data_cbk,
+ std::dynamic_pointer_cast<
+ local_client_endpoint_impl
+ >(shared_from_this()),
std::placeholders::_1,
std::placeholders::_2
)
);
+}
+
+void local_client_endpoint_impl::send_end_tag() {
+ static byte_t its_end_tag[] = { 0x07, 0x6D, 0x37, 0x67 };
boost::asio::async_write(
socket_,
@@ -113,10 +119,8 @@ void local_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) {
sizeof(its_end_tag)
),
std::bind(
- &local_client_endpoint_impl::send_tag_cbk,
- std::dynamic_pointer_cast<
- local_client_endpoint_impl
- >(shared_from_this()),
+ &client_endpoint_impl::send_cbk,
+ shared_from_this(),
std::placeholders::_1,
std::placeholders::_2
)
@@ -126,13 +130,28 @@ void local_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) {
void local_client_endpoint_impl::send_magic_cookie() {
}
-void local_client_endpoint_impl::send_tag_cbk(
+void local_client_endpoint_impl::send_start_tag_cbk(
boost::system::error_code const &_error, std::size_t _bytes) {
+ (void)_bytes;
+ if (_error)
+ send_cbk(_error, 0);
+
+ send_queued_data();
+}
+
+void local_client_endpoint_impl::send_queued_data_cbk(
+ boost::system::error_code const &_error, std::size_t _bytes) {
+ (void)_bytes;
+ if (_error)
+ send_cbk(_error, 0);
+
+ send_end_tag();
}
void local_client_endpoint_impl::receive_cbk(
- packet_buffer_ptr_t _buffer,
boost::system::error_code const &_error, std::size_t _bytes) {
+ (void)_error;
+ (void)_bytes;
VSOMEIP_ERROR << "Local endpoint received message ("
<< _error.message() << ")";
}
diff --git a/implementation/endpoints/src/local_server_endpoint_impl.cpp b/implementation/endpoints/src/local_server_endpoint_impl.cpp
index 3a237c6..b392cec 100644
--- a/implementation/endpoints/src/local_server_endpoint_impl.cpp
+++ b/implementation/endpoints/src/local_server_endpoint_impl.cpp
@@ -1,252 +1,276 @@
-// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.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 <deque>
-#include <iomanip>
-#include <iostream>
-#include <sstream>
-
-#include <boost/asio/write.hpp>
-
-#include <vsomeip/logger.hpp>
-
-#include "../include/endpoint_host.hpp"
-#include "../include/local_server_endpoint_impl.hpp"
-
-namespace vsomeip {
-
-local_server_endpoint_impl::local_server_endpoint_impl(
- std::shared_ptr< endpoint_host > _host,
- endpoint_type _local, boost::asio::io_service &_io)
- : local_server_endpoint_base_impl(_host, _local, _io),
- acceptor_(_io, _local) {
- is_supporting_magic_cookies_ = false;
-}
-
-local_server_endpoint_impl::~local_server_endpoint_impl() {
-}
-
-bool local_server_endpoint_impl::is_local() const {
- return true;
-}
-
-void local_server_endpoint_impl::start() {
- connection::ptr new_connection = connection::create(this);
-
- acceptor_.async_accept(
- new_connection->get_socket(),
- std::bind(
- &local_server_endpoint_impl::accept_cbk,
- std::dynamic_pointer_cast<
- local_server_endpoint_impl
- >(shared_from_this()),
- new_connection,
- std::placeholders::_1
- )
- );
-}
-
-void local_server_endpoint_impl::stop() {
-}
-
-bool local_server_endpoint_impl::send_to(
- const std::shared_ptr<endpoint_definition> _target,
- const byte_t *_data, uint32_t _size, bool _flush) {
- return false;
-}
-
-void local_server_endpoint_impl::send_queued(
- endpoint_type _target, message_buffer_ptr_t _buffer) {
- auto connection_iterator = connections_.find(_target);
- if (connection_iterator != connections_.end())
- connection_iterator->second->send_queued(_buffer);
-}
-
-void local_server_endpoint_impl::receive() {
- // intentionally left empty
-}
-
-void local_server_endpoint_impl::restart() {
- current_->start();
-}
-
-local_server_endpoint_impl::endpoint_type
-local_server_endpoint_impl::get_remote() const {
- return current_->get_socket().remote_endpoint();
-}
-
-bool local_server_endpoint_impl::get_multicast(
- service_t, event_t,
- local_server_endpoint_impl::endpoint_type &) const {
- return false;
-}
-
-void local_server_endpoint_impl::remove_connection(
- local_server_endpoint_impl::connection *_connection) {
- std::map< endpoint_type, connection::ptr >::iterator i
- = connections_.end();
- for (i = connections_.begin(); i != connections_.end(); i++) {
- if (i->second.get() == _connection)
- break;
- }
-
- if (i != connections_.end()) {
- connections_.erase(i);
- }
-}
-
-void local_server_endpoint_impl::accept_cbk(
- connection::ptr _connection, boost::system::error_code const &_error) {
-
- if (!_error) {
- socket_type &new_connection_socket = _connection->get_socket();
- endpoint_type remote = new_connection_socket.remote_endpoint();
-
- connections_[remote] = _connection;
- _connection->start();
- }
-
- start();
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// class local_service_impl::connection
-///////////////////////////////////////////////////////////////////////////////
-local_server_endpoint_impl::connection::connection(
- local_server_endpoint_impl *_server)
- : socket_(_server->service_), server_(_server) {
-}
-
-local_server_endpoint_impl::connection::ptr
-local_server_endpoint_impl::connection::create(
- local_server_endpoint_impl *_server) {
- return ptr(new connection(_server));
-}
-
-local_server_endpoint_impl::socket_type &
-local_server_endpoint_impl::connection::get_socket() {
- return socket_;
-}
-
-void local_server_endpoint_impl::connection::start() {
- packet_buffer_ptr_t its_buffer
- = std::make_shared< packet_buffer_t >();
- socket_.async_receive(
- boost::asio::buffer(*its_buffer),
- std::bind(
- &local_server_endpoint_impl::connection::receive_cbk,
- shared_from_this(),
- its_buffer,
- std::placeholders::_1,
- std::placeholders::_2
- )
- );
-}
-
-void local_server_endpoint_impl::connection::send_queued(
- message_buffer_ptr_t _buffer) {
-#if 0
- std::stringstream msg;
- msg << "lse::sq: ";
- for (std::size_t i = 0; i < _buffer->size(); i++)
- msg << std::setw(2) << std::setfill('0') << std::hex
- << (int)(*_buffer)[i] << " ";
- VSOMEIP_DEBUG << msg.str();
-#endif
- boost::asio::async_write(
- socket_,
- boost::asio::buffer(*_buffer),
- std::bind(
- &local_server_endpoint_base_impl::send_cbk,
- server_->shared_from_this(),
- _buffer,
- std::placeholders::_1,
- std::placeholders::_2
- )
- );
-}
-
-void local_server_endpoint_impl::connection::send_magic_cookie() {
-}
-
-void local_server_endpoint_impl::connection::receive_cbk(
- packet_buffer_ptr_t _buffer,
- boost::system::error_code const &_error, std::size_t _bytes) {
-
- std::shared_ptr<endpoint_host> its_host = server_->host_.lock();
- if (its_host) {
- std::size_t its_start;
- std::size_t its_end;
-
- if (!_error && 0 < _bytes) {
- #if 0
- std::stringstream msg;
- msg << "lse::c<" << this << ">rcb: ";
- for (std::size_t i = 0; i < _bytes; i++)
- msg << std::setw(2) << std::setfill('0') << std::hex
- << (int)(*_buffer)[i] << " ";
- VSOMEIP_DEBUG << msg.str();
- #endif
-
- message_.insert(message_.end(), _buffer->begin(),
- _buffer->begin() + _bytes);
-
- #define MESSAGE_IS_EMPTY (-1)
- #define FOUND_MESSAGE (-2)
-
- do {
- its_start = 0;
- while (its_start + 3 < message_.size() &&
- (message_[its_start] != 0x67 ||
- message_[its_start+1] != 0x37 ||
- message_[its_start+2] != 0x6d ||
- message_[its_start+3] != 0x07)) {
- its_start ++;
- }
-
- its_start = (its_start + 3 == message_.size() ?
- MESSAGE_IS_EMPTY : its_start+4);
-
- if (its_start != MESSAGE_IS_EMPTY) {
- its_end = its_start;
- while (its_end + 3 < message_.size() &&
- (message_[its_end] != 0x07 ||
- message_[its_end+1] != 0x6d ||
- message_[its_end+2] != 0x37 ||
- message_[its_end+3] != 0x67)) {
- its_end ++;
- }
- }
-
- if (its_start != MESSAGE_IS_EMPTY &&
- its_end+3 < message_.size()) {
- its_host->on_message(&message_[its_start],
- its_end - its_start, server_);
-
- #if 0
- std::stringstream local_msg;
- local_msg << "lse::c<" << this << ">rcb::thunk: ";
- for (std::size_t i = its_start; i < its_end; i++)
- local_msg << std::setw(2) << std::setfill('0') << std::hex
- << (int)(message_)[i] << " ";
- VSOMEIP_DEBUG << local_msg.str();
- #endif
-
- message_.erase(message_.begin(),
- message_.begin() + its_end + 4);
- its_start = FOUND_MESSAGE;
- }
- } while (message_.size() > 0 && its_start == FOUND_MESSAGE);
- }
-
- if (_error == boost::asio::error::misc_errors::eof) {
- server_->remove_connection(this);
- } else {
- start();
- }
- }
-}
-
-} // namespace vsomeip
+// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.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 <deque>
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+
+#include <boost/asio/write.hpp>
+
+#include "../include/endpoint_host.hpp"
+#include "../include/local_server_endpoint_impl.hpp"
+
+#include "../../logging/include/logger.hpp"
+
+namespace vsomeip {
+
+local_server_endpoint_impl::local_server_endpoint_impl(
+ std::shared_ptr< endpoint_host > _host,
+ endpoint_type _local, boost::asio::io_service &_io,
+ std::uint32_t _max_message_size)
+ : local_server_endpoint_base_impl(_host, _local, _io, _max_message_size),
+ acceptor_(_io, _local) {
+ is_supporting_magic_cookies_ = false;
+}
+
+local_server_endpoint_impl::~local_server_endpoint_impl() {
+}
+
+bool local_server_endpoint_impl::is_local() const {
+ return true;
+}
+
+void local_server_endpoint_impl::start() {
+ connection::ptr new_connection = connection::create(this, max_message_size_);
+
+ acceptor_.async_accept(
+ new_connection->get_socket(),
+ std::bind(
+ &local_server_endpoint_impl::accept_cbk,
+ std::dynamic_pointer_cast<
+ local_server_endpoint_impl
+ >(shared_from_this()),
+ new_connection,
+ std::placeholders::_1
+ )
+ );
+}
+
+void local_server_endpoint_impl::stop() {
+}
+
+bool local_server_endpoint_impl::send_to(
+ const std::shared_ptr<endpoint_definition> _target,
+ const byte_t *_data, uint32_t _size, bool _flush) {
+ (void)_target;
+ (void)_data;
+ (void)_size;
+ (void)_flush;
+ return false;
+}
+
+void local_server_endpoint_impl::send_queued(
+ queue_iterator_type _queue_iterator) {
+ auto connection_iterator = connections_.find(_queue_iterator->first);
+ if (connection_iterator != connections_.end())
+ connection_iterator->second->send_queued(_queue_iterator);
+}
+
+void local_server_endpoint_impl::receive() {
+ // intentionally left empty
+}
+
+void local_server_endpoint_impl::restart() {
+ current_->start();
+}
+
+local_server_endpoint_impl::endpoint_type
+local_server_endpoint_impl::get_remote() const {
+ return current_->get_socket().remote_endpoint();
+}
+
+bool local_server_endpoint_impl::get_multicast(
+ service_t, event_t,
+ local_server_endpoint_impl::endpoint_type &) const {
+ return false;
+}
+
+void local_server_endpoint_impl::remove_connection(
+ local_server_endpoint_impl::connection *_connection) {
+ std::map< endpoint_type, connection::ptr >::iterator i
+ = connections_.end();
+ for (i = connections_.begin(); i != connections_.end(); i++) {
+ if (i->second.get() == _connection)
+ break;
+ }
+
+ if (i != connections_.end()) {
+ connections_.erase(i);
+ }
+}
+
+void local_server_endpoint_impl::accept_cbk(
+ connection::ptr _connection, boost::system::error_code const &_error) {
+
+ if (!_error) {
+ socket_type &new_connection_socket = _connection->get_socket();
+ endpoint_type remote = new_connection_socket.remote_endpoint();
+
+ connections_[remote] = _connection;
+ _connection->start();
+ }
+
+ start();
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// class local_service_impl::connection
+///////////////////////////////////////////////////////////////////////////////
+
+local_server_endpoint_impl::connection::connection(
+ local_server_endpoint_impl *_server, std::uint32_t _max_message_size)
+ : socket_(_server->service_), server_(_server),
+ max_message_size_(_max_message_size + 8),
+ recv_buffer_(max_message_size_, 0),
+ recv_buffer_size_(0) {
+}
+
+local_server_endpoint_impl::connection::ptr
+local_server_endpoint_impl::connection::create(
+ local_server_endpoint_impl *_server, std::uint32_t _max_message_size) {
+ return ptr(new connection(_server, _max_message_size));
+}
+
+local_server_endpoint_impl::socket_type &
+local_server_endpoint_impl::connection::get_socket() {
+ return socket_;
+}
+
+void local_server_endpoint_impl::connection::start() {
+ if (recv_buffer_size_ == max_message_size_) {
+ // Overrun -> Reset buffer
+ recv_buffer_size_ = 0;
+ }
+ size_t buffer_size = max_message_size_ - recv_buffer_size_;
+ socket_.async_receive(
+ boost::asio::buffer(&recv_buffer_[recv_buffer_size_], buffer_size),
+ std::bind(
+ &local_server_endpoint_impl::connection::receive_cbk,
+ shared_from_this(),
+ std::placeholders::_1,
+ std::placeholders::_2
+ )
+ );
+}
+
+void local_server_endpoint_impl::connection::send_queued(
+ queue_iterator_type _queue_iterator) {
+
+ // TODO: We currently do _not_ use the send method of the local server
+ // endpoints. If we ever need it, we need to add the "start tag", "data",
+ // "end tag" sequence here.
+
+ message_buffer_ptr_t its_buffer = _queue_iterator->second.front();
+#if 0
+ std::stringstream msg;
+ msg << "lse::sq: ";
+ for (std::size_t i = 0; i < its_buffer->size(); i++)
+ msg << std::setw(2) << std::setfill('0') << std::hex
+ << (int)(*its_buffer)[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
+#endif
+ boost::asio::async_write(
+ socket_,
+ boost::asio::buffer(*its_buffer),
+ std::bind(
+ &local_server_endpoint_base_impl::send_cbk,
+ server_->shared_from_this(),
+ _queue_iterator,
+ std::placeholders::_1,
+ std::placeholders::_2
+ )
+ );
+}
+
+void local_server_endpoint_impl::connection::send_magic_cookie() {
+}
+
+void local_server_endpoint_impl::connection::receive_cbk(
+ boost::system::error_code const &_error, std::size_t _bytes) {
+
+ std::shared_ptr<endpoint_host> its_host = server_->host_.lock();
+ if (its_host) {
+ std::size_t its_start;
+ std::size_t its_end;
+ std::size_t its_iteration_gap = 0;
+
+ if (!_error && 0 < _bytes) {
+ #if 0
+ std::stringstream msg;
+ msg << "lse::c<" << this << ">rcb: ";
+ for (std::size_t i = 0; i < _bytes + recv_buffer_size_; i++)
+ msg << std::setw(2) << std::setfill('0') << std::hex
+ << (int) (recv_buffer_[i]) << " ";
+ VSOMEIP_DEBUG << msg.str();
+ #endif
+
+ recv_buffer_size_ += _bytes;
+
+ #define MESSAGE_IS_EMPTY std::size_t(-1)
+ #define FOUND_MESSAGE std::size_t(-2)
+
+ do {
+ its_start = 0 + its_iteration_gap;
+ while (its_start + 3 < recv_buffer_size_ + its_iteration_gap &&
+ (recv_buffer_[its_start] != 0x67 ||
+ recv_buffer_[its_start+1] != 0x37 ||
+ recv_buffer_[its_start+2] != 0x6d ||
+ recv_buffer_[its_start+3] != 0x07)) {
+ its_start ++;
+ }
+
+ its_start = (its_start + 3 == recv_buffer_size_ + its_iteration_gap ?
+ MESSAGE_IS_EMPTY : its_start+4);
+
+ if (its_start != MESSAGE_IS_EMPTY) {
+ its_end = its_start;
+ while (its_end + 3 < recv_buffer_size_ + its_iteration_gap &&
+ (recv_buffer_[its_end] != 0x07 ||
+ recv_buffer_[its_end+1] != 0x6d ||
+ recv_buffer_[its_end+2] != 0x37 ||
+ recv_buffer_[its_end+3] != 0x67)) {
+ its_end ++;
+ }
+ }
+
+ if (its_start != MESSAGE_IS_EMPTY &&
+ its_end + 3 < recv_buffer_size_ + its_iteration_gap) {
+ its_host->on_message(&recv_buffer_[its_start],
+ uint32_t(its_end - its_start), server_);
+
+ #if 0
+ std::stringstream local_msg;
+ local_msg << "lse::c<" << this << ">rcb::thunk: ";
+ for (std::size_t i = its_start; i < its_end; i++)
+ local_msg << std::setw(2) << std::setfill('0') << std::hex
+ << (int) recv_buffer_[i] << " ";
+ VSOMEIP_DEBUG << local_msg.str();
+ #endif
+
+ recv_buffer_size_ -= (its_end + 4 - its_iteration_gap);
+ its_start = FOUND_MESSAGE;
+ its_iteration_gap = its_end + 4;
+ } else {
+ if (its_start != MESSAGE_IS_EMPTY && its_iteration_gap) {
+ // Message not complete and not in front of the buffer!
+ // Copy last part to front for consume in future receive_cbk call!
+ for (size_t i = 0; i < recv_buffer_size_; ++i) {
+ recv_buffer_[i] = recv_buffer_[i + its_iteration_gap];
+ }
+ }
+ }
+ } while (recv_buffer_size_ > 0 && its_start == FOUND_MESSAGE);
+ }
+
+ if (_error == boost::asio::error::misc_errors::eof) {
+ server_->remove_connection(this);
+ } else {
+ start();
+ }
+ }
+}
+
+} // namespace vsomeip
diff --git a/implementation/endpoints/src/server_endpoint_impl.cpp b/implementation/endpoints/src/server_endpoint_impl.cpp
index 0158cf6..b67ecec 100644
--- a/implementation/endpoints/src/server_endpoint_impl.cpp
+++ b/implementation/endpoints/src/server_endpoint_impl.cpp
@@ -12,10 +12,10 @@
#include <boost/asio/local/stream_protocol.hpp>
#include <vsomeip/defines.hpp>
-#include <vsomeip/logger.hpp>
#include "../include/server_endpoint_impl.hpp"
#include "../../configuration/include/internal.hpp"
+#include "../../logging/include/logger.hpp"
#include "../../utility/include/byteorder.hpp"
#include "../../utility/include/utility.hpp"
@@ -24,8 +24,9 @@ namespace vsomeip {
template<typename Protocol, int MaxBufferSize>
server_endpoint_impl<Protocol, MaxBufferSize>::server_endpoint_impl(
std::shared_ptr<endpoint_host> _host, endpoint_type _local,
- boost::asio::io_service &_io)
- : endpoint_impl<MaxBufferSize>(_host, _io), flush_timer_(_io) {
+ boost::asio::io_service &_io, std::uint32_t _max_message_size)
+ : endpoint_impl<MaxBufferSize>(_host, _io, _max_message_size),
+ flush_timer_(_io), local_(_local) {
}
template<typename Protocol, int MaxBufferSize>
@@ -92,7 +93,10 @@ bool server_endpoint_impl<Protocol, MaxBufferSize>::send_intern(
endpoint_type _target, const byte_t *_data, uint32_t _size,
bool _flush) {
- std::shared_ptr<std::vector<byte_t> > target_packetizer;
+ bool is_flushing(false);
+ message_buffer_ptr_t target_packetizer;
+ queue_iterator_type target_queue_iterator;
+
auto found_packetizer = packetizer_.find(_target);
if (found_packetizer != packetizer_.end()) {
target_packetizer = found_packetizer->second;
@@ -101,8 +105,19 @@ bool server_endpoint_impl<Protocol, MaxBufferSize>::send_intern(
packetizer_.insert(std::make_pair(_target, target_packetizer));
}
- if (target_packetizer->size() + _size > MaxBufferSize) {
- send_queued(_target, target_packetizer);
+ target_queue_iterator = queues_.find(_target);
+ if (target_queue_iterator == queues_.end()) {
+ target_queue_iterator = queues_.insert(queues_.begin(),
+ std::make_pair(
+ _target,
+ std::deque<message_buffer_ptr_t>()
+ ));
+ }
+
+ // TODO compare against value from configuration here
+ if (target_packetizer->size() + _size > endpoint_impl<MaxBufferSize>::max_message_size_) {
+ target_queue_iterator->second.push_back(target_packetizer);
+ is_flushing = true;
packetizer_[_target] = std::make_shared<message_buffer_t>();
}
@@ -110,7 +125,8 @@ bool server_endpoint_impl<Protocol, MaxBufferSize>::send_intern(
if (_flush) {
flush_timer_.cancel();
- send_queued(_target, target_packetizer);
+ target_queue_iterator->second.push_back(target_packetizer);
+ is_flushing = true;
packetizer_[_target] = std::make_shared<message_buffer_t>();
} else {
std::chrono::milliseconds flush_timeout(VSOMEIP_DEFAULT_FLUSH_TIMEOUT);
@@ -123,6 +139,11 @@ bool server_endpoint_impl<Protocol, MaxBufferSize>::send_intern(
_target,
std::placeholders::_1));
}
+
+ if (is_flushing && target_queue_iterator->second.size() == 1) { // no writing in progress
+ send_queued(target_queue_iterator);
+ }
+
return true;
}
@@ -131,10 +152,9 @@ bool server_endpoint_impl<Protocol, MaxBufferSize>::flush(
endpoint_type _target) {
bool is_flushed = false;
std::lock_guard<std::mutex> its_lock(mutex_);
- auto i = packetizer_.find(_target);
- if (i != packetizer_.end() && !i->second->empty()) {
- send_queued(_target, i->second);
- i->second = std::make_shared<message_buffer_t>();
+ auto queue_iterator = queues_.find(_target);
+ if (queue_iterator != queues_.end() && !queue_iterator->second.empty()) {
+ send_queued(queue_iterator);
is_flushed = true;
}
@@ -144,20 +164,22 @@ bool server_endpoint_impl<Protocol, MaxBufferSize>::flush(
template<typename Protocol, int MaxBufferSize>
void server_endpoint_impl<Protocol, MaxBufferSize>::connect_cbk(
boost::system::error_code const &_error) {
+ (void)_error;
}
template<typename Protocol, int MaxBufferSize>
void server_endpoint_impl<Protocol, MaxBufferSize>::send_cbk(
- message_buffer_ptr_t _buffer, boost::system::error_code const &_error,
+ queue_iterator_type _queue_iterator, boost::system::error_code const &_error,
std::size_t _bytes) {
-#if 0
- std::stringstream msg;
- msg << "sei::scb (" << _error.message() << "): ";
- for (std::size_t i = 0; i < _buffer->size(); ++i)
- msg << std::hex << std::setw(2) << std::setfill('0')
- << (int)(*_buffer)[i] << " ";
- VSOMEIP_DEBUG << msg.str();
-#endif
+ (void)_bytes;
+
+ if (!_error) {
+ std::lock_guard<std::mutex> its_lock(mutex_);
+ _queue_iterator->second.pop_front();
+ if (_queue_iterator->second.size() > 0) {
+ send_queued(_queue_iterator);
+ }
+ }
}
template<typename Protocol, int MaxBufferSize>
@@ -170,16 +192,15 @@ void server_endpoint_impl<Protocol, MaxBufferSize>::flush_cbk(
// Instantiate template
#ifndef WIN32
-template class server_endpoint_impl<boost::asio::local::stream_protocol,
-VSOMEIP_MAX_LOCAL_MESSAGE_SIZE> ;
-#else
-// TODO: put instantiation for windows here!
-//template class server_endpoint_impl<boost::asio::ip::tcp,
-// VSOMEIP_MAX_TCP_MESSAGE_SIZE>;
+template class server_endpoint_impl<
+ boost::asio::local::stream_protocol,
+ VSOMEIP_MAX_LOCAL_MESSAGE_SIZE> ;
#endif
-template class server_endpoint_impl<boost::asio::ip::tcp,
-VSOMEIP_MAX_TCP_MESSAGE_SIZE> ;
-template class server_endpoint_impl<boost::asio::ip::udp,
-VSOMEIP_MAX_UDP_MESSAGE_SIZE> ;
+template class server_endpoint_impl<
+ boost::asio::ip::tcp,
+ VSOMEIP_MAX_TCP_MESSAGE_SIZE> ;
+template class server_endpoint_impl<
+ boost::asio::ip::udp,
+ VSOMEIP_MAX_UDP_MESSAGE_SIZE> ;
} // namespace vsomeip
diff --git a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp
index cf91fa7..26c7424 100644
--- a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp
+++ b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp
@@ -9,10 +9,10 @@
#include <vsomeip/constants.hpp>
#include <vsomeip/defines.hpp>
-#include <vsomeip/logger.hpp>
#include "../include/endpoint_host.hpp"
#include "../include/tcp_client_endpoint_impl.hpp"
+#include "../../logging/include/logger.hpp"
#include "../../utility/include/utility.hpp"
namespace ip = boost::asio::ip;
@@ -20,8 +20,11 @@ namespace ip = boost::asio::ip;
namespace vsomeip {
tcp_client_endpoint_impl::tcp_client_endpoint_impl(
- std::shared_ptr< endpoint_host > _host, endpoint_type _remote, boost::asio::io_service &_io)
- : tcp_client_endpoint_base_impl(_host, _remote, _io) {
+ std::shared_ptr< endpoint_host > _host, endpoint_type _remote,
+ boost::asio::io_service &_io, std::uint32_t _max_message_size)
+ : tcp_client_endpoint_base_impl(_host, _remote, _io, _max_message_size),
+ recv_buffer_(_max_message_size, 0),
+ recv_buffer_size_(0) {
is_supporting_magic_cookies_ = true;
}
@@ -40,8 +43,7 @@ void tcp_client_endpoint_impl::connect() {
socket_.open(remote_.protocol());
// Nagle algorithm off
- ip::tcp::no_delay option;
- socket_.set_option(option);
+ socket_.set_option(ip::tcp::no_delay(true));
socket_.async_connect(
remote_,
@@ -54,31 +56,44 @@ void tcp_client_endpoint_impl::connect() {
}
void tcp_client_endpoint_impl::receive() {
- packet_buffer_ptr_t its_buffer
- = std::make_shared< packet_buffer_t >();
+ if (recv_buffer_size_ == max_message_size_) {
+ // Overrun -> Reset buffer
+ recv_buffer_size_ = 0;
+ }
+ size_t buffer_size = max_message_size_ - recv_buffer_size_;
socket_.async_receive(
- boost::asio::buffer(*its_buffer),
+ boost::asio::buffer(&recv_buffer_[recv_buffer_size_], buffer_size),
std::bind(
&tcp_client_endpoint_impl::receive_cbk,
std::dynamic_pointer_cast< tcp_client_endpoint_impl >(shared_from_this()),
- its_buffer,
std::placeholders::_1,
std::placeholders::_2
)
);
}
-void tcp_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) {
+void tcp_client_endpoint_impl::send_queued() {
+ message_buffer_ptr_t its_buffer = queue_.front();
+
if (has_enabled_magic_cookies_)
- send_magic_cookie(_buffer);
+ send_magic_cookie(its_buffer);
+
+#if 0
+ std::stringstream msg;
+ msg << "tcei<" << remote_.address() << ":"
+ << std::dec << remote_.port() << ">::sq: ";
+ for (std::size_t i = 0; i < its_buffer->size(); i++)
+ msg << std::hex << std::setw(2) << std::setfill('0')
+ << (int)(*its_buffer)[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
+#endif
boost::asio::async_write(
socket_,
- boost::asio::buffer(*_buffer),
+ boost::asio::buffer(*its_buffer),
std::bind(
&tcp_client_endpoint_base_impl::send_cbk,
shared_from_this(),
- _buffer,
std::placeholders::_1,
std::placeholders::_2
)
@@ -103,8 +118,8 @@ bool tcp_client_endpoint_impl::is_reliable() const {
return true;
}
-bool tcp_client_endpoint_impl::is_magic_cookie() const {
- return (0 == std::memcmp(SERVICE_COOKIE, &message_[0], sizeof(SERVICE_COOKIE)));
+bool tcp_client_endpoint_impl::is_magic_cookie(size_t _offset) const {
+ return (0 == std::memcmp(SERVICE_COOKIE, &recv_buffer_[_offset], sizeof(SERVICE_COOKIE)));
}
void tcp_client_endpoint_impl::send_magic_cookie(message_buffer_ptr_t &_buffer) {
@@ -121,35 +136,36 @@ void tcp_client_endpoint_impl::send_magic_cookie(message_buffer_ptr_t &_buffer)
}
void tcp_client_endpoint_impl::receive_cbk(
- packet_buffer_ptr_t _buffer,
boost::system::error_code const &_error, std::size_t _bytes) {
#if 0
std::stringstream msg;
msg << "cei::rcb (" << _error.message() << "): ";
- for (std::size_t i = 0; i < _bytes; ++i)
+ for (std::size_t i = 0; i < _bytes + recv_buffer_size_; ++i)
msg << std::hex << std::setw(2) << std::setfill('0')
- << (int)(*_buffer)[i] << " ";
+ << (int) recv_buffer_[i] << " ";
VSOMEIP_DEBUG << msg.str();
#endif
std::shared_ptr<endpoint_host> its_host = host_.lock();
if (its_host) {
if (!_error && 0 < _bytes) {
- this->message_.insert(this->message_.end(), _buffer->begin(),
- _buffer->begin() + _bytes);
+ recv_buffer_size_ += _bytes;
+ size_t its_iteration_gap = 0;
bool has_full_message;
do {
uint32_t current_message_size
- = utility::get_message_size(message_);
+ = utility::get_message_size(&recv_buffer_[its_iteration_gap],
+ (uint32_t) recv_buffer_size_);
has_full_message = (current_message_size > 0
- && current_message_size <= message_.size());
+ && current_message_size <= recv_buffer_size_);
if (has_full_message) {
bool needs_forwarding(true);
- if (is_magic_cookie()) {
+ if (is_magic_cookie(its_iteration_gap)) {
has_enabled_magic_cookies_ = true;
} else {
if (has_enabled_magic_cookies_) {
- uint32_t its_offset = find_magic_cookie(message_);
+ uint32_t its_offset = find_magic_cookie(&recv_buffer_[its_iteration_gap],
+ (uint32_t) recv_buffer_size_);
if (its_offset < current_message_size) {
VSOMEIP_ERROR << "Message includes Magic Cookie. Ignoring it.";
current_message_size = its_offset;
@@ -157,27 +173,44 @@ void tcp_client_endpoint_impl::receive_cbk(
}
}
}
- if (needs_forwarding)
- its_host->on_message(&message_[0],
- current_message_size, this);
- message_.erase(message_.begin(),
- message_.begin() + current_message_size);
- } else if (has_enabled_magic_cookies_ && message_.size() > 0){
- uint32_t its_offset = find_magic_cookie(message_);
- if (its_offset < message_.size()) {
- message_.erase(message_.begin(),
- message_.begin() + its_offset);
+ if (needs_forwarding) {
+ if (!has_enabled_magic_cookies_) {
+ its_host->on_message(&recv_buffer_[its_iteration_gap],
+ current_message_size, this);
+ } else {
+ // Only call on_message without a magic cookie in front of the buffer!
+ if (!is_magic_cookie(its_iteration_gap)) {
+ its_host->on_message(&recv_buffer_[its_iteration_gap],
+ current_message_size, this);
+ }
+ }
+ }
+ recv_buffer_size_ -= current_message_size;
+ its_iteration_gap += current_message_size;
+ } else if (has_enabled_magic_cookies_ && recv_buffer_size_ > 0){
+ uint32_t its_offset = find_magic_cookie(&recv_buffer_[its_iteration_gap], recv_buffer_size_);
+ if (its_offset < recv_buffer_size_) {
+ recv_buffer_size_ -= its_offset;
+ its_iteration_gap += its_offset;
has_full_message = true; // trigger next loop
}
- } else if (message_.size() > VSOMEIP_MAX_TCP_MESSAGE_SIZE) {
+ } else if (current_message_size > max_message_size_) {
VSOMEIP_ERROR << "Message exceeds maximum message size. "
<< "Resetting receiver.";
- message_.clear();
+ recv_buffer_size_ = 0;
+ }
+ } while (has_full_message && recv_buffer_size_);
+ if (its_iteration_gap) {
+ // Copy incomplete message to front for next receive_cbk iteration
+ for (size_t i = 0; i < recv_buffer_size_; ++i) {
+ recv_buffer_[i] = recv_buffer_[i + its_iteration_gap];
}
- } while (has_full_message);
+ }
restart();
} else {
- receive();
+ if (socket_.is_open()) {
+ receive();
+ }
}
}
}
diff --git a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp
index be4ac5f..20391a0 100644
--- a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp
+++ b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp
@@ -1,263 +1,322 @@
-// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#include <iomanip>
-
-#include <boost/asio/write.hpp>
-
-#include <vsomeip/constants.hpp>
-#include <vsomeip/logger.hpp>
-
-#include "../include/endpoint_definition.hpp"
-#include "../include/endpoint_host.hpp"
-#include "../include/tcp_server_endpoint_impl.hpp"
-#include "../../utility/include/utility.hpp"
-
-namespace ip = boost::asio::ip;
-
-namespace vsomeip {
-
-tcp_server_endpoint_impl::tcp_server_endpoint_impl(
- std::shared_ptr<endpoint_host> _host, endpoint_type _local,
- boost::asio::io_service &_io)
- : tcp_server_endpoint_base_impl(_host, _local, _io),
- acceptor_(_io, _local),
- current_(0) {
- is_supporting_magic_cookies_ = true;
-}
-
-tcp_server_endpoint_impl::~tcp_server_endpoint_impl() {
-}
-
-bool tcp_server_endpoint_impl::is_local() const {
- return false;
-}
-
-void tcp_server_endpoint_impl::start() {
- connection::ptr new_connection = connection::create(this);
-
- acceptor_.async_accept(new_connection->get_socket(),
- std::bind(&tcp_server_endpoint_impl::accept_cbk,
- std::dynamic_pointer_cast<tcp_server_endpoint_impl>(
- shared_from_this()), new_connection,
- std::placeholders::_1));
-}
-
-void tcp_server_endpoint_impl::stop() {
- for (auto& i : connections_)
- i.second->stop();
- acceptor_.close();
-}
-
-bool tcp_server_endpoint_impl::send_to(
- const std::shared_ptr<endpoint_definition> _target,
- const byte_t *_data,
- uint32_t _size, bool _flush) {
- endpoint_type its_target(_target->get_address(), _target->get_port());
- return send_intern(its_target, _data, _size, _flush);
-}
-
-void tcp_server_endpoint_impl::send_queued(endpoint_type _target,
- message_buffer_ptr_t _buffer) {
- auto connection_iterator = connections_.find(_target);
- if (connection_iterator != connections_.end())
- connection_iterator->second->send_queued(_buffer);
-}
-
-tcp_server_endpoint_impl::endpoint_type
-tcp_server_endpoint_impl::get_remote() const {
- return current_->get_socket().remote_endpoint();
-}
-
-bool tcp_server_endpoint_impl::get_multicast(service_t, event_t,
- tcp_server_endpoint_impl::endpoint_type &) const {
- return false;
-}
-
-void tcp_server_endpoint_impl::accept_cbk(connection::ptr _connection,
- boost::system::error_code const &_error) {
-
- if (!_error) {
- socket_type &new_connection_socket = _connection->get_socket();
- endpoint_type remote = new_connection_socket.remote_endpoint();
-
- connections_[remote] = _connection;
- _connection->start();
- }
-
- start();
-}
-
-unsigned short tcp_server_endpoint_impl::get_local_port() const {
- return acceptor_.local_endpoint().port();
-}
-
-bool tcp_server_endpoint_impl::is_reliable() const {
- return true;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// class tcp_service_impl::connection
-///////////////////////////////////////////////////////////////////////////////
-tcp_server_endpoint_impl::connection::connection(
- tcp_server_endpoint_impl *_server) :
- socket_(_server->service_), server_(_server) {
-}
-
-tcp_server_endpoint_impl::connection::ptr
-tcp_server_endpoint_impl::connection::create(
- tcp_server_endpoint_impl *_server) {
- return ptr(new connection(_server));
-}
-
-tcp_server_endpoint_impl::socket_type &
-tcp_server_endpoint_impl::connection::get_socket() {
- return socket_;
-}
-
-void tcp_server_endpoint_impl::connection::start() {
- packet_buffer_ptr_t its_buffer = std::make_shared<packet_buffer_t>();
- socket_.async_receive(boost::asio::buffer(*its_buffer),
- std::bind(&tcp_server_endpoint_impl::connection::receive_cbk,
- shared_from_this(), its_buffer, std::placeholders::_1,
- std::placeholders::_2));
-}
-
-void tcp_server_endpoint_impl::connection::stop() {
- socket_.close();
-}
-
-void tcp_server_endpoint_impl::connection::send_queued(
- message_buffer_ptr_t _buffer) {
- if (server_->has_enabled_magic_cookies_)
- send_magic_cookie(_buffer);
-
- boost::asio::async_write(socket_, boost::asio::buffer(*_buffer),
- std::bind(&tcp_server_endpoint_base_impl::send_cbk,
- server_->shared_from_this(),
- _buffer, std::placeholders::_1,
- std::placeholders::_2));
-}
-
-void tcp_server_endpoint_impl::connection::send_magic_cookie(
- message_buffer_ptr_t &_buffer) {
- if (VSOMEIP_MAX_TCP_MESSAGE_SIZE - _buffer->size() >=
- VSOMEIP_SOMEIP_HEADER_SIZE + VSOMEIP_SOMEIP_MAGIC_COOKIE_SIZE) {
- _buffer->insert(_buffer->begin(), SERVICE_COOKIE,
- SERVICE_COOKIE + sizeof(SERVICE_COOKIE));
- }
-}
-
-bool tcp_server_endpoint_impl::connection::is_magic_cookie() const {
- return (0 == std::memcmp(CLIENT_COOKIE, &message_[0],
- sizeof(CLIENT_COOKIE)));
-}
-
-void tcp_server_endpoint_impl::connection::receive_cbk(
- packet_buffer_ptr_t _buffer, boost::system::error_code const &_error,
- std::size_t _bytes) {
-#if 0
- std::stringstream msg;
- for (std::size_t i = 0; i < _bytes; ++i)
- msg << std::hex << std::setw(2) << std::setfill('0')
- << (int) (*_buffer)[i] << " ";
- VSOMEIP_DEBUG<< msg.str();
-#endif
- std::shared_ptr<endpoint_host> its_host = server_->host_.lock();
- if (its_host) {
- if (!_error && 0 < _bytes) {
- message_.insert(message_.end(), _buffer->begin(),
- _buffer->begin() + _bytes);
-
- static int i = 1;
-
- bool has_full_message;
- do {
- uint32_t current_message_size
- = utility::get_message_size(message_);
- has_full_message = (current_message_size > 0
- && current_message_size <= message_.size());
- if (has_full_message) {
- bool needs_forwarding(true);
- if (is_magic_cookie()) {
- server_->has_enabled_magic_cookies_ = true;
- } else {
- if (server_->has_enabled_magic_cookies_) {
- uint32_t its_offset
- = server_->find_magic_cookie(message_);
- if (its_offset < current_message_size) {
- VSOMEIP_ERROR << "Detected Magic Cookie within message data. Resyncing.";
- current_message_size = its_offset;
- needs_forwarding = false;
- }
- }
- }
- if (needs_forwarding) {
- if (utility::is_request(message_[VSOMEIP_MESSAGE_TYPE_POS])) {
- client_t its_client;
- std::memcpy(&its_client,
- &message_[VSOMEIP_CLIENT_POS_MIN],
- sizeof(client_t));
- session_t its_session;
- std::memcpy(&its_session,
- &message_[VSOMEIP_SESSION_POS_MIN],
- sizeof(session_t));
- server_->clients_[its_client][its_session] =
- socket_.remote_endpoint();
- }
- its_host->on_message(&message_[0], current_message_size, server_);
- }
- message_.erase(message_.begin(), message_.begin() + current_message_size);
- } else if (server_->has_enabled_magic_cookies_ && message_.size() > 0){
- uint32_t its_offset = server_->find_magic_cookie(message_);
- if (its_offset < message_.size()) {
- VSOMEIP_ERROR << "Detected Magic Cookie within message data. Resyncing.";
- message_.erase(message_.begin(), message_.begin() + its_offset);
- has_full_message = true; // trigger next loop
- }
- } else if (message_.size() > VSOMEIP_MAX_TCP_MESSAGE_SIZE) {
- VSOMEIP_ERROR << "Message exceeds maximum message size. Resetting receiver.";
- message_.clear();
- }
- } while (has_full_message);
-
- start();
- }
- }
-}
-
-client_t tcp_server_endpoint_impl::get_client(std::shared_ptr<endpoint_definition> _endpoint) {
- endpoint_type endpoint(_endpoint->get_address(), _endpoint->get_port());
- auto its_remote = connections_.find(endpoint);
- if (its_remote != connections_.end()) {
- return its_remote->second->get_client(endpoint);
- }
- return 0;
-}
-
-client_t tcp_server_endpoint_impl::connection::get_client(endpoint_type _endpoint_type) {
- for (auto its_client : server_->clients_) {
- for (auto its_session : server_->clients_[its_client.first]) {
- auto endpoint = its_session.second;
- if (endpoint == _endpoint_type) {
- // TODO: Check system byte order before convert!
- client_t client = its_client.first << 8 | its_client.first >> 8;
- return client;
- }
- }
- }
- return 0;
-}
-
-// Dummies
-void tcp_server_endpoint_impl::receive() {
- // intentionally left empty
-}
-
-void tcp_server_endpoint_impl::restart() {
- // intentionally left empty
-}
-
-} // namespace vsomeip
+// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <iomanip>
+
+#include <boost/asio/write.hpp>
+
+#include <vsomeip/constants.hpp>
+
+#include "../include/endpoint_definition.hpp"
+#include "../include/endpoint_host.hpp"
+#include "../include/tcp_server_endpoint_impl.hpp"
+#include "../../logging/include/logger.hpp"
+#include "../../utility/include/utility.hpp"
+
+namespace ip = boost::asio::ip;
+
+namespace vsomeip {
+
+tcp_server_endpoint_impl::tcp_server_endpoint_impl(
+ std::shared_ptr<endpoint_host> _host, endpoint_type _local,
+ boost::asio::io_service &_io, std::uint32_t _max_message_size)
+ : tcp_server_endpoint_base_impl(_host, _local, _io, _max_message_size),
+ acceptor_(_io, _local),
+ current_(0) {
+ is_supporting_magic_cookies_ = true;
+}
+
+tcp_server_endpoint_impl::~tcp_server_endpoint_impl() {
+}
+
+bool tcp_server_endpoint_impl::is_local() const {
+ return false;
+}
+
+void tcp_server_endpoint_impl::start() {
+ connection::ptr new_connection = connection::create(this, max_message_size_);
+
+ acceptor_.async_accept(new_connection->get_socket(),
+ std::bind(&tcp_server_endpoint_impl::accept_cbk,
+ std::dynamic_pointer_cast<tcp_server_endpoint_impl>(
+ shared_from_this()), new_connection,
+ std::placeholders::_1));
+}
+
+void tcp_server_endpoint_impl::stop() {
+ for (auto& i : connections_)
+ i.second->stop();
+ acceptor_.close();
+}
+
+bool tcp_server_endpoint_impl::send_to(
+ const std::shared_ptr<endpoint_definition> _target,
+ const byte_t *_data,
+ uint32_t _size, bool _flush) {
+ endpoint_type its_target(_target->get_address(), _target->get_port());
+ return send_intern(its_target, _data, _size, _flush);
+}
+
+void tcp_server_endpoint_impl::send_queued(queue_iterator_type _queue_iterator) {
+ auto connection_iterator = connections_.find(_queue_iterator->first);
+ if (connection_iterator != connections_.end())
+ connection_iterator->second->send_queued(_queue_iterator);
+}
+
+tcp_server_endpoint_impl::endpoint_type
+tcp_server_endpoint_impl::get_remote() const {
+ return current_->get_socket().remote_endpoint();
+}
+
+bool tcp_server_endpoint_impl::get_multicast(service_t, event_t,
+ tcp_server_endpoint_impl::endpoint_type &) const {
+ return false;
+}
+
+void tcp_server_endpoint_impl::accept_cbk(connection::ptr _connection,
+ boost::system::error_code const &_error) {
+
+ if (!_error) {
+ socket_type &new_connection_socket = _connection->get_socket();
+ endpoint_type remote = new_connection_socket.remote_endpoint();
+
+ connections_[remote] = _connection;
+ _connection->start();
+
+ start();
+ }
+}
+
+unsigned short tcp_server_endpoint_impl::get_local_port() const {
+ return acceptor_.local_endpoint().port();
+}
+
+bool tcp_server_endpoint_impl::is_reliable() const {
+ return true;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// class tcp_service_impl::connection
+///////////////////////////////////////////////////////////////////////////////
+tcp_server_endpoint_impl::connection::connection(
+ tcp_server_endpoint_impl *_server, std::uint32_t _max_message_size) :
+ socket_(_server->service_), server_(_server),
+ max_message_size_(_max_message_size),
+ recv_buffer_(_max_message_size, 0),
+ recv_buffer_size_(0) {
+}
+
+tcp_server_endpoint_impl::connection::ptr
+tcp_server_endpoint_impl::connection::create(
+ tcp_server_endpoint_impl *_server, std::uint32_t _max_message_size) {
+ return ptr(new connection(_server, _max_message_size));
+}
+
+tcp_server_endpoint_impl::socket_type &
+tcp_server_endpoint_impl::connection::get_socket() {
+ return socket_;
+}
+
+void tcp_server_endpoint_impl::connection::start() {
+ receive();
+ // Nagle algorithm off
+ socket_.set_option(ip::tcp::no_delay(true));
+}
+
+void tcp_server_endpoint_impl::connection::receive() {
+ if (recv_buffer_size_ == max_message_size_) {
+ // Overrun -> Reset buffer
+ recv_buffer_size_ = 0;
+ }
+ std::lock_guard<std::mutex> its_lock(stop_mutex_);
+ if(socket_.is_open()) {
+ size_t buffer_size = max_message_size_ - recv_buffer_size_;
+ socket_.async_receive(boost::asio::buffer(&recv_buffer_[recv_buffer_size_], buffer_size),
+ std::bind(&tcp_server_endpoint_impl::connection::receive_cbk,
+ shared_from_this(), std::placeholders::_1,
+ std::placeholders::_2));
+ }
+}
+
+void tcp_server_endpoint_impl::connection::stop() {
+ std::lock_guard<std::mutex> its_lock(stop_mutex_);
+ if(socket_.is_open()) {
+ socket_.shutdown(socket_.shutdown_both);
+ socket_.close();
+ }
+}
+
+void tcp_server_endpoint_impl::connection::send_queued(
+ queue_iterator_type _queue_iterator) {
+ message_buffer_ptr_t its_buffer = _queue_iterator->second.front();
+
+ if (server_->has_enabled_magic_cookies_)
+ send_magic_cookie(its_buffer);
+
+ boost::asio::async_write(socket_, boost::asio::buffer(*its_buffer),
+ std::bind(&tcp_server_endpoint_base_impl::send_cbk,
+ server_->shared_from_this(),
+ _queue_iterator, std::placeholders::_1,
+ std::placeholders::_2));
+}
+
+void tcp_server_endpoint_impl::connection::send_magic_cookie(
+ message_buffer_ptr_t &_buffer) {
+ if (VSOMEIP_MAX_TCP_MESSAGE_SIZE - _buffer->size() >=
+ VSOMEIP_SOMEIP_HEADER_SIZE + VSOMEIP_SOMEIP_MAGIC_COOKIE_SIZE) {
+ _buffer->insert(_buffer->begin(), SERVICE_COOKIE,
+ SERVICE_COOKIE + sizeof(SERVICE_COOKIE));
+ }
+}
+
+bool tcp_server_endpoint_impl::connection::is_magic_cookie(size_t _offset) const {
+ return (0 == std::memcmp(CLIENT_COOKIE, &recv_buffer_[_offset],
+ sizeof(CLIENT_COOKIE)));
+}
+
+void tcp_server_endpoint_impl::connection::receive_cbk(
+ boost::system::error_code const &_error,
+ std::size_t _bytes) {
+#if 0
+ std::stringstream msg;
+ for (std::size_t i = 0; i < _bytes + recv_buffer_size_; ++i)
+ msg << std::hex << std::setw(2) << std::setfill('0')
+ << (int) recv_buffer_[i] << " ";
+ VSOMEIP_DEBUG<< msg.str();
+#endif
+ std::shared_ptr<endpoint_host> its_host = server_->host_.lock();
+ if (its_host) {
+ if (!_error && 0 < _bytes) {
+ recv_buffer_size_ += _bytes;
+
+ size_t its_iteration_gap = 0;
+ bool has_full_message;
+ do {
+ uint32_t current_message_size
+ = utility::get_message_size(&recv_buffer_[its_iteration_gap],
+ (uint32_t) recv_buffer_size_);
+ has_full_message = (current_message_size > VSOMEIP_SOMEIP_HEADER_SIZE
+ && current_message_size <= recv_buffer_size_);
+ if (has_full_message) {
+ bool needs_forwarding(true);
+ if (is_magic_cookie(its_iteration_gap)) {
+ server_->has_enabled_magic_cookies_ = true;
+ } else {
+ if (server_->has_enabled_magic_cookies_) {
+ uint32_t its_offset
+ = server_->find_magic_cookie(&recv_buffer_[its_iteration_gap],
+ recv_buffer_size_);
+ if (its_offset < current_message_size) {
+ VSOMEIP_ERROR << "Detected Magic Cookie within message data. Resyncing.";
+ if (!is_magic_cookie(its_iteration_gap)) {
+ its_host->on_error(&recv_buffer_[its_iteration_gap],
+ static_cast<length_t>(recv_buffer_size_), server_);
+ }
+ current_message_size = its_offset;
+ needs_forwarding = false;
+ }
+ }
+ }
+ if (needs_forwarding) {
+ if (utility::is_request(recv_buffer_[VSOMEIP_MESSAGE_TYPE_POS])) {
+ client_t its_client;
+ std::memcpy(&its_client,
+ &recv_buffer_[VSOMEIP_CLIENT_POS_MIN],
+ sizeof(client_t));
+ session_t its_session;
+ std::memcpy(&its_session,
+ &recv_buffer_[VSOMEIP_SESSION_POS_MIN],
+ sizeof(session_t));
+ {
+ std::lock_guard<std::mutex> its_lock(stop_mutex_);
+ if (socket_.is_open()) {
+ server_->clients_[its_client][its_session] =
+ socket_.remote_endpoint();
+ server_->current_ = this;
+ }
+ }
+ }
+ if (!server_->has_enabled_magic_cookies_) {
+ its_host->on_message(&recv_buffer_[its_iteration_gap],
+ current_message_size, server_);
+ } else {
+ // Only call on_message without a magic cookie in front of the buffer!
+ if (!is_magic_cookie(its_iteration_gap)) {
+ its_host->on_message(&recv_buffer_[its_iteration_gap],
+ current_message_size, server_);
+ }
+ }
+ }
+ recv_buffer_size_ -= current_message_size;
+ its_iteration_gap += current_message_size;
+ } else if (server_->has_enabled_magic_cookies_ && recv_buffer_size_ > 0){
+ uint32_t its_offset =
+ server_->find_magic_cookie(&recv_buffer_[its_iteration_gap],
+ recv_buffer_size_);
+ if (its_offset < recv_buffer_size_) {
+ VSOMEIP_ERROR << "Detected Magic Cookie within message data. Resyncing.";
+ if (!is_magic_cookie(its_iteration_gap)) {
+ its_host->on_error(&recv_buffer_[its_iteration_gap],
+ static_cast<length_t>(recv_buffer_size_), server_);
+ }
+ recv_buffer_size_ -= its_offset;
+ its_iteration_gap += its_offset;
+ has_full_message = true; // trigger next loop
+ if (!is_magic_cookie(its_iteration_gap)) {
+ its_host->on_error(&recv_buffer_[its_iteration_gap],
+ static_cast<length_t>(recv_buffer_size_), server_);
+ }
+ }
+ } else if (current_message_size > max_message_size_) {
+ VSOMEIP_ERROR << "Message exceeds maximum message size ("
+ << std::dec << current_message_size
+ << "). Resetting receiver.";
+ recv_buffer_size_ = 0;
+ }
+ } while (has_full_message && recv_buffer_size_);
+ if (its_iteration_gap) {
+ // Copy incomplete message to front for next receive_cbk iteration
+ for (size_t i = 0; i < recv_buffer_size_; ++i) {
+ recv_buffer_[i] = recv_buffer_[i + its_iteration_gap];
+ }
+ }
+ receive();
+ }
+ }
+}
+
+client_t tcp_server_endpoint_impl::get_client(std::shared_ptr<endpoint_definition> _endpoint) {
+ endpoint_type endpoint(_endpoint->get_address(), _endpoint->get_port());
+ auto its_remote = connections_.find(endpoint);
+ if (its_remote != connections_.end()) {
+ return its_remote->second->get_client(endpoint);
+ }
+ return 0;
+}
+
+client_t tcp_server_endpoint_impl::connection::get_client(endpoint_type _endpoint_type) {
+ for (auto its_client : server_->clients_) {
+ for (auto its_session : server_->clients_[its_client.first]) {
+ auto endpoint = its_session.second;
+ if (endpoint == _endpoint_type) {
+ // TODO: Check system byte order before convert!
+ client_t client = client_t(its_client.first << 8 | its_client.first >> 8);
+ return client;
+ }
+ }
+ }
+ return 0;
+}
+
+// Dummies
+void tcp_server_endpoint_impl::receive() {
+ // intentionally left empty
+}
+
+void tcp_server_endpoint_impl::restart() {
+ // intentionally left empty
+}
+
+} // namespace vsomeip
diff --git a/implementation/endpoints/src/udp_client_endpoint_impl.cpp b/implementation/endpoints/src/udp_client_endpoint_impl.cpp
index 95f12c3..a5a90cc 100644
--- a/implementation/endpoints/src/udp_client_endpoint_impl.cpp
+++ b/implementation/endpoints/src/udp_client_endpoint_impl.cpp
@@ -8,10 +8,9 @@
#include <boost/asio/ip/multicast.hpp>
-#include <vsomeip/logger.hpp>
-
#include "../include/endpoint_host.hpp"
#include "../include/udp_client_endpoint_impl.hpp"
+#include "../../logging/include/logger.hpp"
#include "../../utility/include/utility.hpp"
namespace vsomeip {
@@ -19,7 +18,9 @@ namespace vsomeip {
udp_client_endpoint_impl::udp_client_endpoint_impl(
std::shared_ptr< endpoint_host > _host, endpoint_type _remote,
boost::asio::io_service &_io)
- : udp_client_endpoint_base_impl(_host, _remote, _io) {
+ : udp_client_endpoint_base_impl(_host, _remote, _io, VSOMEIP_MAX_UDP_MESSAGE_SIZE),
+ recv_buffer_(VSOMEIP_MAX_UDP_MESSAGE_SIZE, 0),
+ recv_buffer_size_(0) {
}
udp_client_endpoint_impl::~udp_client_endpoint_impl() {
@@ -43,44 +44,44 @@ void udp_client_endpoint_impl::connect() {
void udp_client_endpoint_impl::start() {
socket_.open(remote_.protocol());
connect();
- receive();
}
-void udp_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) {
+void udp_client_endpoint_impl::send_queued() {
+ message_buffer_ptr_t its_buffer = queue_.front();
#if 0
std::stringstream msg;
msg << "ucei<" << remote_.address() << ":"
<< std::dec << remote_.port() << ">::sq: ";
- for (std::size_t i = 0; i < _buffer->size(); i++)
+ for (std::size_t i = 0; i < its_buffer->size(); i++)
msg << std::hex << std::setw(2) << std::setfill('0')
- << (int)(*_buffer)[i] << " ";
+ << (int)(*its_buffer)[i] << " ";
VSOMEIP_DEBUG << msg.str();
#endif
socket_.async_send(
- boost::asio::buffer(*_buffer),
+ boost::asio::buffer(*its_buffer),
std::bind(
&udp_client_endpoint_base_impl::send_cbk,
shared_from_this(),
- _buffer,
std::placeholders::_1,
std::placeholders::_2
)
);
- receive();
}
void udp_client_endpoint_impl::receive() {
- packet_buffer_ptr_t its_buffer
- = std::make_shared< packet_buffer_t >();
+ if (recv_buffer_size_ == max_message_size_) {
+ // Overrun -> Reset buffer
+ recv_buffer_size_ = 0;
+ }
+ size_t buffer_size = max_message_size_ - recv_buffer_size_;
socket_.async_receive_from(
- boost::asio::buffer(*its_buffer),
+ boost::asio::buffer(&recv_buffer_[recv_buffer_size_], buffer_size),
remote_,
std::bind(
&udp_client_endpoint_impl::receive_cbk,
std::dynamic_pointer_cast<
udp_client_endpoint_impl
>(shared_from_this()),
- its_buffer,
std::placeholders::_1,
std::placeholders::_2
)
@@ -101,69 +102,37 @@ unsigned short udp_client_endpoint_impl::get_remote_port() const {
return socket_.remote_endpoint().port();
}
-void udp_client_endpoint_impl::join(const std::string &_address) {
-
- if (remote_.address().is_v4()) {
- try {
- socket_.set_option(
- boost::asio::ip::udp::socket::reuse_address(true));
- socket_.set_option(boost::asio::ip::multicast::join_group(
- boost::asio::ip::address::from_string(_address)));
- }
- catch (...) {
- }
- } else {
- // TODO: support multicast for IPv6
- }
-}
-
-void udp_client_endpoint_impl::leave(const std::string &_address) {
- if (remote_.address().is_v4()) {
- try {
- socket_.set_option(
- boost::asio::ip::udp::socket::reuse_address(true));
- socket_.set_option(boost::asio::ip::multicast::leave_group(
- boost::asio::ip::address::from_string(_address)));
- }
- catch (...) {
- }
- } else {
- // TODO: support multicast for IPv6
- }
-}
-
void udp_client_endpoint_impl::receive_cbk(
- packet_buffer_ptr_t _buffer,
boost::system::error_code const &_error, std::size_t _bytes) {
std::shared_ptr<endpoint_host> its_host = host_.lock();
if (!_error && 0 < _bytes && its_host) {
#if 0
std::stringstream msg;
msg << "ucei::rcb(" << _error.message() << "): ";
- for (std::size_t i = 0; i < _bytes; ++i)
+ for (std::size_t i = 0; i < _bytes + recv_buffer_size_; ++i)
msg << std::hex << std::setw(2) << std::setfill('0')
- << (int)(*_buffer)[i] << " ";
+ << (int) recv_buffer_[i] << " ";
VSOMEIP_DEBUG << msg.str();
#endif
- this->message_.insert(this->message_.end(), _buffer->begin(),
- _buffer->begin() + _bytes);
-
- bool has_full_message;
- do {
- uint32_t current_message_size
- = utility::get_message_size(this->message_);
-
- has_full_message = (current_message_size > 0
- && current_message_size <= this->message_.size());
- if (has_full_message) {
- its_host->on_message(&message_[0], current_message_size, this);
- this->message_.erase(this->message_.begin(),
- this->message_.begin() + current_message_size);
- }
- } while (has_full_message);
+ recv_buffer_size_ += _bytes;
+ uint32_t current_message_size
+ = utility::get_message_size(&this->recv_buffer_[0],
+ (uint32_t) recv_buffer_size_);
+ if (current_message_size > VSOMEIP_SOMEIP_HEADER_SIZE &&
+ current_message_size <= _bytes) {
+ its_host->on_message(&recv_buffer_[0], current_message_size, this);
+ } else {
+ VSOMEIP_ERROR << "Received a unreliable vSomeIP message with bad length field";
+ }
+ recv_buffer_size_ = 0;
+ }
+ if (!_error) {
+ receive();
+ } else {
+ if (socket_.is_open()) {
+ receive();
+ }
}
-
- receive();
}
} // namespace vsomeip
diff --git a/implementation/endpoints/src/udp_server_endpoint_impl.cpp b/implementation/endpoints/src/udp_server_endpoint_impl.cpp
index f0fee37..f29dfba 100644
--- a/implementation/endpoints/src/udp_server_endpoint_impl.cpp
+++ b/implementation/endpoints/src/udp_server_endpoint_impl.cpp
@@ -1,251 +1,264 @@
-// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#include <iomanip>
-#include <sstream>
-
-#include <boost/asio/ip/multicast.hpp>
-
-#include <vsomeip/logger.hpp>
-
-#include "../include/endpoint_definition.hpp"
-#include "../include/endpoint_host.hpp"
-#include "../include/udp_server_endpoint_impl.hpp"
-#include "../../utility/include/byteorder.hpp"
-#include "../../utility/include/utility.hpp"
-
-namespace ip = boost::asio::ip;
-
-namespace vsomeip {
-
-udp_server_endpoint_impl::udp_server_endpoint_impl(
- std::shared_ptr< endpoint_host > _host,
- endpoint_type _local,
- boost::asio::io_service &_io)
- : server_endpoint_impl<
- ip::udp, VSOMEIP_MAX_UDP_MESSAGE_SIZE
- >(_host, _local, _io),
- socket_(_io, _local.protocol()) {
+// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <iomanip>
+#include <sstream>
+
+#include <boost/asio/ip/multicast.hpp>
+
+#include "../include/endpoint_definition.hpp"
+#include "../include/endpoint_host.hpp"
+#include "../include/udp_server_endpoint_impl.hpp"
+#include "../../logging/include/logger.hpp"
+#include "../../utility/include/byteorder.hpp"
+#include "../../utility/include/utility.hpp"
+#include "../../service_discovery/include/defines.hpp"
+
+namespace ip = boost::asio::ip;
+
+namespace vsomeip {
+
+udp_server_endpoint_impl::udp_server_endpoint_impl(
+ std::shared_ptr< endpoint_host > _host,
+ endpoint_type _local,
+ boost::asio::io_service &_io)
+ : server_endpoint_impl<
+ ip::udp, VSOMEIP_MAX_UDP_MESSAGE_SIZE
+ >(_host, _local, _io, VSOMEIP_MAX_UDP_MESSAGE_SIZE),
+ socket_(_io, _local.protocol()),
+ recv_buffer_(VSOMEIP_MAX_UDP_MESSAGE_SIZE, 0),
+ recv_buffer_size_(0) {
boost::system::error_code ec;
- boost::asio::socket_base::reuse_address optionReuseAddress(true);
+ boost::asio::socket_base::reuse_address optionReuseAddress(true);
socket_.set_option(optionReuseAddress);
socket_.bind(_local, ec);
- boost::asio::detail::throw_error(ec, "bind");
-
- boost::asio::socket_base::broadcast option(true);
- socket_.set_option(option);
-}
-
-udp_server_endpoint_impl::~udp_server_endpoint_impl() {
-}
-
-bool udp_server_endpoint_impl::is_local() const {
- return false;
-}
-
-void udp_server_endpoint_impl::start() {
- receive();
-}
-
-void udp_server_endpoint_impl::stop() {
- if (socket_.is_open())
- socket_.close();
-}
-
-void udp_server_endpoint_impl::receive() {
- packet_buffer_ptr_t its_buffer
- = std::make_shared< packet_buffer_t >();
- socket_.async_receive_from(
- boost::asio::buffer(*its_buffer),
- remote_,
- std::bind(
- &udp_server_endpoint_impl::receive_cbk,
- std::dynamic_pointer_cast<
- udp_server_endpoint_impl >(shared_from_this()),
- its_buffer,
- std::placeholders::_1,
- std::placeholders::_2
- )
- );
-}
-
-void udp_server_endpoint_impl::restart() {
- receive();
-}
-
-bool udp_server_endpoint_impl::send_to(
- const std::shared_ptr<endpoint_definition> _target,
- const byte_t *_data, uint32_t _size, bool _flush) {
- endpoint_type its_target(_target->get_address(), _target->get_port());
- return send_intern(its_target, _data, _size, _flush);
-}
-
-void udp_server_endpoint_impl::send_queued(
- endpoint_type _target, message_buffer_ptr_t _buffer) {
-#if 0
- std::stringstream msg;
- msg << "usei::sq(" << _target.address().to_string() << ":"
- << _target.port() << "): ";
- for (std::size_t i = 0; i < _buffer->size(); ++i)
- msg << std::hex << std::setw(2) << std::setfill('0')
- << (int)(*_buffer)[i] << " ";
- VSOMEIP_DEBUG << msg.str();
-#endif
- socket_.async_send_to(
- boost::asio::buffer(*_buffer),
- _target,
- std::bind(
- &udp_server_endpoint_base_impl::send_cbk,
- shared_from_this(),
- _buffer,
- std::placeholders::_1,
- std::placeholders::_2
- )
- );
-}
-
-udp_server_endpoint_impl::endpoint_type
-udp_server_endpoint_impl::get_remote() const {
- return remote_;
-}
-
-bool udp_server_endpoint_impl::get_multicast(service_t _service, event_t _event,
- udp_server_endpoint_impl::endpoint_type &_target) const {
- bool is_valid(false);
- auto find_service = multicasts_.find(_service);
- if (find_service != multicasts_.end()) {
- auto find_event = find_service->second.find(_event);
- if (find_event != find_service->second.end()) {
- _target = find_event->second;
- is_valid = true;
- }
- }
- return is_valid;
-}
-
-void udp_server_endpoint_impl::join(const std::string &_address) {
- if (local_.address().is_v4()) {
- try {
- socket_.set_option(
- boost::asio::ip::udp::socket::reuse_address(true));
- socket_.set_option(
- boost::asio::ip::multicast::enable_loopback(false));
- socket_.set_option(boost::asio::ip::multicast::join_group(
- boost::asio::ip::address::from_string(_address).to_v4()));
- }
- catch (const std::exception &e) {
- VSOMEIP_ERROR << e.what();
- }
- } else {
- // TODO: support multicast for IPv6
- }
-}
-
-void udp_server_endpoint_impl::leave(const std::string &_address) {
- if (local_.address().is_v4()) {
- try {
- socket_.set_option(boost::asio::ip::multicast::leave_group(
- boost::asio::ip::address::from_string(_address)));
- }
- catch (...) {
-
- }
- } else {
- // TODO: support multicast for IPv6
- }
-}
-
-void udp_server_endpoint_impl::add_multicast(
- service_t _service, instance_t _instance,
- const std::string &_address, uint16_t _port) {
- endpoint_type its_endpoint(
- boost::asio::ip::address::from_string(_address), _port);
- multicasts_[_service][_instance] = its_endpoint;
-}
-
-void udp_server_endpoint_impl::remove_multicast(
- service_t _service, instance_t _instance) {
- auto found_service = multicasts_.find(_service);
- if (found_service != multicasts_.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- found_service->second.erase(_instance);
- }
- }
-}
-
-unsigned short udp_server_endpoint_impl::get_local_port() const {
- return socket_.local_endpoint().port();
-}
-
-// TODO: find a better way to structure the receive functions
-void udp_server_endpoint_impl::receive_cbk(
- packet_buffer_ptr_t _buffer,
- boost::system::error_code const &_error, std::size_t _bytes) {
-#if 0
- std::stringstream msg;
- msg << "usei::rcb(" << _error.message() << "): ";
- for (std::size_t i = 0; i < _bytes; ++i)
- msg << std::hex << std::setw(2) << std::setfill('0')
- << (int)(*_buffer)[i] << " ";
- VSOMEIP_DEBUG << msg.str();
-#endif
- std::shared_ptr<endpoint_host> its_host = this->host_.lock();
- if (its_host) {
- if (!_error && 0 < _bytes) {
- message_.insert(message_.end(), _buffer->begin(),
- _buffer->begin() + _bytes);
-
- bool has_full_message;
- do {
- uint32_t current_message_size
- = utility::get_message_size(message_);
- has_full_message = (current_message_size > 0
- && current_message_size <= message_.size());
- if (has_full_message) {
- if (utility::is_request(
- message_[VSOMEIP_MESSAGE_TYPE_POS])) {
- client_t its_client;
- std::memcpy(&its_client,
- &message_[VSOMEIP_CLIENT_POS_MIN],
- sizeof(client_t));
- session_t its_session;
- std::memcpy(&its_session,
- &message_[VSOMEIP_SESSION_POS_MIN],
- sizeof(session_t));
- clients_[its_client][its_session] = remote_;
- }
-
- its_host->on_message(&message_[0],
- current_message_size, this);
- message_.erase(message_.begin(),
- message_.begin() + current_message_size);
- }
- } while (has_full_message);
-
- restart();
- } else {
- receive();
- }
- }
-}
-
-client_t udp_server_endpoint_impl::get_client(std::shared_ptr<endpoint_definition> _endpoint) {
- endpoint_type endpoint(_endpoint->get_address(), _endpoint->get_port());
- for (auto its_client : clients_) {
- for (auto its_session : clients_[its_client.first]) {
- if (endpoint == its_session.second) {
- // TODO: Check system byte order before convert!
- client_t client = its_client.first << 8 | its_client.first >> 8;
- return client;
- }
- }
- }
- return 0;
-}
-
-} // namespace vsomeip
+ boost::asio::detail::throw_error(ec, "bind");
+
+ boost::asio::socket_base::broadcast option(true);
+ socket_.set_option(option);
+}
+
+udp_server_endpoint_impl::~udp_server_endpoint_impl() {
+}
+
+bool udp_server_endpoint_impl::is_local() const {
+ return false;
+}
+
+void udp_server_endpoint_impl::start() {
+ receive();
+}
+
+void udp_server_endpoint_impl::stop() {
+ std::lock_guard<std::mutex> its_lock(stop_mutex_);
+ if (socket_.is_open()) {
+ socket_.close();
+ }
+}
+
+void udp_server_endpoint_impl::receive() {
+ if (recv_buffer_size_ == max_message_size_) {
+ // Overrun -> Reset buffer
+ recv_buffer_size_ = 0;
+ }
+ std::lock_guard<std::mutex> its_lock(stop_mutex_);
+ if(socket_.is_open()) {
+ size_t buffer_size = max_message_size_ - recv_buffer_size_;
+ socket_.async_receive_from(
+ boost::asio::buffer(&recv_buffer_[recv_buffer_size_], buffer_size),
+ remote_,
+ std::bind(
+ &udp_server_endpoint_impl::receive_cbk,
+ std::dynamic_pointer_cast<
+ udp_server_endpoint_impl >(shared_from_this()),
+ std::placeholders::_1,
+ std::placeholders::_2
+ )
+ );
+ }
+}
+
+void udp_server_endpoint_impl::restart() {
+ receive();
+}
+
+bool udp_server_endpoint_impl::send_to(
+ const std::shared_ptr<endpoint_definition> _target,
+ const byte_t *_data, uint32_t _size, bool _flush) {
+ endpoint_type its_target(_target->get_address(), _target->get_port());
+ return send_intern(its_target, _data, _size, _flush);
+}
+
+void udp_server_endpoint_impl::send_queued(
+ queue_iterator_type _queue_iterator) {
+ message_buffer_ptr_t its_buffer = _queue_iterator->second.front();
+#if 0
+ std::stringstream msg;
+ msg << "usei::sq(" << _queue_iterator->first.address().to_string() << ":"
+ << _queue_iterator->first.port() << "): ";
+ for (std::size_t i = 0; i < its_buffer->size(); ++i)
+ msg << std::hex << std::setw(2) << std::setfill('0')
+ << (int)(*its_buffer)[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
+#endif
+ socket_.async_send_to(
+ boost::asio::buffer(*its_buffer),
+ _queue_iterator->first,
+ std::bind(
+ &udp_server_endpoint_base_impl::send_cbk,
+ shared_from_this(),
+ _queue_iterator,
+ std::placeholders::_1,
+ std::placeholders::_2
+ )
+ );
+}
+
+udp_server_endpoint_impl::endpoint_type
+udp_server_endpoint_impl::get_remote() const {
+ return remote_;
+}
+
+bool udp_server_endpoint_impl::get_multicast(service_t _service, event_t _event,
+ udp_server_endpoint_impl::endpoint_type &_target) const {
+ bool is_valid(false);
+ auto find_service = multicasts_.find(_service);
+ if (find_service != multicasts_.end()) {
+ auto find_event = find_service->second.find(_event);
+ if (find_event != find_service->second.end()) {
+ _target = find_event->second;
+ is_valid = true;
+ }
+ }
+ return is_valid;
+}
+
+void udp_server_endpoint_impl::join(const std::string &_address) {
+ try {
+ if (local_.address().is_v4()) {
+ socket_.set_option(
+ boost::asio::ip::udp::socket::reuse_address(true));
+ socket_.set_option(
+ boost::asio::ip::multicast::enable_loopback(false));
+ socket_.set_option(boost::asio::ip::multicast::join_group(
+ boost::asio::ip::address::from_string(_address).to_v4()));
+ } else if (local_.address().is_v6()) {
+ socket_.set_option(
+ boost::asio::ip::udp::socket::reuse_address(true));
+ socket_.set_option(
+ boost::asio::ip::multicast::enable_loopback(false));
+ socket_.set_option(boost::asio::ip::multicast::join_group(
+ boost::asio::ip::address::from_string(_address).to_v6()));
+ }
+ }
+ catch (const std::exception &e) {
+ VSOMEIP_ERROR << e.what();
+ }
+}
+
+void udp_server_endpoint_impl::leave(const std::string &_address) {
+ try {
+ if (local_.address().is_v4()) {
+ socket_.set_option(boost::asio::ip::multicast::leave_group(
+ boost::asio::ip::address::from_string(_address)));
+ } else if (local_.address().is_v6()) {
+ socket_.set_option(boost::asio::ip::multicast::leave_group(
+ boost::asio::ip::address::from_string(_address)));
+ }
+ }
+ catch (const std::exception &e) {
+ VSOMEIP_ERROR << e.what();
+ }
+}
+
+void udp_server_endpoint_impl::add_multicast(
+ service_t _service, instance_t _instance,
+ const std::string &_address, uint16_t _port) {
+ endpoint_type its_endpoint(
+ boost::asio::ip::address::from_string(_address), _port);
+ multicasts_[_service][_instance] = its_endpoint;
+}
+
+void udp_server_endpoint_impl::remove_multicast(
+ service_t _service, instance_t _instance) {
+ auto found_service = multicasts_.find(_service);
+ if (found_service != multicasts_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ found_service->second.erase(_instance);
+ }
+ }
+}
+
+unsigned short udp_server_endpoint_impl::get_local_port() const {
+ return socket_.local_endpoint().port();
+}
+
+// TODO: find a better way to structure the receive functions
+void udp_server_endpoint_impl::receive_cbk(
+ boost::system::error_code const &_error, std::size_t _bytes) {
+#if 0
+ std::stringstream msg;
+ msg << "usei::rcb(" << _error.message() << "): ";
+ for (std::size_t i = 0; i < _bytes + recv_buffer_size_; ++i)
+ msg << std::hex << std::setw(2) << std::setfill('0')
+ << (int) recv_buffer_[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
+#endif
+ std::shared_ptr<endpoint_host> its_host = this->host_.lock();
+ if (its_host) {
+ if (!_error && 0 < _bytes) {
+ recv_buffer_size_ += _bytes;
+ uint32_t current_message_size
+ = utility::get_message_size(&this->recv_buffer_[0],
+ (uint32_t) recv_buffer_size_);
+ if (current_message_size > VSOMEIP_SOMEIP_HEADER_SIZE &&
+ current_message_size <= _bytes) {
+ if (utility::is_request(
+ recv_buffer_[VSOMEIP_MESSAGE_TYPE_POS])) {
+ client_t its_client;
+ std::memcpy(&its_client,
+ &recv_buffer_[VSOMEIP_CLIENT_POS_MIN],
+ sizeof(client_t));
+ session_t its_session;
+ std::memcpy(&its_session,
+ &recv_buffer_[VSOMEIP_SESSION_POS_MIN],
+ sizeof(session_t));
+ clients_[its_client][its_session] = remote_;
+ }
+ its_host->on_message(&recv_buffer_[0], current_message_size, this);
+ } else {
+ VSOMEIP_ERROR << "Received a unreliable vSomeIP message with bad length field";
+ service_t its_service = VSOMEIP_BYTES_TO_WORD(recv_buffer_[VSOMEIP_SERVICE_POS_MIN],
+ recv_buffer_[VSOMEIP_SERVICE_POS_MAX]);
+ if (its_service != VSOMEIP_SD_SERVICE) {
+ its_host->on_error(&recv_buffer_[0], (uint32_t)_bytes, this);
+ }
+ }
+ recv_buffer_size_ = 0;
+ restart();
+ } else {
+ receive();
+ }
+ }
+}
+
+client_t udp_server_endpoint_impl::get_client(std::shared_ptr<endpoint_definition> _endpoint) {
+ endpoint_type endpoint(_endpoint->get_address(), _endpoint->get_port());
+ for (auto its_client : clients_) {
+ for (auto its_session : clients_[its_client.first]) {
+ if (endpoint == its_session.second) {
+ // TODO: Check system byte order before convert!
+ client_t client = client_t(its_client.first << 8 | its_client.first >> 8);
+ return client;
+ }
+ }
+ }
+ return 0;
+}
+
+} // namespace vsomeip
diff --git a/implementation/endpoints/src/virtual_server_endpoint_impl.cpp b/implementation/endpoints/src/virtual_server_endpoint_impl.cpp
new file mode 100644
index 0000000..7700874
--- /dev/null
+++ b/implementation/endpoints/src/virtual_server_endpoint_impl.cpp
@@ -0,0 +1,114 @@
+// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <vsomeip/constants.hpp>
+
+#include "../include/virtual_server_endpoint_impl.hpp"
+#include "../../logging/include/logger.hpp"
+
+namespace vsomeip {
+
+virtual_server_endpoint_impl::virtual_server_endpoint_impl(
+ const std::string &_address, uint16_t _port, bool _reliable)
+ : address_(_address), port_(_port), reliable_(_reliable), use_count_(0) {
+}
+
+virtual_server_endpoint_impl::~virtual_server_endpoint_impl() {
+}
+
+void virtual_server_endpoint_impl::start() {
+}
+
+void virtual_server_endpoint_impl::stop() {
+}
+
+bool virtual_server_endpoint_impl::is_connected() const {
+ return false;
+}
+
+bool virtual_server_endpoint_impl::send(const byte_t *_data, uint32_t _size,
+ bool _flush) {
+ (void)_data;
+ (void)_size;
+ (void)_flush;
+ return false;
+}
+
+bool virtual_server_endpoint_impl::send_to(
+ const std::shared_ptr<endpoint_definition> _target,
+ const byte_t *_data, uint32_t _size, bool _flush) {
+ (void)_target;
+ (void)_data;
+ (void)_size;
+ (void)_flush;
+ return false;
+}
+
+void virtual_server_endpoint_impl::enable_magic_cookies() {
+}
+
+void virtual_server_endpoint_impl::receive() {
+}
+
+void virtual_server_endpoint_impl::join(const std::string &_address) {
+ (void)_address;
+}
+
+void virtual_server_endpoint_impl::leave(const std::string &_address) {
+ (void)_address;
+}
+
+void virtual_server_endpoint_impl::add_multicast(
+ service_t _service, event_t _event,
+ const std::string &_address, uint16_t _port) {
+ (void)_service;
+ (void)_event;
+ (void)_address;
+ (void)_port;
+}
+
+void virtual_server_endpoint_impl::remove_multicast(
+ service_t _service, event_t _event) {
+ (void)_service;
+ (void)_event;
+}
+
+bool virtual_server_endpoint_impl::get_remote_address(
+ boost::asio::ip::address &_address) const {
+ (void)_address;
+ return false;
+}
+
+unsigned short virtual_server_endpoint_impl::get_local_port() const {
+ return port_;
+}
+
+unsigned short virtual_server_endpoint_impl::get_remote_port() const {
+ return ILLEGAL_PORT;
+}
+
+bool virtual_server_endpoint_impl::is_reliable() const {
+ return reliable_;
+}
+
+bool virtual_server_endpoint_impl::is_local() const {
+ return true;
+}
+
+
+void virtual_server_endpoint_impl::increment_use_count() {
+ use_count_++;
+}
+
+void virtual_server_endpoint_impl::decrement_use_count() {
+ if (use_count_ > 0)
+ use_count_--;
+}
+
+uint32_t virtual_server_endpoint_impl::get_use_count() {
+ return use_count_;
+}
+
+} // namespace vsomeip
diff --git a/implementation/logging/include/logger.hpp b/implementation/logging/include/logger.hpp
new file mode 100644
index 0000000..555f15e
--- /dev/null
+++ b/implementation/logging/include/logger.hpp
@@ -0,0 +1,48 @@
+// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef VSOMEIP_LOGGER_HPP
+#define VSOMEIP_LOGGER_HPP
+
+#include <string>
+
+#ifdef WIN32
+#include <iostream>
+#endif
+
+#include <vsomeip/export.hpp>
+
+#include <boost/log/sources/severity_logger.hpp>
+#include <boost/log/trivial.hpp>
+
+namespace vsomeip {
+
+class VSOMEIP_EXPORT logger {
+public:
+ static std::shared_ptr<logger> get();
+
+ virtual ~logger() {
+ }
+
+ virtual boost::log::sources::severity_logger<
+ boost::log::trivial::severity_level> & get_internal() = 0;
+};
+
+#define VSOMEIP_FATAL BOOST_LOG_SEV(vsomeip::logger::get()->get_internal(), \
+ boost::log::trivial::severity_level::fatal)
+#define VSOMEIP_ERROR BOOST_LOG_SEV(vsomeip::logger::get()->get_internal(), \
+ boost::log::trivial::severity_level::error)
+#define VSOMEIP_WARNING BOOST_LOG_SEV(vsomeip::logger::get()->get_internal(), \
+ boost::log::trivial::severity_level::warning)
+#define VSOMEIP_INFO BOOST_LOG_SEV(vsomeip::logger::get()->get_internal(), \
+ boost::log::trivial::severity_level::info)
+#define VSOMEIP_DEBUG BOOST_LOG_SEV(vsomeip::logger::get()->get_internal(), \
+ boost::log::trivial::severity_level::debug)
+#define VSOMEIP_TRACE BOOST_LOG_SEV(vsomeip::logger::get()->get_internal(), \
+ boost::log::trivial::severity_level::trace)
+
+} // namespace vsomeip
+
+#endif // VSOMEIP_LOGGER_HPP
diff --git a/implementation/logging/include/logger_impl.hpp b/implementation/logging/include/logger_impl.hpp
index de98f25..56c2397 100644
--- a/implementation/logging/include/logger_impl.hpp
+++ b/implementation/logging/include/logger_impl.hpp
@@ -14,10 +14,12 @@
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/trivial.hpp>
-#include <vsomeip/logger.hpp>
+#include "logger.hpp"
namespace vsomeip {
+class configuration;
+
BOOST_LOG_ATTRIBUTE_KEYWORD(channel, "Channel", std::string)
BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity",
boost::log::trivial::severity_level)
@@ -28,7 +30,7 @@ typedef boost::log::sinks::synchronous_sink<
class logger_impl: public logger {
public:
static std::shared_ptr<logger_impl> & get();
- static void init(const std::string &_path);
+ static void init(const std::shared_ptr<configuration> &_configuration);
logger_impl();
diff --git a/implementation/logging/src/logger_impl.cpp b/implementation/logging/src/logger_impl.cpp
index f354a40..ef98749 100644
--- a/implementation/logging/src/logger_impl.cpp
+++ b/implementation/logging/src/logger_impl.cpp
@@ -29,8 +29,8 @@
#include <boost/core/null_deleter.hpp>
#endif
-#include <vsomeip/configuration.hpp>
#include "../include/logger_impl.hpp"
+#include "../../configuration/include/configuration.hpp"
namespace logging = boost::log;
namespace sources = boost::log::sources;
@@ -59,19 +59,19 @@ logger_impl::get_internal() {
return logger_;
}
-void logger_impl::init(const std::string &_path) {
- configuration *its_configuration = configuration::get(_path);
- get()->loglevel_ = its_configuration->get_loglevel();
+void logger_impl::init(const std::shared_ptr<configuration> &_configuration) {
+ get()->loglevel_ = _configuration->get_loglevel();
+
logging::core::get()->set_filter(
logging::trivial::severity >= get()->loglevel_);
- if (its_configuration->has_console_log())
+ if (_configuration->has_console_log())
get()->enable_console();
- if (its_configuration->has_file_log())
- get()->enable_file(its_configuration->get_logfile());
+ if (_configuration->has_file_log())
+ get()->enable_file(_configuration->get_logfile());
- if (its_configuration->has_dlt_log())
+ if (_configuration->has_dlt_log())
get()->enable_dlt();
}
diff --git a/implementation/message/include/message_header_impl.hpp b/implementation/message/include/message_header_impl.hpp
index 1d3e70b..b233d75 100644
--- a/implementation/message/include/message_header_impl.hpp
+++ b/implementation/message/include/message_header_impl.hpp
@@ -9,7 +9,7 @@
#include <vsomeip/export.hpp>
#include <vsomeip/primitive_types.hpp>
#include <vsomeip/enumeration_types.hpp>
-#include <vsomeip/serializable.hpp>
+#include <vsomeip/internal/serializable.hpp>
namespace vsomeip {
@@ -20,8 +20,8 @@ public:
VSOMEIP_EXPORT message_header_impl();
VSOMEIP_EXPORT message_header_impl(const message_header_impl& header);
- VSOMEIP_EXPORT virtual bool serialize(serializer *_to) const;
- VSOMEIP_EXPORT virtual bool deserialize(deserializer *_from);
+ VSOMEIP_EXPORT bool serialize(serializer *_to) const;
+ VSOMEIP_EXPORT bool deserialize(deserializer *_from);
// internal
VSOMEIP_EXPORT message_base * get_owner() const;
diff --git a/implementation/message/src/deserializer.cpp b/implementation/message/src/deserializer.cpp
index fb9cde6..6017d5a 100644
--- a/implementation/message/src/deserializer.cpp
+++ b/implementation/message/src/deserializer.cpp
@@ -9,7 +9,7 @@
#include <iomanip>
#include <sstream>
-#include <vsomeip/logger.hpp>
+#include "../../logging/include/logger.hpp"
#endif
#include "../include/message_impl.hpp"
@@ -19,186 +19,186 @@
namespace vsomeip {
deserializer::deserializer()
- : position_(data_.begin()),
- remaining_(0) {
+ : position_(data_.begin()),
+ remaining_(0) {
}
deserializer::deserializer(byte_t *_data, std::size_t _length)
- : data_(_data, _data + _length),
- position_(data_.begin()),
- remaining_(_length) {
+ : data_(_data, _data + _length),
+ position_(data_.begin()),
+ remaining_(_length) {
}
deserializer::deserializer(const deserializer &_other)
- : data_(_other.data_),
- position_(_other.position_){
+ : data_(_other.data_),
+ position_(_other.position_){
}
deserializer::~deserializer() {
}
std::size_t deserializer::get_available() const {
- return data_.size();
+ return data_.size();
}
std::size_t deserializer::get_remaining() const {
- return remaining_;
+ return remaining_;
}
void deserializer::set_remaining(std::size_t _remaining) {
- remaining_ = _remaining;
+ remaining_ = _remaining;
}
bool deserializer::deserialize(uint8_t& _value) {
- if (0 == remaining_)
- return false;
+ if (0 == remaining_)
+ return false;
- _value = *position_++;
+ _value = *position_++;
- remaining_--;
- return true;
+ remaining_--;
+ return true;
}
bool deserializer::deserialize(uint16_t& _value) {
- if (2 > remaining_)
- return false;
+ if (2 > remaining_)
+ return false;
- uint8_t byte0, byte1;
- byte0 = *position_++;
- byte1 = *position_++;
- remaining_ -= 2;
+ uint8_t byte0, byte1;
+ byte0 = *position_++;
+ byte1 = *position_++;
+ remaining_ -= 2;
- _value = VSOMEIP_BYTES_TO_WORD(byte0, byte1);
+ _value = VSOMEIP_BYTES_TO_WORD(byte0, byte1);
- return true;
+ return true;
}
bool deserializer::deserialize(uint32_t &_value, bool _omit_last_byte) {
- if (3 > remaining_ || (!_omit_last_byte && 4 > remaining_))
- return false;
+ if (3 > remaining_ || (!_omit_last_byte && 4 > remaining_))
+ return false;
- uint8_t byte0 = 0, byte1, byte2, byte3;
- if (!_omit_last_byte) {
- byte0 = *position_++;
- remaining_--;
- }
- byte1 = *position_++;
- byte2 = *position_++;
- byte3 = *position_++;
- remaining_ -= 3;
+ uint8_t byte0 = 0, byte1, byte2, byte3;
+ if (!_omit_last_byte) {
+ byte0 = *position_++;
+ remaining_--;
+ }
+ byte1 = *position_++;
+ byte2 = *position_++;
+ byte3 = *position_++;
+ remaining_ -= 3;
- _value = VSOMEIP_BYTES_TO_LONG(
- byte0, byte1, byte2, byte3);
+ _value = VSOMEIP_BYTES_TO_LONG(
+ byte0, byte1, byte2, byte3);
- return true;
+ return true;
}
bool deserializer::deserialize(uint8_t *_data, std::size_t _length) {
- if (_length > remaining_)
- return false;
+ if (_length > remaining_)
+ return false;
- std::memcpy(_data, &data_[position_ - data_.begin()], _length);
- position_ += _length;
- remaining_ -= _length;
+ std::memcpy(_data, &data_[position_ - data_.begin()], _length);
+ position_ += _length;
+ remaining_ -= _length;
- return true;
+ return true;
}
bool deserializer::deserialize(std::vector< uint8_t >& _value) {
- if (_value.capacity() > remaining_)
- return false;
+ if (_value.capacity() > remaining_)
+ return false;
- _value.assign(position_, position_ + _value.capacity());
- position_ += _value.capacity();
- remaining_ -= _value.capacity();
+ _value.assign(position_, position_ + _value.capacity());
+ position_ += _value.capacity();
+ remaining_ -= _value.capacity();
- return true;
+ return true;
}
bool deserializer::look_ahead(std::size_t _index, uint8_t &_value) const {
- if (_index >= data_.size())
- return false;
+ if (_index >= data_.size())
+ return false;
- _value = *(position_ + _index);
+ _value = *(position_ + _index);
- return true;
+ return true;
}
bool deserializer::look_ahead(std::size_t _index, uint16_t &_value) const {
- if (_index+1 >= data_.size())
- return false;
+ if (_index+1 >= data_.size())
+ return false;
- std::vector< uint8_t >::iterator i = position_ + _index;
- _value = VSOMEIP_BYTES_TO_WORD(*i, *(i+1));
+ std::vector< uint8_t >::iterator i = position_ + _index;
+ _value = VSOMEIP_BYTES_TO_WORD(*i, *(i+1));
- return true;
+ return true;
}
bool deserializer::look_ahead(std::size_t _index, uint32_t &_value) const {
- if (_index+3 >= data_.size())
- return false;
+ if (_index+3 >= data_.size())
+ return false;
- std::vector< uint8_t >::const_iterator i = position_ + _index;
- _value = VSOMEIP_BYTES_TO_LONG(*i, *(i+1), *(i+2), *(i+3));
+ std::vector< uint8_t >::const_iterator i = position_ + _index;
+ _value = VSOMEIP_BYTES_TO_LONG(*i, *(i+1), *(i+2), *(i+3));
- return true;
+ return true;
}
message * deserializer::deserialize_message() {
- message_impl* deserialized_message = new message_impl;
- if (0 != deserialized_message) {
- if (false == deserialized_message->deserialize(this)) {
- delete deserialized_message;
- deserialized_message = 0;
- }
- }
+ message_impl* deserialized_message = new message_impl;
+ if (0 != deserialized_message) {
+ if (false == deserialized_message->deserialize(this)) {
+ delete deserialized_message;
+ deserialized_message = 0;
+ }
+ }
- return deserialized_message;
+ return deserialized_message;
}
void deserializer::set_data(const byte_t *_data, std::size_t _length) {
- if (0 != _data) {
- data_.assign(_data, _data + _length);
- position_ = data_.begin();
- remaining_ = data_.end() - position_;
- } else {
- data_.clear();
- position_ = data_.end();
- remaining_ = 0;
- }
+ if (0 != _data) {
+ data_.assign(_data, _data + _length);
+ position_ = data_.begin();
+ remaining_ = data_.end() - position_;
+ } else {
+ data_.clear();
+ position_ = data_.end();
+ remaining_ = 0;
+ }
}
void deserializer::append_data(const byte_t *_data, std::size_t _length) {
- std::size_t offset = (position_ - data_.begin());
- data_.insert(data_.end(), _data, _data + _length);
- position_ = data_.begin() + offset;
- remaining_ += _length;
+ std::size_t offset = (position_ - data_.begin());
+ data_.insert(data_.end(), _data, _data + _length);
+ position_ = data_.begin() + offset;
+ remaining_ += _length;
}
void deserializer::drop_data(std::size_t _length) {
- if (position_ + _length < data_.end())
- position_ += _length;
- else
- position_ = data_.end();
+ if (position_ + _length < data_.end())
+ position_ += _length;
+ else
+ position_ = data_.end();
}
void deserializer::reset() {
- data_.erase(data_.begin(), position_);
- position_ = data_.begin();
- remaining_ = data_.size();
+ data_.erase(data_.begin(), position_);
+ position_ = data_.begin();
+ remaining_ = data_.size();
}
#ifdef VSOMEIP_DEBUGGING
void deserializer::show() const {
- std::stringstream its_message;
- its_message << "("
- << std::hex << std::setw(2) << std::setfill('0')
- << (int)*position_ << ", "
- << std:: dec << remaining_ << ") ";
- for (int i = 0; i < data_.size(); ++i)
- its_message << std::hex << std::setw(2) << std::setfill('0')
- << (int)data_[i] << " ";
- VSOMEIP_DEBUG << its_message;
+ std::stringstream its_message;
+ its_message << "("
+ << std::hex << std::setw(2) << std::setfill('0')
+ << (int)*position_ << ", "
+ << std:: dec << remaining_ << ") ";
+ for (int i = 0; i < data_.size(); ++i)
+ its_message << std::hex << std::setw(2) << std::setfill('0')
+ << (int)data_[i] << " ";
+ VSOMEIP_DEBUG << its_message;
}
#endif
diff --git a/implementation/message/src/message_base_impl.cpp b/implementation/message/src/message_base_impl.cpp
index c5ab95a..616ed63 100644
--- a/implementation/message/src/message_base_impl.cpp
+++ b/implementation/message/src/message_base_impl.cpp
@@ -10,7 +10,7 @@ namespace vsomeip {
message_base_impl::message_base_impl()
: is_reliable_(false) {
- header_.set_owner(this);
+ header_.set_owner(this);
}
message_base_impl::~message_base_impl() {
@@ -18,88 +18,88 @@ message_base_impl::~message_base_impl() {
// header interface
message_t message_base_impl::get_message() const {
- return VSOMEIP_WORDS_TO_LONG(header_.service_, header_.method_);
+ return VSOMEIP_WORDS_TO_LONG(header_.service_, header_.method_);
}
void message_base_impl::set_message(message_t _message) {
- header_.service_ = VSOMEIP_LONG_WORD0(_message);
- header_.method_ = VSOMEIP_LONG_WORD1(_message);
+ header_.service_ = VSOMEIP_LONG_WORD0(_message);
+ header_.method_ = VSOMEIP_LONG_WORD1(_message);
}
service_t message_base_impl::get_service() const {
- return header_.service_;
+ return header_.service_;
}
void message_base_impl::set_service(service_t _service) {
- header_.service_ = _service;
+ header_.service_ = _service;
}
instance_t message_base_impl::get_instance() const {
- return header_.instance_;
+ return header_.instance_;
}
void message_base_impl::set_instance(instance_t _instance) {
- header_.instance_ = _instance;
+ header_.instance_ = _instance;
}
method_t message_base_impl::get_method() const {
- return header_.method_;
+ return header_.method_;
}
void message_base_impl::set_method(method_t _method) {
- header_.method_ = _method;
+ header_.method_ = _method;
}
request_t message_base_impl::get_request() const {
- return VSOMEIP_WORDS_TO_LONG(header_.client_, header_.session_);
+ return VSOMEIP_WORDS_TO_LONG(header_.client_, header_.session_);
}
client_t message_base_impl::get_client() const {
- return header_.client_;
+ return header_.client_;
}
void message_base_impl::set_client(client_t _client) {
- header_.client_ = _client;
+ header_.client_ = _client;
}
session_t message_base_impl::get_session() const {
- return header_.session_;
+ return header_.session_;
}
void message_base_impl::set_session(session_t _session) {
- header_.session_ = _session;
+ header_.session_ = _session;
}
protocol_version_t message_base_impl::get_protocol_version() const {
- return header_.protocol_version_;
+ return header_.protocol_version_;
}
void message_base_impl::set_protocol_version(protocol_version_t _protocol_version) {
- header_.protocol_version_ = _protocol_version;
+ header_.protocol_version_ = _protocol_version;
}
interface_version_t message_base_impl::get_interface_version() const {
- return header_.interface_version_;
+ return header_.interface_version_;
}
void message_base_impl::set_interface_version(interface_version_t _interface_version) {
- header_.interface_version_ = _interface_version;
+ header_.interface_version_ = _interface_version;
}
message_type_e message_base_impl::get_message_type() const {
- return header_.type_;
+ return header_.type_;
}
void message_base_impl::set_message_type(message_type_e _type) {
- header_.type_ = _type;
+ header_.type_ = _type;
}
return_code_e message_base_impl::get_return_code() const {
- return header_.code_;
+ return header_.code_;
}
void message_base_impl::set_return_code(return_code_e _code) {
- header_.code_ = _code;
+ header_.code_ = _code;
}
bool message_base_impl::is_reliable() const {
diff --git a/implementation/message/src/message_header_impl.cpp b/implementation/message/src/message_header_impl.cpp
index 1bde36c..39446b7 100644
--- a/implementation/message/src/message_header_impl.cpp
+++ b/implementation/message/src/message_header_impl.cpp
@@ -13,66 +13,69 @@
namespace vsomeip {
message_header_impl::message_header_impl()
- : service_(0x0), instance_(0x0), method_(0x0),
- client_(0x0), session_(0x0),
- protocol_version_(0x1), interface_version_(0x0),
- type_(message_type_e::MT_UNKNOWN),
- code_(return_code_e::E_UNKNOWN) {
+ : service_(0x0), method_(0x0),
+ client_(0x0), session_(0x0),
+ protocol_version_(0x1), interface_version_(0x0),
+ type_(message_type_e::MT_UNKNOWN),
+ code_(return_code_e::E_UNKNOWN),
+ instance_(0x0) {
};
-message_header_impl::message_header_impl(const message_header_impl& _header)
- : service_(_header.service_), instance_(_header.instance_), method_(_header.method_),
- client_(_header.client_), session_(_header.session_),
- protocol_version_(_header.protocol_version_), interface_version_(_header.interface_version_),
- type_(_header.type_),
- code_(_header.code_) {
+message_header_impl::message_header_impl(const message_header_impl &_header)
+ : service_(_header.service_), method_(_header.method_),
+ client_(_header.client_), session_(_header.session_),
+ protocol_version_(_header.protocol_version_),
+ interface_version_(_header.interface_version_),
+ type_(_header.type_),
+ code_(_header.code_),
+ instance_(_header.instance_) {
};
bool message_header_impl::serialize(serializer *_to) const {
- return (0 != _to
- && _to->serialize(service_)
- && _to->serialize(method_)
- && _to->serialize(owner_->get_length())
- && _to->serialize(client_)
- && _to->serialize(session_)
- && _to->serialize(protocol_version_)
- && _to->serialize(interface_version_)
- && _to->serialize(static_cast<uint8_t>(type_))
- && _to->serialize(static_cast<uint8_t>(code_)));
+ return (0 != _to
+ && _to->serialize(service_)
+ && _to->serialize(method_)
+ && _to->serialize(owner_->get_length())
+ && _to->serialize(client_)
+ && _to->serialize(session_)
+ && _to->serialize(protocol_version_)
+ && _to->serialize(interface_version_)
+ && _to->serialize(static_cast<uint8_t>(type_))
+ && _to->serialize(static_cast<uint8_t>(code_)));
};
bool message_header_impl::deserialize(deserializer *_from) {
- bool is_successful;
+ bool is_successful;
- uint8_t tmp_message_type, tmp_return_code;
- uint32_t tmp_length;
+ uint8_t tmp_message_type, tmp_return_code;
+ uint32_t tmp_length;
- is_successful = (0 != _from
- && _from->deserialize(service_)
- && _from->deserialize(method_)
- && _from->deserialize(tmp_length)
- && _from->deserialize(client_)
- && _from->deserialize(session_)
- && _from->deserialize(protocol_version_)
- && _from->deserialize(interface_version_)
- && _from->deserialize(tmp_message_type)
- && _from->deserialize(tmp_return_code));
+ is_successful = (0 != _from
+ && _from->deserialize(service_)
+ && _from->deserialize(method_)
+ && _from->deserialize(tmp_length)
+ && _from->deserialize(client_)
+ && _from->deserialize(session_)
+ && _from->deserialize(protocol_version_)
+ && _from->deserialize(interface_version_)
+ && _from->deserialize(tmp_message_type)
+ && _from->deserialize(tmp_return_code));
- if (is_successful) {
- type_ = static_cast< message_type_e >(tmp_message_type);
- code_ = static_cast< return_code_e >(tmp_return_code);
- length_ = static_cast< length_t >(tmp_length - VSOMEIP_SOMEIP_HEADER_SIZE);
- }
+ if (is_successful) {
+ type_ = static_cast< message_type_e >(tmp_message_type);
+ code_ = static_cast< return_code_e >(tmp_return_code);
+ length_ = static_cast< length_t >(tmp_length - VSOMEIP_SOMEIP_HEADER_SIZE);
+ }
- return is_successful;
+ return is_successful;
};
message_base * message_header_impl::get_owner() const {
- return owner_;
+ return owner_;
}
void message_header_impl::set_owner(message_base *_owner) {
- owner_ = _owner;
+ owner_ = _owner;
}
} // namespace vsomeip
diff --git a/implementation/message/src/message_impl.cpp b/implementation/message/src/message_impl.cpp
index 51596a0..c19ae76 100644
--- a/implementation/message/src/message_impl.cpp
+++ b/implementation/message/src/message_impl.cpp
@@ -20,31 +20,31 @@ message_impl::~message_impl() {
}
length_t message_impl::get_length() const {
- return (VSOMEIP_SOMEIP_HEADER_SIZE
- + (payload_ ? payload_->get_length() : 0));
+ return (VSOMEIP_SOMEIP_HEADER_SIZE
+ + (payload_ ? payload_->get_length() : 0));
}
std::shared_ptr< payload > message_impl::get_payload() const {
- return payload_;
+ return payload_;
}
void message_impl::set_payload(std::shared_ptr< payload > _payload) {
- payload_ = _payload;
+ payload_ = _payload;
}
bool message_impl::serialize(serializer *_to) const {
- return (header_.serialize(_to)
- && (payload_ ? payload_->serialize(_to) : true));
+ return (header_.serialize(_to)
+ && (payload_ ? payload_->serialize(_to) : true));
}
bool message_impl::deserialize(deserializer *_from) {
- payload_ = runtime::get()->create_payload();
- bool is_successful = header_.deserialize(_from);
- if (is_successful) {
- payload_->set_capacity(header_.length_);
- is_successful = payload_->deserialize(_from);
- }
- return is_successful;
+ payload_ = runtime::get()->create_payload();
+ bool is_successful = header_.deserialize(_from);
+ if (is_successful) {
+ payload_->set_capacity(header_.length_);
+ is_successful = payload_->deserialize(_from);
+ }
+ return is_successful;
}
} // namespace vsomeip
diff --git a/implementation/message/src/payload_impl.cpp b/implementation/message/src/payload_impl.cpp
index 62e48e0..3355788 100644
--- a/implementation/message/src/payload_impl.cpp
+++ b/implementation/message/src/payload_impl.cpp
@@ -10,66 +10,66 @@
namespace vsomeip {
payload_impl::payload_impl()
- : data_() {
+ : data_() {
}
payload_impl::payload_impl(const byte_t *_data, uint32_t _size) {
- data_.assign(_data, _data + _size);
+ data_.assign(_data, _data + _size);
}
payload_impl::payload_impl(const std::vector<byte_t> &_data)
- : data_(_data) {
+ : data_(_data) {
}
payload_impl::payload_impl(const payload_impl& _payload)
- : data_(_payload.data_) {
+ : data_(_payload.data_) {
}
payload_impl::~payload_impl() {
}
bool payload_impl::operator==(const payload &_other) {
- bool is_equal(true);
- try {
- const payload_impl &other = dynamic_cast< const payload_impl & >(_other);
- is_equal = (data_ == other.data_);
- }
- catch (...) {
- is_equal = false;
- }
- return is_equal;
+ bool is_equal(true);
+ try {
+ const payload_impl &other = dynamic_cast< const payload_impl & >(_other);
+ is_equal = (data_ == other.data_);
+ }
+ catch (...) {
+ is_equal = false;
+ }
+ return is_equal;
}
byte_t * payload_impl::get_data() {
- return data_.data();
+ return data_.data();
}
const byte_t * payload_impl::get_data() const {
- return data_.data();
+ return data_.data();
}
length_t payload_impl::get_length() const {
- return data_.size();
+ return length_t(data_.size());
}
void payload_impl::set_capacity(length_t _capacity) {
- data_.reserve(_capacity);
+ data_.reserve(_capacity);
}
void payload_impl::set_data(const byte_t *_data, const length_t _length) {
- data_.assign(_data, _data + _length);
+ data_.assign(_data, _data + _length);
}
void payload_impl::set_data(const std::vector< byte_t > &_data) {
- data_ = _data;
+ data_ = _data;
}
bool payload_impl::serialize(serializer *_to) const {
- return (0 != _to && _to->serialize(data_.data(), data_.size()));
+ return (0 != _to && _to->serialize(data_.data(), uint32_t(data_.size())));
}
bool payload_impl::deserialize(deserializer *_from) {
- return (0 != _from && _from->deserialize(data_));
+ return (0 != _from && _from->deserialize(data_));
}
} // namespace vsomeip
diff --git a/implementation/message/src/serializer.cpp b/implementation/message/src/serializer.cpp
index cfa32ec..6c064ab 100644
--- a/implementation/message/src/serializer.cpp
+++ b/implementation/message/src/serializer.cpp
@@ -9,10 +9,10 @@
#include <iomanip>
#include <sstream>
-#include <vsomeip/logger.hpp>
+#include "../../logging/include/logger.hpp"
#endif
-#include <vsomeip/serializable.hpp>
+#include <vsomeip/internal/serializable.hpp>
#include "../include/serializer.hpp"
#include "../../utility/include/byteorder.hpp"
@@ -20,115 +20,117 @@
namespace vsomeip {
serializer::serializer()
- : data_(0), capacity_(0), position_(0), remaining_(0) {
+ : data_(0), capacity_(0), position_(0), remaining_(0) {
}
serializer::~serializer() {
+ if (0 != data_)
+ delete [] data_;
};
bool serializer::serialize(const serializable *_from) {
- return (_from && _from->serialize(this));
+ return (_from && _from->serialize(this));
}
bool serializer::serialize(const uint8_t _value) {
- if (1 > remaining_)
- return false;
+ if (1 > remaining_)
+ return false;
- *position_++ = _value;
- remaining_--;
+ *position_++ = _value;
+ remaining_--;
- return true;
+ return true;
}
bool serializer::serialize(const uint16_t _value) {
- if (2 > remaining_)
- return false;
+ if (2 > remaining_)
+ return false;
- *position_++ = VSOMEIP_WORD_BYTE1(_value);
- *position_++ = VSOMEIP_WORD_BYTE0(_value);
- remaining_ -= 2;
+ *position_++ = VSOMEIP_WORD_BYTE1(_value);
+ *position_++ = VSOMEIP_WORD_BYTE0(_value);
+ remaining_ -= 2;
- return true;
+ return true;
}
bool serializer::serialize(const uint32_t _value, bool _omit_last_byte) {
- if (3 > remaining_ || (!_omit_last_byte && 4 > remaining_))
- return false;
-
- if (!_omit_last_byte) {
- *position_++ = VSOMEIP_LONG_BYTE3(_value);
- remaining_--;
- }
- *position_++ = VSOMEIP_LONG_BYTE2(_value);
- *position_++ = VSOMEIP_LONG_BYTE1(_value);
- *position_++ = VSOMEIP_LONG_BYTE0(_value);
- remaining_ -= 3;
-
- return true;
+ if (3 > remaining_ || (!_omit_last_byte && 4 > remaining_))
+ return false;
+
+ if (!_omit_last_byte) {
+ *position_++ = VSOMEIP_LONG_BYTE3(_value);
+ remaining_--;
+ }
+ *position_++ = VSOMEIP_LONG_BYTE2(_value);
+ *position_++ = VSOMEIP_LONG_BYTE1(_value);
+ *position_++ = VSOMEIP_LONG_BYTE0(_value);
+ remaining_ -= 3;
+
+ return true;
}
bool serializer::serialize(const uint8_t *_data, uint32_t _length) {
- if (_length > remaining_)
- return false;
+ if (_length > remaining_)
+ return false;
- ::memcpy(position_, _data, _length);
- position_ += _length;
- remaining_ -= _length;
+ ::memcpy(position_, _data, _length);
+ position_ += _length;
+ remaining_ -= _length;
- return true;
+ return true;
}
byte_t * serializer::get_data() const {
- return data_;
+ return data_;
}
uint32_t serializer::get_capacity() const {
- return capacity_;
+ return capacity_;
}
uint32_t serializer::get_size() const {
- return capacity_ - remaining_;
+ return capacity_ - remaining_;
}
void serializer::create_data(uint32_t _capacity) {
- if (0 != data_)
- delete [] data_;
-
- data_ = new byte_t[_capacity];
- position_ = data_;
- if (0 != data_) {
- capacity_ = remaining_ = _capacity;
- } else {
- capacity_ = remaining_ = 0;
- }
+ if (0 != data_)
+ delete [] data_;
+
+ data_ = new byte_t[_capacity];
+ position_ = data_;
+ if (0 != data_) {
+ capacity_ = remaining_ = _capacity;
+ } else {
+ capacity_ = remaining_ = 0;
+ }
}
void serializer::set_data(byte_t *_data, uint32_t _capacity) {
- delete [] data_;
+ delete [] data_;
- data_ = _data;
- position_ = _data;
+ data_ = _data;
+ position_ = _data;
- if (0 != data_) {
- capacity_ = remaining_ = _capacity;
- } else {
- capacity_ = remaining_ = 0;
- }
+ if (0 != data_) {
+ capacity_ = remaining_ = _capacity;
+ } else {
+ capacity_ = remaining_ = 0;
+ }
}
void serializer::reset() {
- position_ = data_;
- remaining_ = capacity_;
+ position_ = data_;
+ remaining_ = capacity_;
}
#ifdef VSOMEIP_DEBUGGING
void serializer::show() {
- std::stringstream its_data;
- its_data << "SERIALIZED: ";
- for (int i = 0; i < position_ - data_; ++i)
- its_data << std::setw(2) << std::setfill('0')
- << std::hex << (int)data_[i];
- VSOMEIP_DEBUG << its_data.str();
+ std::stringstream its_data;
+ its_data << "SERIALIZED: ";
+ for (int i = 0; i < position_ - data_; ++i)
+ its_data << std::setw(2) << std::setfill('0')
+ << std::hex << (int)data_[i];
+ VSOMEIP_DEBUG << its_data.str();
}
#endif
diff --git a/implementation/routing/include/event.hpp b/implementation/routing/include/event.hpp
index 7332c9a..89153ad 100644
--- a/implementation/routing/include/event.hpp
+++ b/implementation/routing/include/event.hpp
@@ -54,6 +54,9 @@ public:
bool is_reliable() const;
void set_reliable(bool _is_reliable);
+ bool is_provided() const;
+ void set_provided(bool _is_provided);
+
// SIP_RPC_357
void set_update_cycle(std::chrono::milliseconds &_cycle);
@@ -69,6 +72,9 @@ public:
void notify_one(const std::shared_ptr<endpoint_definition> &_target);
void notify_one(client_t _client);
+ void add_ref();
+ uint32_t remove_ref();
+
private:
void update_cbk(boost::system::error_code const &_error);
void notify();
@@ -91,6 +97,9 @@ private:
std::set<eventgroup_t> eventgroups_;
bool is_set_;
+ bool is_provided_;
+
+ uint32_t ref_;
};
} // namespace vsomeip
diff --git a/implementation/routing/include/eventgroupinfo.hpp b/implementation/routing/include/eventgroupinfo.hpp
index 558c3b9..08536e0 100644
--- a/implementation/routing/include/eventgroupinfo.hpp
+++ b/implementation/routing/include/eventgroupinfo.hpp
@@ -39,11 +39,12 @@ public:
VSOMEIP_EXPORT const std::set<std::shared_ptr<event> > get_events() const;
VSOMEIP_EXPORT void add_event(std::shared_ptr<event> _event);
+ VSOMEIP_EXPORT void remove_event(std::shared_ptr<event> _event);
VSOMEIP_EXPORT const std::set<
std::shared_ptr<endpoint_definition> > get_targets() const;
- VSOMEIP_EXPORT void add_target(std::shared_ptr<endpoint_definition> _target);
- VSOMEIP_EXPORT void del_target(std::shared_ptr<endpoint_definition> _target);
+ VSOMEIP_EXPORT bool add_target(std::shared_ptr<endpoint_definition> _target);
+ VSOMEIP_EXPORT bool remove_target(std::shared_ptr<endpoint_definition> _target);
VSOMEIP_EXPORT void clear_targets();
private:
diff --git a/implementation/routing/include/routing_manager.hpp b/implementation/routing/include/routing_manager.hpp
index 44a63ac..7791add 100644
--- a/implementation/routing/include/routing_manager.hpp
+++ b/implementation/routing/include/routing_manager.hpp
@@ -36,21 +36,21 @@ public:
virtual void offer_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl) = 0;
+ minor_version_t _minor) = 0;
virtual void stop_offer_service(client_t _client, service_t _service,
instance_t _instance) = 0;
virtual void request_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl, bool _has_selective) = 0;
+ minor_version_t _minor, bool _use_exclusive_proxy) = 0;
virtual void release_service(client_t _client, service_t _service,
instance_t _instance) = 0;
virtual void subscribe(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup,
- major_version_t _major, ttl_t _ttl) = 0;
+ major_version_t _major) = 0;
virtual void unsubscribe(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup) = 0;
@@ -67,6 +67,13 @@ public:
virtual bool send_to(const std::shared_ptr<endpoint_definition> &_target,
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,
+ bool _is_field, bool _is_provided) = 0;
+
+ virtual void unregister_event(client_t _client, service_t _service, instance_t _instance,
+ event_t _event, bool _is_provided) = 0;
+
virtual void notify(service_t _service, instance_t _instance,
event_t _event, std::shared_ptr<payload> _payload) = 0;
diff --git a/implementation/routing/include/routing_manager_host.hpp b/implementation/routing/include/routing_manager_host.hpp
index a80b86d..7b96be0 100644
--- a/implementation/routing/include/routing_manager_host.hpp
+++ b/implementation/routing/include/routing_manager_host.hpp
@@ -29,7 +29,7 @@ public:
virtual void on_availability(service_t _service, instance_t _instance,
bool _is_available) const = 0;
- virtual void on_event(event_type_e _event) = 0;
+ virtual void on_state(state_type_e _state) = 0;
virtual void on_message(std::shared_ptr<message> _message) = 0;
virtual void on_error(error_code_e _error) = 0;
virtual bool on_subscription(service_t _service, instance_t _instance, eventgroup_t _eventgroup,
diff --git a/implementation/routing/include/routing_manager_impl.hpp b/implementation/routing/include/routing_manager_impl.hpp
index b2d5200..a0d692c 100644
--- a/implementation/routing/include/routing_manager_impl.hpp
+++ b/implementation/routing/include/routing_manager_impl.hpp
@@ -63,20 +63,20 @@ public:
void offer_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl);
+ minor_version_t _minor);
void stop_offer_service(client_t _client, service_t _service,
instance_t _instance);
void request_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl, bool _has_selective);
+ minor_version_t _minor, bool _use_exclusive_proxy);
void release_service(client_t _client, service_t _service,
instance_t _instance);
void subscribe(client_t _client, service_t _service, instance_t _instance,
- eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl);
+ eventgroup_t _eventgroup, major_version_t _major);
void unsubscribe(client_t _client, service_t _service, instance_t _instance,
eventgroup_t _eventgroup);
@@ -92,6 +92,15 @@ public:
bool send_to(const std::shared_ptr<endpoint_definition> &_target,
const byte_t *_data, uint32_t _size);
+ void register_event(client_t _client, service_t _service,
+ instance_t _instance, event_t _event,
+ std::set<eventgroup_t> _eventgroups,
+ bool _is_field, bool _is_provided);
+
+ void unregister_event(client_t _client, service_t _service,
+ instance_t _instance, event_t _event,
+ bool _is_provided);
+
void notify(service_t _service, instance_t _instance, event_t _event,
std::shared_ptr<payload> _payload);
@@ -113,25 +122,31 @@ public:
bool _reliable, client_t _client);
void on_connect(std::shared_ptr<endpoint> _endpoint);
void on_disconnect(std::shared_ptr<endpoint> _endpoint);
+ void on_error(const byte_t *_data, length_t _length, endpoint *_receiver);
void on_message(const byte_t *_data, length_t _length, endpoint *_receiver);
void on_message(service_t _service, instance_t _instance,
const byte_t *_data, length_t _size, bool _reliable);
+ void on_notification(client_t _client, service_t _service,
+ instance_t _instance, const byte_t *_data, length_t _size);
// interface "service_discovery_host"
typedef std::map<std::string, std::shared_ptr<servicegroup> > servicegroups_t;
const servicegroups_t & get_servicegroups() const;
std::shared_ptr<eventgroupinfo> find_eventgroup(service_t _service,
instance_t _instance, eventgroup_t _eventgroup) const;
- services_t get_offered_services(const std::string &_name) const;
- void create_service_discovery_endpoint(const std::string &_address,
+ services_t get_offered_services() const;
+ std::shared_ptr<endpoint> create_service_discovery_endpoint(const std::string &_address,
uint16_t _port, bool _reliable);
void init_routing_info();
void add_routing_info(service_t _service, instance_t _instance,
major_version_t _major, minor_version_t _minor, ttl_t _ttl,
- const boost::asio::ip::address &_address, uint16_t _port,
- bool _reliable);
+ const boost::asio::ip::address &_reliable_address,
+ uint16_t _reliable_port,
+ const boost::asio::ip::address &_unreliable_address,
+ uint16_t _unreliable_port);
void del_routing_info(service_t _service, instance_t _instance,
- bool _reliable);
+ bool _has_reliable, bool _has_unreliable);
+ ttl_t update_routing_info(ttl_t _elapsed);
void on_subscribe(service_t _service, instance_t _instance,
eventgroup_t _eventgroup,
@@ -143,11 +158,11 @@ public:
void on_subscribe_ack(service_t _service, instance_t _instance,
const boost::asio::ip::address &_address, uint16_t _port);
- void init_event_routing_info();
-
private:
bool deliver_message(const byte_t *_data, length_t _length,
instance_t _instance, bool _reliable);
+ bool deliver_notification(service_t _service, instance_t _instance,
+ const byte_t *_data, length_t _length, bool _reliable);
bool send_local(
std::shared_ptr<endpoint> &_target, client_t _client,
const byte_t *_data, uint32_t _size, instance_t _instance,
@@ -160,56 +175,71 @@ private:
std::shared_ptr<serviceinfo> find_service(service_t _service,
instance_t _instance) const;
- std::shared_ptr<serviceinfo> create_service(service_t _service,
+ std::shared_ptr<serviceinfo> create_service_info(service_t _service,
instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl);
+ minor_version_t _minor, ttl_t _ttl, bool _is_local_service);
std::shared_ptr<endpoint> create_client_endpoint(
const boost::asio::ip::address &_address, uint16_t _port,
- bool _reliable, client_t _client);
- std::shared_ptr<endpoint> find_client_endpoint(
- const boost::asio::ip::address &_address, uint16_t _port,
- bool _reliable, client_t _client);
- std::shared_ptr<endpoint> find_or_create_client_endpoint(
- const boost::asio::ip::address &_address, uint16_t _port,
- bool _reliable, client_t _client);
+ bool _reliable, client_t _client, bool _start);
+
+ void remove_eventgroup_info(service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup);
std::shared_ptr<endpoint> create_server_endpoint(uint16_t _port,
- bool _reliable);
+ bool _reliable, bool _start);
std::shared_ptr<endpoint> find_server_endpoint(uint16_t _port,
- bool _reliable);
+ bool _reliable);
std::shared_ptr<endpoint> find_or_create_server_endpoint(uint16_t _port,
- bool _reliable);
+ bool _reliable, bool _start);
std::set<std::shared_ptr<event> > find_events(service_t _service,
instance_t _instance, eventgroup_t _eventgroup);
std::shared_ptr<event> find_event(service_t _service, instance_t _instance,
event_t _event) const;
+ bool is_field(service_t _service, instance_t _instance,
+ event_t _event) const;
std::shared_ptr<endpoint> find_remote_client(service_t _service,
- instance_t _instance,
- bool _reliable, client_t _client);
+ instance_t _instance, bool _reliable, client_t _client);
std::shared_ptr<endpoint> create_remote_client(service_t _service,
- instance_t _instance,
- bool _reliable, client_t _client);
+ instance_t _instance, bool _reliable, client_t _client);
+
+ bool deliver_specific_endpoint_message(service_t _service, instance_t _instance,
+ const byte_t *_data, length_t _size, endpoint *_receiver);
+
+ void clear_client_endpoints(service_t _service, instance_t _instance, bool _reliable);
+ void stop_and_delete_client_endpoint(std::shared_ptr<endpoint> _endpoint);
+ void clear_multicast_endpoints(service_t _service, instance_t _instance);
+ void clear_service_info(service_t _service, instance_t _instance, bool _reliable);
private:
void send_subscribe(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup,
- major_version_t _major, ttl_t _ttl);
+ major_version_t _major);
void send_unsubscribe(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup);
- boost::asio::io_service &io_;
- routing_manager_host *host_;
+ bool insert_subscription(service_t _service, instance_t _instance,
+ eventgroup_t _eventgroup, client_t _client);
- std::shared_ptr<configuration> configuration_;
+ return_code_e check_error(const byte_t *_data, length_t _size,
+ instance_t _instance);
+
+ void send_error(return_code_e _return_code, const byte_t *_data,
+ length_t _size, instance_t _instance, bool _reliable,
+ endpoint *_receiver);
+
+ routing_manager_host *host_;
+ boost::asio::io_service &io_;
std::shared_ptr<deserializer> deserializer_;
std::shared_ptr<serializer> serializer_;
+ std::shared_ptr<configuration> configuration_;
+
std::shared_ptr<routing_manager_stub> stub_;
std::shared_ptr<sd::service_discovery> discovery_;
@@ -223,15 +253,20 @@ private:
std::map<uint16_t, std::map<bool, std::shared_ptr<endpoint> > > server_endpoints_;
std::map<service_t, std::map<endpoint *, instance_t> > service_instances_;
+ // Multicast endpoint info (notifications)
+ std::map<service_t, std::map<instance_t, std::shared_ptr<endpoint_definition> > > multicast_info;
+
// Client endpoints for remote services
- std::map<boost::asio::ip::address,
- std::map<uint16_t, std::map<client_t, std::map<bool, std::shared_ptr<endpoint> > > > > client_endpoints_;
+ std::map<service_t,
+ std::map<instance_t, std::map<bool, std::shared_ptr<endpoint_definition> > > > remote_service_info_;
+
std::map<service_t,
std::map<instance_t, std::map<client_t, std::map<bool, std::shared_ptr<endpoint> > > > >remote_services_;
+ std::map<boost::asio::ip::address,
+ std::map<uint16_t, std::map<bool, std::shared_ptr<endpoint> > > > client_endpoints_by_ip_;
- // Servicegroups
- std::map<std::string, std::shared_ptr<servicegroup> > servicegroups_;
- std::map<service_t, std::map<instance_t, std::shared_ptr<serviceinfo> > > services_;
+ // Services
+ services_t services_;
// Eventgroups
std::map<service_t,
@@ -246,6 +281,8 @@ private:
mutable std::recursive_mutex endpoint_mutex_;
mutable std::mutex local_mutex_;
std::mutex serialize_mutex_;
+ mutable std::mutex services_mutex_;
+ mutable std::mutex eventgroups_mutex_;
std::map<client_t, std::shared_ptr<endpoint_definition>> remote_subscriber_map_;
diff --git a/implementation/routing/include/routing_manager_proxy.hpp b/implementation/routing/include/routing_manager_proxy.hpp
index a142db8..852ca19 100644
--- a/implementation/routing/include/routing_manager_proxy.hpp
+++ b/implementation/routing/include/routing_manager_proxy.hpp
@@ -39,20 +39,20 @@ public:
void offer_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl);
+ minor_version_t _minor);
void stop_offer_service(client_t _client, service_t _service,
instance_t _instance);
void request_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl, bool _has_selective);
+ minor_version_t _minor, bool _use_exclusive_proxy);
void release_service(client_t _client, service_t _service,
instance_t _instance);
void subscribe(client_t _client, service_t _service, instance_t _instance,
- eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl);
+ eventgroup_t _eventgroup, major_version_t _major);
void unsubscribe(client_t _client, service_t _service, instance_t _instance,
eventgroup_t _eventgroup);
@@ -68,15 +68,26 @@ public:
bool send_to(const std::shared_ptr<endpoint_definition> &_target,
const byte_t *_data, uint32_t _size);
+ void register_event(client_t _client, service_t _service,
+ instance_t _instance, event_t _event,
+ std::set<eventgroup_t> _eventgroups,
+ bool _is_field, bool _is_provided);
+
+ void unregister_event(client_t _client, service_t _service,
+ instance_t _instance, event_t _event,
+ bool _is_provided);
+
void notify(service_t _service, instance_t _instance, event_t _event,
std::shared_ptr<payload> _payload);
void notify_one(service_t _service, instance_t _instance,
- event_t _event, std::shared_ptr<payload> _payload, client_t _client);
+ event_t _event, std::shared_ptr<payload> _payload,
+ client_t _client);
void on_connect(std::shared_ptr<endpoint> _endpoint);
void on_disconnect(std::shared_ptr<endpoint> _endpoint);
void on_message(const byte_t *_data, length_t _length, endpoint *_receiver);
+ void on_error(const byte_t *_data, length_t _length, endpoint *_receiver);
void on_routing_info(const byte_t *_data, uint32_t _size);
@@ -95,36 +106,47 @@ private:
void send_pong() const;
void send_offer_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl);
+ minor_version_t _minor);
+ void send_request_service(client_t _client, service_t _service,
+ instance_t _instance, major_version_t _major,
+ 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,
+ 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, ttl_t _ttl);
+ major_version_t _major);
- void send_request_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl, bool _is_selective);
+ bool is_field(service_t _service, instance_t _instance,
+ event_t _event) const;
private:
- boost::asio::io_service &io_;bool is_connected_;bool is_started_;
- event_type_e state_;
+ boost::asio::io_service &io_;
+ bool is_connected_;
+ bool is_started_;
+ state_type_e state_;
routing_manager_host *host_;
client_t client_; // store locally as it is needed in each message
+ std::shared_ptr<configuration> configuration_;
+
std::shared_ptr<serializer> serializer_;
std::shared_ptr<deserializer> deserializer_;
- std::shared_ptr<endpoint> sender_; // --> stub
+ std::shared_ptr<endpoint> sender_; // --> stub
std::shared_ptr<endpoint> receiver_; // --> from everybody
std::map<client_t, std::shared_ptr<endpoint> > local_endpoints_;
std::map<service_t, std::map<instance_t, client_t> > local_services_;
+ std::mutex local_services_mutex_;
struct service_data_t {
service_t service_;
instance_t instance_;
major_version_t major_;
minor_version_t minor_;
- ttl_t ttl_;
+ bool use_exclusive_proxy_; // only used for requests!
bool operator<(const service_data_t &_other) const {
return (service_ < _other.service_
@@ -135,12 +157,30 @@ private:
std::set<service_data_t> pending_offers_;
std::set<service_data_t> pending_requests_;
+ struct event_data_t {
+ service_t service_;
+ instance_t instance_;
+ event_t event_;
+ bool is_field_;
+ bool is_provided_;
+ std::set<eventgroup_t> eventgroups_;
+
+ bool operator<(const event_data_t &_other) const {
+ return (service_ < _other.service_
+ || (service_ == _other.service_
+ && instance_ < _other.instance_)
+ || (service_ == _other.service_
+ && instance_ == _other.instance_
+ && event_ < _other.event_));
+ }
+ };
+ std::set<event_data_t> pending_event_registrations_;
+
struct eventgroup_data_t {
service_t service_;
instance_t instance_;
eventgroup_t eventgroup_;
major_version_t major_;
- ttl_t ttl_;
bool operator<(const eventgroup_data_t &_other) const {
return (service_ < _other.service_
@@ -163,7 +203,7 @@ private:
std::mutex deserialize_mutex_;
std::mutex pending_mutex_;
- bool is_selective_;
+ std::map<service_t, std::map<instance_t, std::set<event_t> > > fields_;
};
} // namespace vsomeip
diff --git a/implementation/routing/include/routing_manager_stub.hpp b/implementation/routing/include/routing_manager_stub.hpp
index c261303..6a1ec38 100644
--- a/implementation/routing/include/routing_manager_stub.hpp
+++ b/implementation/routing/include/routing_manager_stub.hpp
@@ -19,12 +19,15 @@
namespace vsomeip {
+class configuration;
class routing_manager_stub_host;
class routing_manager_stub: public endpoint_host,
public std::enable_shared_from_this<routing_manager_stub> {
public:
- routing_manager_stub(routing_manager_stub_host *_host);
+ routing_manager_stub(
+ routing_manager_stub_host *_host,
+ std::shared_ptr<configuration> _configuration);
virtual ~routing_manager_stub();
void init();
@@ -34,6 +37,7 @@ public:
void on_connect(std::shared_ptr<endpoint> _endpoint);
void on_disconnect(std::shared_ptr<endpoint> _endpoint);
void on_message(const byte_t *_data, length_t _length, endpoint *_receiver);
+ void on_error(const byte_t *_data, length_t _length, endpoint *_receiver);
void on_offer_service(client_t _client, service_t _service,
instance_t _instance);
@@ -56,17 +60,17 @@ private:
void send_application_lost(std::list<client_t> &_lost);
private:
+ routing_manager_stub_host *host_;
boost::asio::io_service &io_;
boost::asio::system_timer watchdog_timer_;
- routing_manager_stub_host *host_;
-
std::string endpoint_path_;
std::shared_ptr<endpoint> endpoint_;
std::map<client_t,
std::pair<uint8_t, std::map<service_t, std::set<instance_t> > > > routing_info_;
mutable std::mutex routing_info_mutex_;
+ std::shared_ptr<configuration> configuration_;
};
} // namespace vsomeip
diff --git a/implementation/routing/include/routing_manager_stub_host.hpp b/implementation/routing/include/routing_manager_stub_host.hpp
index 049bc13..f25eef2 100644
--- a/implementation/routing/include/routing_manager_stub_host.hpp
+++ b/implementation/routing/include/routing_manager_stub_host.hpp
@@ -17,21 +17,29 @@ public:
virtual void offer_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl) = 0;
+ minor_version_t _minor) = 0;
virtual void stop_offer_service(client_t _client, service_t _service,
instance_t _instance) = 0;
virtual void request_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl, bool _has_selective) = 0;
+ minor_version_t _minor, bool _use_exclusive_proxy) = 0;
virtual void release_service(client_t _client, service_t _service,
instance_t _instance) = 0;
+ virtual void register_event(client_t _client, service_t _service,
+ instance_t _instance, event_t _event,
+ 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, event_t _event, bool _is_provided) = 0;
+
virtual void subscribe(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup,
- major_version_t _major, ttl_t _ttl) = 0;
+ major_version_t _major) = 0;
virtual void unsubscribe(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup) = 0;
@@ -39,6 +47,10 @@ public:
virtual void on_message(service_t _service, instance_t _instance,
const byte_t *_data, length_t _size, bool _reliable) = 0;
+ virtual void on_notification(client_t _client,
+ service_t _service, instance_t _instance,
+ const byte_t *_data, length_t _size) = 0;
+
virtual void on_stop_offer_service(service_t _service,
instance_t _instance) = 0;
diff --git a/implementation/routing/include/servicegroup.hpp b/implementation/routing/include/servicegroup.hpp
deleted file mode 100644
index 6014df1..0000000
--- a/implementation/routing/include/servicegroup.hpp
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-#ifndef VSOMEIP_SERVICEGROUP_HPP
-#define VSOMEIP_SERVICEGROUP_HPP
-
-#include <memory>
-#include <set>
-#include <string>
-
-#include "types.hpp"
-
-namespace vsomeip {
-
-class serviceinfo;
-
-class servicegroup {
-public:
- servicegroup(const std::string &_name, bool _is_local);
- virtual ~servicegroup();
-
- std::string get_name() const;
- bool is_local() const;
-
- bool add_service(service_t _service, instance_t _instance,
- std::shared_ptr<serviceinfo> _info);
- bool remove_service(service_t _service, instance_t _instance);
-
- services_t get_services() const;
-
-private:
- std::string name_;
- bool is_local_;
- services_t services_;
-};
-
-} // namespace vsomeip
-
-#endif // VSOMEIP_SERVICEGROUP_HPP
diff --git a/implementation/routing/include/serviceinfo.hpp b/implementation/routing/include/serviceinfo.hpp
index a98127e..af3a50c 100644
--- a/implementation/routing/include/serviceinfo.hpp
+++ b/implementation/routing/include/serviceinfo.hpp
@@ -21,7 +21,7 @@ class servicegroup;
class serviceinfo {
public:
VSOMEIP_EXPORT serviceinfo(major_version_t _major, minor_version_t _minor,
- ttl_t _ttl);
+ ttl_t _ttl, bool _is_local);
VSOMEIP_EXPORT ~serviceinfo();
VSOMEIP_EXPORT servicegroup * get_group() const;
@@ -49,6 +49,8 @@ public:
VSOMEIP_EXPORT void add_client(client_t _client);
VSOMEIP_EXPORT void remove_client(client_t _client);
+ VSOMEIP_EXPORT bool is_local() const;
+
private:
servicegroup *group_;
@@ -64,6 +66,8 @@ private:
eventgroup_t multicast_group_;
std::set<client_t> requesters_;
+
+ bool is_local_;
};
} // namespace vsomeip
diff --git a/implementation/routing/src/event.cpp b/implementation/routing/src/event.cpp
index eb86a12..4572632 100644
--- a/implementation/routing/src/event.cpp
+++ b/implementation/routing/src/event.cpp
@@ -4,7 +4,6 @@
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <vsomeip/defines.hpp>
-#include <vsomeip/logger.hpp>
#include <vsomeip/message.hpp>
#include <vsomeip/payload.hpp>
#include <vsomeip/runtime.hpp>
@@ -12,6 +11,7 @@
#include "../include/event.hpp"
#include "../include/routing_manager.hpp"
#include "../../configuration/include/internal.hpp"
+#include "../../logging/include/logger.hpp"
#include "../../message/include/payload_impl.hpp"
namespace vsomeip {
@@ -21,7 +21,8 @@ event::event(routing_manager *_routing) :
message_(runtime::get()->create_notification()),
cycle_timer_(_routing->get_io()),
is_updating_on_change_(true),
- is_set_(false) {
+ is_set_(false),
+ ref_(0) {
}
service_t event::get_service() const {
@@ -56,6 +57,14 @@ void event::set_field(bool _is_field) {
is_field_ = _is_field;
}
+bool event::is_provided() const {
+ return (is_provided_);
+}
+
+void event::set_provided(bool _is_provided) {
+ is_provided_ = _is_provided;
+}
+
bool event::is_reliable() const {
return message_->is_reliable();
}
@@ -69,64 +78,76 @@ const std::shared_ptr<payload> event::get_payload() const {
}
void event::set_payload(std::shared_ptr<payload> _payload) {
- if (set_payload_helper(_payload)) {
- std::shared_ptr<payload> its_new_payload
- = runtime::get()->create_payload(
- _payload->get_data(), _payload->get_length());
-
- message_->set_payload(its_new_payload);
- if (is_updating_on_change_) {
- notify();
- }
- }
+ if (is_provided_) {
+ if (set_payload_helper(_payload)) {
+ std::shared_ptr<payload> its_new_payload
+ = runtime::get()->create_payload(
+ _payload->get_data(), _payload->get_length());
+
+ message_->set_payload(its_new_payload);
+ if (is_updating_on_change_) {
+ notify();
+ }
+ }
+ }
}
void event::set_payload(std::shared_ptr<payload> _payload, client_t _client) {
- set_payload_helper(_payload);
- std::shared_ptr<payload> its_new_payload
- = runtime::get()->create_payload(
- _payload->get_data(), _payload->get_length());
-
- message_->set_payload(its_new_payload);
- if (is_updating_on_change_) {
- notify_one(_client);
- }
+ if (is_provided_) {
+ set_payload_helper(_payload);
+ std::shared_ptr<payload> its_new_payload
+ = runtime::get()->create_payload(
+ _payload->get_data(), _payload->get_length());
+
+ message_->set_payload(its_new_payload);
+ if (is_updating_on_change_) {
+ notify_one(_client);
+ }
+ }
}
void event::set_payload(std::shared_ptr<payload> _payload,
const std::shared_ptr<endpoint_definition> _target) {
-
- set_payload_helper(_payload);
- std::shared_ptr<payload> its_new_payload
- = runtime::get()->create_payload(
- _payload->get_data(), _payload->get_length());
-
- message_->set_payload(its_new_payload);
- if (is_updating_on_change_) {
- notify_one(_target);
- }
+ if (is_provided_) {
+ if (set_payload_helper(_payload)) {
+ std::shared_ptr<payload> its_new_payload
+ = runtime::get()->create_payload(
+ _payload->get_data(), _payload->get_length());
+
+ message_->set_payload(its_new_payload);
+ if (is_updating_on_change_) {
+ notify_one(_target);
+ }
+ }
+ }
}
void event::unset_payload() {
- is_set_ = false;
- message_->set_payload(std::make_shared<payload_impl>());
+ if (is_provided_) {
+ is_set_ = false;
+ message_->set_payload(std::make_shared<payload_impl>());
+ }
}
void event::set_update_on_change(bool _is_active) {
- is_updating_on_change_ = _is_active;
+ if (is_provided_) {
+ is_updating_on_change_ = _is_active;
+ }
}
void event::set_update_cycle(std::chrono::milliseconds &_cycle) {
- cycle_ = _cycle;
+ if (is_provided_) {
+ cycle_ = _cycle;
- cycle_timer_.cancel();
+ cycle_timer_.cancel();
- if (std::chrono::milliseconds::zero() != _cycle) {
- cycle_timer_.expires_from_now(cycle_);
- std::function<void(boost::system::error_code const &)> its_handler =
- std::bind(&event::update_cbk, shared_from_this(),
- std::placeholders::_1);
- cycle_timer_.async_wait(its_handler);
+ if (std::chrono::milliseconds::zero() != _cycle) {
+ cycle_timer_.expires_from_now(cycle_);
+ std::function<void(boost::system::error_code const &)> its_handler =
+ std::bind(&event::update_cbk, shared_from_this(),
+ std::placeholders::_1);
+ cycle_timer_.async_wait(its_handler);
+ }
}
}
@@ -172,7 +193,7 @@ void event::notify_one(client_t _client) {
bool event::set_payload_helper(std::shared_ptr<payload> _payload) {
std::shared_ptr<payload> its_payload = message_->get_payload();
bool is_change(!is_field_);
- if(is_field_) {
+ if (is_field_) {
is_change = (its_payload->get_length() != _payload->get_length());
if (!is_change) {
std::size_t its_pos = 0;
@@ -189,4 +210,13 @@ bool event::set_payload_helper(std::shared_ptr<payload> _payload) {
return is_change;
}
+void event::add_ref() {
+ ref_++;
+}
+
+uint32_t event::remove_ref() {
+ ref_--;
+ return ref_;
+}
+
} // namespace vsomeip
diff --git a/implementation/routing/src/eventgroupinfo.cpp b/implementation/routing/src/eventgroupinfo.cpp
index 64d9b6b..0d098e4 100644
--- a/implementation/routing/src/eventgroupinfo.cpp
+++ b/implementation/routing/src/eventgroupinfo.cpp
@@ -10,76 +10,83 @@
namespace vsomeip {
eventgroupinfo::eventgroupinfo()
- : major_(DEFAULT_MAJOR),
- ttl_(DEFAULT_TTL),
- is_multicast_(false) {
+ : major_(DEFAULT_MAJOR), ttl_(DEFAULT_TTL), is_multicast_(false) {
}
eventgroupinfo::eventgroupinfo(major_version_t _major, ttl_t _ttl)
- : major_(_major),
- ttl_(_ttl),
- is_multicast_(false) {
+ : major_(_major), ttl_(_ttl), is_multicast_(false) {
}
eventgroupinfo::~eventgroupinfo() {
}
major_version_t eventgroupinfo::get_major() const {
- return major_;
+ return major_;
}
void eventgroupinfo::set_major(major_version_t _major) {
- major_ = _major;
+ major_ = _major;
}
ttl_t eventgroupinfo::get_ttl() const {
- return ttl_;
+ return ttl_;
}
void eventgroupinfo::set_ttl(ttl_t _ttl) {
- ttl_ = _ttl;
+ ttl_ = _ttl;
}
bool eventgroupinfo::is_multicast() const {
- return is_multicast_;
+ return is_multicast_;
}
-bool eventgroupinfo::get_multicast(boost::asio::ip::address &_address, uint16_t &_port) const {
- if (is_multicast_) {
- _address = address_;
- _port = port_;
- }
- return is_multicast_;
+bool eventgroupinfo::get_multicast(boost::asio::ip::address &_address,
+ uint16_t &_port) const {
+ if (is_multicast_) {
+ _address = address_;
+ _port = port_;
+ }
+ return is_multicast_;
}
-void eventgroupinfo::set_multicast(const boost::asio::ip::address &_address, uint16_t _port) {
- address_ = _address;
- port_ = _port;
- is_multicast_ = true;
+void eventgroupinfo::set_multicast(const boost::asio::ip::address &_address,
+ uint16_t _port) {
+ address_ = _address;
+ port_ = _port;
+ is_multicast_ = true;
}
const std::set<std::shared_ptr<event> > eventgroupinfo::get_events() const {
- return events_;
+ return events_;
}
void eventgroupinfo::add_event(std::shared_ptr<event> _event) {
- events_.insert(_event);
+ events_.insert(_event);
+}
+
+void eventgroupinfo::remove_event(std::shared_ptr<event> _event) {
+ events_.erase(_event);
}
const std::set<std::shared_ptr<endpoint_definition> > eventgroupinfo::get_targets() const {
- return targets_;
+ return targets_;
}
-void eventgroupinfo::add_target(std::shared_ptr<endpoint_definition> _target) {
- targets_.insert(_target);
+bool eventgroupinfo::add_target(std::shared_ptr<endpoint_definition> _target) {
+ std::size_t its_size = targets_.size();
+ targets_.insert(_target);
+ return (its_size != targets_.size());
}
-void eventgroupinfo::del_target(std::shared_ptr<endpoint_definition> _target) {
- targets_.erase(_target);
+bool eventgroupinfo::remove_target(
+ std::shared_ptr<endpoint_definition> _target) {
+ std::size_t its_size = targets_.size();
+ targets_.erase(_target);
+ return (its_size != targets_.size());
}
void eventgroupinfo::clear_targets() {
- targets_.clear();
+ targets_.clear();
}
} // namespace vsomeip
diff --git a/implementation/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp
index d22a76e..ff1c67e 100644
--- a/implementation/routing/src/routing_manager_impl.cpp
+++ b/implementation/routing/src/routing_manager_impl.cpp
@@ -7,9 +7,7 @@
#include <memory>
#include <sstream>
-#include <vsomeip/configuration.hpp>
#include <vsomeip/constants.hpp>
-#include <vsomeip/logger.hpp>
#include <vsomeip/message.hpp>
#include <vsomeip/payload.hpp>
#include <vsomeip/runtime.hpp>
@@ -19,8 +17,8 @@
#include "../include/routing_manager_host.hpp"
#include "../include/routing_manager_impl.hpp"
#include "../include/routing_manager_stub.hpp"
-#include "../include/servicegroup.hpp"
#include "../include/serviceinfo.hpp"
+#include "../../configuration/include/configuration.hpp"
#include "../../configuration/include/internal.hpp"
#include "../../endpoints/include/endpoint_definition.hpp"
#include "../../endpoints/include/local_client_endpoint_impl.hpp"
@@ -28,6 +26,8 @@
#include "../../endpoints/include/tcp_server_endpoint_impl.hpp"
#include "../../endpoints/include/udp_client_endpoint_impl.hpp"
#include "../../endpoints/include/udp_server_endpoint_impl.hpp"
+#include "../../endpoints/include/virtual_server_endpoint_impl.hpp"
+#include "../../logging/include/logger.hpp"
#include "../../message/include/deserializer.hpp"
#include "../../message/include/serializer.hpp"
#include "../../service_discovery/include/constants.hpp"
@@ -40,10 +40,11 @@
namespace vsomeip {
routing_manager_impl::routing_manager_impl(routing_manager_host *_host) :
- host_(_host), io_(_host->get_io()), deserializer_(
- std::make_shared<deserializer>()), serializer_(
- std::make_shared<serializer>()), configuration_(
- host_->get_configuration()) {
+ host_(_host),
+ io_(_host->get_io()),
+ deserializer_(std::make_shared<deserializer>()),
+ serializer_(std::make_shared<serializer>()),
+ configuration_(host_->get_configuration()) {
}
routing_manager_impl::~routing_manager_impl() {
@@ -58,22 +59,16 @@ client_t routing_manager_impl::get_client() const {
}
void routing_manager_impl::init() {
- uint32_t its_max_message_size = VSOMEIP_MAX_LOCAL_MESSAGE_SIZE;
- if (VSOMEIP_MAX_TCP_MESSAGE_SIZE > its_max_message_size)
- its_max_message_size = VSOMEIP_MAX_TCP_MESSAGE_SIZE;
- if (VSOMEIP_MAX_UDP_MESSAGE_SIZE > its_max_message_size)
- its_max_message_size = VSOMEIP_MAX_UDP_MESSAGE_SIZE;
-
- serializer_->create_data(its_max_message_size);
+ serializer_->create_data(configuration_->get_max_message_size_local());
// TODO: Only instantiate the stub if needed
- stub_ = std::make_shared<routing_manager_stub>(this);
+ stub_ = std::make_shared<routing_manager_stub>(this, configuration_);
stub_->init();
// We need to be able to send messages to ourself (for delivering events)
(void)create_local(VSOMEIP_ROUTING_CLIENT);
- if (configuration_->is_service_discovery_enabled()) {
+ if (configuration_->is_sd_enabled()) {
VSOMEIP_INFO<< "Service Discovery enabled. Trying to load module.";
std::shared_ptr<sd::runtime> *its_runtime =
static_cast<std::shared_ptr<sd::runtime> *>(utility::load_library(
@@ -85,10 +80,8 @@ void routing_manager_impl::init() {
discovery_ = (*its_runtime)->create_service_discovery(this);
discovery_->init();
}
-
- init_event_routing_info();
} else {
- init_routing_info();
+ init_routing_info(); // Static routing
}
}
@@ -97,11 +90,11 @@ void routing_manager_impl::start() {
if (discovery_)
discovery_->start();
- host_->on_event(event_type_e::ET_REGISTERED);
+ host_->on_state(state_type_e::ST_REGISTERED);
}
void routing_manager_impl::stop() {
- host_->on_event(event_type_e::ET_DEREGISTERED);
+ host_->on_state(state_type_e::ST_DEREGISTERED);
if (discovery_)
discovery_->stop();
@@ -109,8 +102,7 @@ void routing_manager_impl::stop() {
}
void routing_manager_impl::offer_service(client_t _client, service_t _service,
- instance_t _instance, major_version_t _major, minor_version_t _minor,
- ttl_t _ttl) {
+ instance_t _instance, major_version_t _major, minor_version_t _minor) {
std::shared_ptr<serviceinfo> its_info;
{
std::lock_guard<std::mutex> its_lock(local_mutex_);
@@ -121,20 +113,18 @@ void routing_manager_impl::offer_service(client_t _client, service_t _service,
if (its_info) {
if (its_info->get_major() == _major
&& its_info->get_minor() == _minor) {
- its_info->set_ttl(_ttl);
+ its_info->set_ttl(DEFAULT_TTL);
} else {
host_->on_error(error_code_e::SERVICE_PROPERTY_MISMATCH);
}
} else {
- its_info = create_service(_service, _instance, _major, _minor, _ttl);
+ its_info = create_service_info(_service, _instance, _major, _minor,
+ DEFAULT_TTL, true);
}
}
if (discovery_ && its_info) {
- std::string group_name("default");
- if (its_info->get_group())
- group_name = its_info->get_group()->get_name();
- discovery_->on_offer_change(group_name);
+ discovery_->on_offer_change();
}
stub_->on_offer_service(_client, _service, _instance);
@@ -149,26 +139,26 @@ void routing_manager_impl::stop_offer_service(client_t _client,
void routing_manager_impl::request_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major, minor_version_t _minor,
- ttl_t _ttl, bool _has_selective) {
+ bool _use_exclusive_proxy) {
std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance));
if (its_info) {
- if ((_major < ANY_MAJOR && _major > its_info->get_major())
- || (_major == its_info->get_major()
- && _minor < ANY_MINOR && _minor > its_info->get_minor())
- || (_ttl > its_info->get_ttl())) {
- host_->on_error(error_code_e::SERVICE_PROPERTY_MISMATCH);
- } else {
+ if ((_major == its_info->get_major()
+ || DEFAULT_MAJOR == its_info->get_major())
+ && (_minor <= its_info->get_minor()
+ || DEFAULT_MINOR == its_info->get_minor())) {
its_info->add_client(_client);
+ } else {
+ host_->on_error(error_code_e::SERVICE_PROPERTY_MISMATCH);
}
} else {
if (discovery_)
discovery_->request_service(_service, _instance, _major, _minor,
- _ttl);
+ DEFAULT_TTL);
}
// TODO: Mutex?!
- if (_has_selective) {
+ if (_use_exclusive_proxy) {
specific_endpoint_clients.insert(_client);
}
}
@@ -185,35 +175,36 @@ 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,
- ttl_t _ttl) {
+ instance_t _instance, eventgroup_t _eventgroup, major_version_t _major) {
if (discovery_) {
if (!host_->on_subscription(_service, _instance, _eventgroup, _client, true)) {
VSOMEIP_INFO << "Subscription request for eventgroup " << _eventgroup
- << " rejected from application handler";
+ << " rejected from application handler";
return;
}
- eventgroup_clients_[_service][_instance][_eventgroup].insert(_client);
- if (0 == find_local_client(_service, _instance)) {
- client_t subscriber = VSOMEIP_ROUTING_CLIENT;
- // subscriber != VSOMEIP_ROUTING_CLIENT implies to use its own endpoint
- auto its_selective = specific_endpoint_clients.find(_client);
- if (its_selective != specific_endpoint_clients.end()) {
- subscriber = _client;
- }
- discovery_->subscribe(_service, _instance, _eventgroup, _major,
- _ttl, subscriber);
- } else {
- send_subscribe(_client, _service, _instance, _eventgroup, _major, _ttl);
- std::shared_ptr<eventgroupinfo> its_eventgroup
- = find_eventgroup(_service, _instance, _eventgroup);
- if (its_eventgroup) {
- std::set<std::shared_ptr<event> > its_events
- = its_eventgroup->get_events();
- for (auto e : its_events) {
- if (e->is_field())
- e->notify_one(_client);
+ if (insert_subscription(_service, _instance, _eventgroup, _client)) {
+ if (0 == find_local_client(_service, _instance)) {
+ client_t subscriber = VSOMEIP_ROUTING_CLIENT;
+ // subscriber != VSOMEIP_ROUTING_CLIENT implies to use its own endpoint
+ auto its_selective = specific_endpoint_clients.find(_client);
+ if (its_selective != specific_endpoint_clients.end()) {
+ subscriber = _client;
+ }
+ discovery_->subscribe(_service, _instance, _eventgroup,
+ _major, DEFAULT_TTL, subscriber);
+ } else {
+ send_subscribe(_client, _service, _instance, _eventgroup, _major);
+
+ std::shared_ptr<eventgroupinfo> its_eventgroup
+ = find_eventgroup(_service, _instance, _eventgroup);
+ if (its_eventgroup) {
+ std::set<std::shared_ptr<event> > its_events
+ = its_eventgroup->get_events();
+ for (auto e : its_events) {
+ if (e->is_field())
+ e->notify_one(_client);
+ }
}
}
}
@@ -240,12 +231,18 @@ void routing_manager_impl::unsubscribe(client_t _client, service_t _service,
}
}
host_->on_subscription(_service, _instance, _eventgroup, _client, false);
-
if (0 == find_local_client(_service, _instance)) {
- discovery_->unsubscribe(_service, _instance, _eventgroup);
+ client_t subscriber = VSOMEIP_ROUTING_CLIENT;
+ // subscriber != VSOMEIP_ROUTING_CLIENT implies to use its own endpoint
+ auto its_selective = specific_endpoint_clients.find(_client);
+ if (its_selective != specific_endpoint_clients.end()) {
+ subscriber = _client;
+ }
+ discovery_->unsubscribe(_service, _instance, _eventgroup, subscriber);
} else {
send_unsubscribe(_client, _service, _instance, _eventgroup);
}
+ clear_multicast_endpoints(_service, _instance);
} else {
VSOMEIP_ERROR<< "SOME/IP eventgroups require SD to be enabled!";
}
@@ -265,6 +262,8 @@ bool routing_manager_impl::send(client_t its_client,
serializer_->get_size(), _message->get_instance(),
_flush, _message->is_reliable());
serializer_->reset();
+ } else {
+ VSOMEIP_ERROR << "Failed to serialize message. Check message size!";
}
return (is_sent);
@@ -409,7 +408,7 @@ bool routing_manager_impl::send_local(
std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + _size
+ sizeof(instance_t) + sizeof(bool)], &_reliable, sizeof(bool));
- return _target->send(&its_command[0], its_command.size(), _flush);
+ return _target->send(&its_command[0], uint32_t(its_command.size()), _flush);
}
bool routing_manager_impl::send_to(
@@ -430,12 +429,94 @@ bool routing_manager_impl::send_to(
bool routing_manager_impl::send_to(
const std::shared_ptr<endpoint_definition> &_target,
const byte_t *_data, uint32_t _size) {
- std::shared_ptr<endpoint> its_endpoint = find_or_create_server_endpoint(
+ std::shared_ptr<endpoint> its_endpoint = find_server_endpoint(
_target->get_remote_port(), _target->is_reliable());
return (its_endpoint && its_endpoint->send_to(_target, _data, _size));
}
+void routing_manager_impl::register_event(client_t _client,
+ service_t _service, instance_t _instance,
+ event_t _event, std::set<eventgroup_t> _eventgroups,
+ bool _is_field, bool _is_provided) {
+ (void)_client;
+
+ std::shared_ptr<event> its_event = find_event(_service, _instance, _event);
+ if (its_event) {
+ if (its_event->is_field() == _is_field) {
+ if (_is_provided) {
+ its_event->set_provided(true);
+ }
+ for (auto eg : _eventgroups) {
+ its_event->add_eventgroup(eg);
+ }
+ } else {
+ VSOMEIP_ERROR << "Event registration update failed. "
+ "Specified arguments do not match existing registration.";
+ }
+ } else {
+ its_event = std::make_shared<event>(this);
+ its_event->set_service(_service);
+ its_event->set_instance(_instance);
+ its_event->set_event(_event);
+ its_event->set_field(_is_field);
+ its_event->set_provided(_is_provided);
+
+ if (_eventgroups.size() == 0) { // No eventgroup specified
+ _eventgroups.insert(_event);
+ }
+
+ its_event->set_eventgroups(_eventgroups);
+ }
+
+ its_event->add_ref();
+
+ for (auto eg : _eventgroups) {
+ std::shared_ptr<eventgroupinfo> its_eventgroup_info
+ = find_eventgroup(_service, _instance, eg);
+ if (!its_eventgroup_info) {
+ its_eventgroup_info = std::make_shared<eventgroupinfo>();
+ eventgroups_[_service][_instance][eg] = its_eventgroup_info;
+ }
+ its_eventgroup_info->add_event(its_event);
+ }
+
+ events_[_service][_instance][_event] = its_event;
+}
+
+void routing_manager_impl::unregister_event(client_t _client,
+ service_t _service, instance_t _instance,
+ event_t _event, bool _is_provided) {
+ (void)_client;
+
+ auto found_service = events_.find(_service);
+ if (found_service != events_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ auto found_event = found_instance->second.find(_event);
+ if (found_event != found_instance->second.end()) {
+ auto its_event = found_event->second;
+ if (!its_event->remove_ref()) {
+ auto its_eventgroups = its_event->get_eventgroups();
+ for (auto eg : its_eventgroups) {
+ std::shared_ptr<eventgroupinfo> its_eventgroup_info
+ = find_eventgroup(_service, _instance, eg);
+ if (its_eventgroup_info) {
+ its_eventgroup_info->remove_event(its_event);
+ if (0 == its_eventgroup_info->get_events().size()) {
+ remove_eventgroup_info(_service, _instance, eg);
+ }
+ }
+ }
+ found_instance->second.erase(_event);
+ } else if (_is_provided) {
+ its_event->set_provided(false);
+ }
+ }
+ }
+ }
+}
+
void routing_manager_impl::notify(
service_t _service, instance_t _instance, event_t _event,
std::shared_ptr<payload> _payload) {
@@ -443,9 +524,9 @@ void routing_manager_impl::notify(
if (its_event) {
its_event->set_payload(_payload);
} else {
- VSOMEIP_ERROR << "routing_manager_impl::notify: event ["
+ VSOMEIP_WARNING << "Attempt to update the undefined event/field ["
<< std::hex << _service << "." << _instance << "." << _event
- << "] is unknown.";
+ << "]";
}
}
@@ -466,10 +547,21 @@ void routing_manager_impl::notify_one(service_t _service, instance_t _instance,
}
}
} else {
- VSOMEIP_ERROR << "routing_manager_impl::notify: event ["
+ VSOMEIP_WARNING << "Attempt to update the undefined event/field ["
<< std::hex << _service << "." << _instance << "." << _event
- << "] is unknown.";
+ << "]";
+ }
+}
+
+void routing_manager_impl::on_error(const byte_t *_data, length_t _length, endpoint *_receiver) {
+ instance_t its_instance = 0;
+ if (_length >= VSOMEIP_SERVICE_POS_MAX) {
+ service_t its_service = VSOMEIP_BYTES_TO_WORD(
+ _data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]);
+ its_instance = find_instance(its_service, _receiver);
}
+ send_error(return_code_e::E_MALFORMED_MESSAGE, _data, _length,
+ its_instance, _receiver->is_reliable(), _receiver);
}
void routing_manager_impl::on_message(const byte_t *_data, length_t _size,
@@ -482,9 +574,6 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size,
VSOMEIP_DEBUG << msg.str();
#endif
service_t its_service;
- instance_t its_instance;
- message_type_e its_message_type;
-
if (_size >= VSOMEIP_SOMEIP_HEADER_SIZE) {
its_service = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_SERVICE_POS_MIN],
_data[VSOMEIP_SERVICE_POS_MAX]);
@@ -492,41 +581,21 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size,
if (discovery_)
discovery_->on_message(_data, _size);
} else {
- its_instance = find_instance(its_service, _receiver);
- its_message_type = static_cast<message_type_e>(_data[VSOMEIP_MESSAGE_TYPE_POS]);
- if (its_instance == 0xFFFF) {
- VSOMEIP_WARNING << "Receiving endpoint is not configured for service 0x"
- << std::hex << its_service;
+ instance_t its_instance = find_instance(its_service, _receiver);
+ return_code_e return_code = check_error(_data, _size, its_instance);
+ if (return_code != return_code_e::E_OK) {
+ if (return_code != return_code_e::E_NOT_OK) {
+ send_error(return_code, _data, _size, its_instance,
+ _receiver->is_reliable(), _receiver);
+ }
return;
}
- // TODO: move specific endpoint handling to to a method!
- auto found_service = remote_services_.find(its_service);
- if (found_service != remote_services_.end()) {
- auto found_instance = found_service->second.find(its_instance);
- if (found_instance != found_service->second.end()) {
- for (auto client_entry : found_instance->second) {
- client_t client = client_entry.first;
- if (!client) {
- continue;
- }
- auto found_reliability = client_entry.second.find(_receiver->is_reliable());
- if (found_reliability != client_entry.second.end()) {
- auto found_enpoint = found_reliability->second;
- if (found_enpoint.get() == _receiver) {
- auto local_endpoint = find_local(client);
- if (client != get_client()) {
- send_local(local_endpoint, client, _data, _size, its_instance, true, _receiver->is_reliable());
- } else {
- deliver_message(_data, _size, its_instance, _receiver->is_reliable());
- }
- return;
- }
- }
- }
- }
+ if (!deliver_specific_endpoint_message(
+ its_service, its_instance, _data, _size, _receiver)) {
+ // Common way of message handling
+ on_message(its_service, its_instance, _data, _size, _receiver->is_reliable());
}
- on_message(its_service, its_instance, _data, _size, _receiver->is_reliable());
}
}
}
@@ -535,6 +604,15 @@ void routing_manager_impl::on_message(
service_t _service, instance_t _instance,
const byte_t *_data, length_t _size,
bool _reliable) {
+#if 0
+ std::stringstream msg;
+ msg << "rmi::on_message("
+ << std::hex << std::setw(4) << std::setfill('0')
+ << _service << ", " << _instance << "): ";
+ for (uint32_t i = 0; i < _size; ++i)
+ msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
+#endif
method_t its_method;
client_t its_client;
session_t its_session;
@@ -552,10 +630,6 @@ void routing_manager_impl::on_message(
const_cast<byte_t *>(_data)[VSOMEIP_CLIENT_POS_MIN] = 0;
const_cast<byte_t *>(_data)[VSOMEIP_CLIENT_POS_MAX] = 0;
- its_method = VSOMEIP_BYTES_TO_WORD(
- _data[VSOMEIP_METHOD_POS_MIN],
- _data[VSOMEIP_METHOD_POS_MAX]);
-
auto it_subscriber = remote_subscriber_map_.find(its_client);
if (it_subscriber != remote_subscriber_map_.end()) {
send_to(it_subscriber->second, _data, _size);
@@ -574,11 +648,11 @@ void routing_manager_impl::on_message(
= find_event(_service, _instance, its_method);
if (its_event) {
uint32_t its_length = utility::get_payload_size(_data, _size);
- std::shared_ptr<payload> its_payload =
- runtime::get()->create_payload(
- &_data[VSOMEIP_PAYLOAD_POS],
- its_length);
- its_event->set_payload(its_payload);
+ std::shared_ptr<payload> its_payload =
+ runtime::get()->create_payload(
+ &_data[VSOMEIP_PAYLOAD_POS],
+ its_length);
+ its_event->set_payload(its_payload);
if (!utility::is_request_no_return(
_data[VSOMEIP_MESSAGE_TYPE_POS])) {
@@ -622,27 +696,59 @@ void routing_manager_impl::on_message(
_data[VSOMEIP_CLIENT_POS_MAX]);
}
- if ((its_client == VSOMEIP_ROUTING_CLIENT
- && utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS]))
- || its_client == host_->get_client()) {
+ if (its_client == VSOMEIP_ROUTING_CLIENT
+ && utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS])) {
+ deliver_notification(_service, _instance, _data, _size, _reliable);
+ } else if (its_client == host_->get_client()) {
deliver_message(_data, _size, _instance, _reliable);
} else {
send(its_client, _data, _size, _instance, true, _reliable);
}
}
+void routing_manager_impl::on_notification(client_t _client,
+ service_t _service, instance_t _instance,
+ const byte_t *_data, length_t _size) {
+ event_t its_event_id = VSOMEIP_BYTES_TO_WORD(
+ _data[VSOMEIP_METHOD_POS_MIN],
+ _data[VSOMEIP_METHOD_POS_MAX]);
+
+ std::shared_ptr<event> its_event = find_event(_service, _instance, its_event_id);
+ if (its_event) {
+ uint32_t its_length = utility::get_payload_size(_data, _size);
+ std::shared_ptr<payload> its_payload =
+ runtime::get()->create_payload(
+ &_data[VSOMEIP_PAYLOAD_POS],
+ its_length);
+
+ if (_client == VSOMEIP_ROUTING_CLIENT)
+ its_event->set_payload(its_payload);
+ else
+ its_event->set_payload(its_payload, _client);
+ }
+}
+
void routing_manager_impl::on_connect(std::shared_ptr<endpoint> _endpoint) {
+ // Is called when endpoint->connect succeded!
for (auto &its_service : remote_services_) {
for (auto &its_instance : its_service.second) {
- auto found_endpoint = its_instance.second.find(false);
- if (found_endpoint != its_instance.second.end()) {
- host_->on_availability(its_service.first, its_instance.first,
- true);
- } else {
- found_endpoint = its_instance.second.find(true);
- if (found_endpoint != its_instance.second.end()) {
- host_->on_availability(its_service.first,
- its_instance.first, true);
+ for (auto &its_client : its_instance.second) {
+ if (its_client.first == VSOMEIP_ROUTING_CLIENT ||
+ its_client.first == get_client()) {
+ auto found_endpoint = its_client.second.find(false);
+ if (found_endpoint != its_client.second.end()) {
+ if (found_endpoint->second.get() == _endpoint.get()) {
+ host_->on_availability(its_service.first, its_instance.first,
+ true);
+ }
+ }
+ found_endpoint = its_client.second.find(true);
+ if (found_endpoint != its_client.second.end()) {
+ if (found_endpoint->second.get() == _endpoint.get()) {
+ host_->on_availability(its_service.first,
+ its_instance.first, true);
+ }
+ }
}
}
}
@@ -650,17 +756,26 @@ void routing_manager_impl::on_connect(std::shared_ptr<endpoint> _endpoint) {
}
void routing_manager_impl::on_disconnect(std::shared_ptr<endpoint> _endpoint) {
+ // Is called when endpoint->connect fails!
for (auto &its_service : remote_services_) {
for (auto &its_instance : its_service.second) {
- auto found_endpoint = its_instance.second.find(false);
- if (found_endpoint != its_instance.second.end()) {
- host_->on_availability(its_service.first, its_instance.first,
- false);
- } else {
- found_endpoint = its_instance.second.find(true);
- if (found_endpoint != its_instance.second.end()) {
- host_->on_availability(its_service.first,
- its_instance.first, false);
+ for (auto &its_client : its_instance.second) {
+ if (its_client.first == VSOMEIP_ROUTING_CLIENT ||
+ its_client.first == get_client()) {
+ auto found_endpoint = its_client.second.find(false);
+ if (found_endpoint != its_client.second.end()) {
+ if (found_endpoint->second.get() == _endpoint.get()) {
+ host_->on_availability(its_service.first, its_instance.first,
+ false);
+ }
+ }
+ found_endpoint = its_client.second.find(true);
+ if (found_endpoint != its_client.second.end()) {
+ if (found_endpoint->second.get() == _endpoint.get()) {
+ host_->on_availability(its_service.first,
+ its_instance.first, false);
+ }
+ }
}
}
}
@@ -675,50 +790,147 @@ void routing_manager_impl::on_stop_offer_service(service_t _service,
for (auto &e : i.second)
e.second->unset_payload();
- host_->on_availability(_service, _instance, false);
+ /**
+ * Hold reliable & unreliable server-endpoints from service info
+ * because if "del_routing_info" is called those entries could be freed
+ * and we can't be sure this happens synchronous when SD is active.
+ * After triggering "del_routing_info" this endpoints gets cleanup up
+ * within this method if they not longer used by any other local service.
+ */
+ std::shared_ptr<endpoint> its_reliable_endpoint;
+ std::shared_ptr<endpoint> its_unreliable_endpoint;
+ std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance));
+ if (its_info) {
+ its_reliable_endpoint = its_info->get_endpoint(true);
+ its_unreliable_endpoint = its_info->get_endpoint(false);
+ }
+ // Trigger "del_routing_info" either over SD or static
if (discovery_) {
auto found_service = services_.find(_service);
if (found_service != services_.end()) {
auto found_instance = found_service->second.find(_instance);
if (found_instance != found_service->second.end()) {
found_instance->second->set_ttl(0);
- discovery_->on_offer_change(
- found_instance->second->get_group()->get_name());
+ discovery_->on_offer_change();
}
}
} else {
- // TODO: allow to withdraw a service on one endpoint only
- del_routing_info(_service, _instance, false);
- del_routing_info(_service, _instance, true);
+ del_routing_info(_service, _instance,
+ (its_reliable_endpoint != nullptr),
+ (its_unreliable_endpoint != nullptr));
+ }
+
+ // Cleanup reliable & unreliable server endpoints hold before
+ if (its_info) {
+ std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
+ std::shared_ptr<endpoint> its_empty_endpoint;
+ bool reliable = true;
+
+ // Loop over reliable/unreliable and cleanup if needed
+ for (uint8_t i = 0; i < 2; ++i) {
+ std::shared_ptr<endpoint> its_endpoint;
+ if (reliable) {
+ its_endpoint = its_reliable_endpoint;
+ } else {
+ its_endpoint = its_unreliable_endpoint;
+ }
+ if (!its_endpoint) {
+ reliable = !reliable;
+ continue;
+ }
+
+ // Check whether any service still uses this endpoint
+ its_endpoint->decrement_use_count();
+ bool isLastService = (its_endpoint->get_use_count() == 0);
+
+ // Clear service_instances_
+ if (1 >= service_instances_[_service].size()) {
+ service_instances_.erase(_service);
+ } else {
+ service_instances_[_service].erase(its_endpoint.get());
+ }
+
+ // Clear server endpoint if no service remains using it
+ if (isLastService) {
+ uint16_t port = its_endpoint->get_local_port();
+ if (server_endpoints_.find(port) != server_endpoints_.end()) {
+ server_endpoints_[port].erase(reliable);
+ if (server_endpoints_[port].find(!reliable) == server_endpoints_[port].end()) {
+ server_endpoints_.erase(port);
+ }
+ }
+
+ // Stop endpoint (close socket) to release its async_handlers!
+ its_endpoint->stop();
+ }
+
+ // Clear service info and service group
+ clear_service_info(_service, _instance, reliable);
+
+ // Invert reliable flag and loop again
+ reliable = !reliable;
+ }
}
}
bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size,
instance_t _instance, bool _reliable) {
- bool is_sent(false);
+ bool is_delivered(false);
deserializer_->set_data(_data, _size);
std::shared_ptr<message> its_message(deserializer_->deserialize_message());
if (its_message) {
its_message->set_instance(_instance);
its_message->set_reliable(_reliable);
host_->on_message(its_message);
- is_sent = true;
+ is_delivered = true;
} else {
- // TODO: send error "Malformed Message"
- //send_error();
+ VSOMEIP_ERROR << "Deserialization of vSomeIP message failed";
+ if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) {
+ send_error(return_code_e::E_MALFORMED_MESSAGE, _data,
+ _size, _instance, _reliable, nullptr);
+ }
}
- return (is_sent);
+ return is_delivered;
}
-const std::map<std::string, std::shared_ptr<servicegroup> > &
-routing_manager_impl::get_servicegroups() const {
- return (servicegroups_);
+bool routing_manager_impl::deliver_notification(
+ service_t _service, instance_t _instance,
+ const byte_t *_data, length_t _length,
+ bool _reliable) {
+ bool is_delivered(false);
+
+ method_t its_method = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_METHOD_POS_MIN],
+ _data[VSOMEIP_METHOD_POS_MAX]);
+
+ std::shared_ptr<event> its_event = find_event(_service, _instance, its_method);
+ if (its_event) {
+ std::vector< byte_t > its_data;
+
+ for (auto its_group : its_event->get_eventgroups()) {
+ auto its_local_clients = find_local_clients(_service, _instance, its_group);
+ for (auto its_local_client : its_local_clients) {
+ if (its_local_client == host_->get_client()) {
+ deliver_message(_data, _length, _instance, _reliable);
+ } else {
+ std::shared_ptr<endpoint> its_local_target = find_local(its_local_client);
+ if (its_local_target) {
+ send_local(its_local_target, VSOMEIP_ROUTING_CLIENT,
+ _data, _length, _instance, true, _reliable);
+ }
+ }
+ }
+ }
+ }
+
+ return is_delivered;
}
std::shared_ptr<eventgroupinfo> routing_manager_impl::find_eventgroup(
service_t _service, instance_t _instance,
eventgroup_t _eventgroup) const {
+ std::lock_guard<std::mutex> its_lock(eventgroups_mutex_);
+
std::shared_ptr<eventgroupinfo> its_info(nullptr);
auto found_service = eventgroups_.find(_service);
if (found_service != eventgroups_.end()) {
@@ -758,20 +970,33 @@ std::shared_ptr<eventgroupinfo> routing_manager_impl::find_eventgroup(
return (its_info);
}
+void routing_manager_impl::remove_eventgroup_info(service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup) {
+ std::lock_guard<std::mutex> its_lock(eventgroups_mutex_);
+ auto found_service = eventgroups_.find(_service);
+ if (found_service != eventgroups_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ found_instance->second.erase(_eventgroup);
+ }
+ }
+}
+
std::shared_ptr<configuration> routing_manager_impl::get_configuration() const {
return (host_->get_configuration());
}
-void routing_manager_impl::create_service_discovery_endpoint(
+std::shared_ptr<endpoint> routing_manager_impl::create_service_discovery_endpoint(
const std::string &_address, uint16_t _port, bool _reliable) {
std::shared_ptr<endpoint> its_service_endpoint = find_server_endpoint(_port,
_reliable);
if (!its_service_endpoint) {
- its_service_endpoint = create_server_endpoint(_port, _reliable);
+ its_service_endpoint = create_server_endpoint(_port, _reliable, true);
if (its_service_endpoint) {
std::shared_ptr<serviceinfo> its_info(
- std::make_shared<serviceinfo>(ANY_MAJOR, ANY_MINOR, ANY_TTL));
+ std::make_shared<serviceinfo>(ANY_MAJOR, ANY_MINOR, DEFAULT_TTL,
+ false)); // false, because we do _not_ want to announce it...
its_info->set_endpoint(its_service_endpoint, _reliable);
// routing info
@@ -780,35 +1005,33 @@ void routing_manager_impl::create_service_discovery_endpoint(
its_service_endpoint->add_multicast(VSOMEIP_SD_SERVICE,
VSOMEIP_SD_METHOD, _address, _port);
its_service_endpoint->join(_address);
- its_service_endpoint->start();
} else {
VSOMEIP_ERROR << "Service Discovery endpoint could not be created. "
"Please check your network configuration.";
}
}
+ return its_service_endpoint;
}
-services_t routing_manager_impl::get_offered_services(
- const std::string &_name) const {
+services_t routing_manager_impl::get_offered_services() const {
services_t its_offers;
- auto find_servicegroup = servicegroups_.find(_name);
- if (find_servicegroup != servicegroups_.end()) {
- if (find_servicegroup->second->is_local()) {
- return (find_servicegroup->second->get_services());
+ std::lock_guard<std::mutex> its_lock(services_mutex_);
+ for (auto s : services_) {
+ for (auto i : s.second) {
+ if (i.second->is_local()) {
+ its_offers[s.first][i.first] = i.second;
+ }
}
}
-
return (its_offers);
}
std::shared_ptr<endpoint> routing_manager_impl::find_or_create_remote_client(
service_t _service, instance_t _instance, bool _reliable, client_t _client) {
+ std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
std::shared_ptr<endpoint> its_endpoint = find_remote_client(_service, _instance,
_reliable, _client);
- // Create specific IP-client-endpoint for selective clients
- if (!its_endpoint &&
- specific_endpoint_clients.find(_client) != specific_endpoint_clients.end()) {
-
+ if (!its_endpoint) {
its_endpoint = create_remote_client(_service, _instance, _reliable, _client);
}
return its_endpoint;
@@ -820,6 +1043,7 @@ std::shared_ptr<endpoint> routing_manager_impl::find_or_create_remote_client(
std::shared_ptr<serviceinfo> routing_manager_impl::find_service(
service_t _service, instance_t _instance) const {
std::shared_ptr<serviceinfo> its_info;
+ std::lock_guard<std::mutex> its_lock(services_mutex_);
auto found_service = services_.find(_service);
if (found_service != services_.end()) {
auto found_instance = found_service->second.find(_instance);
@@ -830,19 +1054,20 @@ std::shared_ptr<serviceinfo> routing_manager_impl::find_service(
return (its_info);
}
-std::shared_ptr<serviceinfo> routing_manager_impl::create_service(
+std::shared_ptr<serviceinfo> routing_manager_impl::create_service_info(
service_t _service, instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl) {
-
+ minor_version_t _minor, ttl_t _ttl, bool _is_local_service) {
std::shared_ptr<serviceinfo> its_info;
if (configuration_) {
- its_info = std::make_shared<serviceinfo>(_major, _minor, _ttl);
+ its_info = std::make_shared<serviceinfo>(_major, _minor, _ttl, _is_local_service);
uint16_t its_reliable_port = configuration_->get_reliable_port(_service,
_instance);
uint16_t its_unreliable_port = configuration_->get_unreliable_port(
_service, _instance);
+ bool is_someip = configuration_->is_someip(_service, _instance);
+
its_info->set_multicast_address(
configuration_->get_multicast_address(_service, _instance));
its_info->set_multicast_port(
@@ -853,41 +1078,41 @@ std::shared_ptr<serviceinfo> routing_manager_impl::create_service(
std::shared_ptr<endpoint> its_reliable_endpoint;
std::shared_ptr<endpoint> its_unreliable_endpoint;
- if (ILLEGAL_PORT != its_reliable_port) {
- its_reliable_endpoint = find_or_create_server_endpoint(
- its_reliable_port,
- true);
- its_info->set_endpoint(its_reliable_endpoint, true);
-
- // TODO: put this in a method and check whether an assignment already exists!
- service_instances_[_service][its_reliable_endpoint.get()] =
- _instance;
- }
+ // Create server endpoints for local services only
+ if (_is_local_service) {
+ if (ILLEGAL_PORT != its_reliable_port) {
+ its_reliable_endpoint = find_or_create_server_endpoint(
+ its_reliable_port, true, is_someip);
+ if (its_reliable_endpoint) {
+ its_info->set_endpoint(its_reliable_endpoint, true);
+ its_reliable_endpoint->increment_use_count();
+ service_instances_[_service][its_reliable_endpoint.get()] =
+ _instance;
+ }
+ }
- if (ILLEGAL_PORT != its_unreliable_port) {
- its_unreliable_endpoint = find_or_create_server_endpoint(
- its_unreliable_port, false);
- its_info->set_endpoint(its_unreliable_endpoint, false);
+ if (ILLEGAL_PORT != its_unreliable_port) {
+ its_unreliable_endpoint = find_or_create_server_endpoint(
+ its_unreliable_port, false, is_someip);
+ if (its_unreliable_endpoint) {
+ its_info->set_endpoint(its_unreliable_endpoint, false);
+ its_unreliable_endpoint->increment_use_count();
+ service_instances_[_service][its_unreliable_endpoint.get()] =
+ _instance;
+ }
+ }
- service_instances_[_service][its_unreliable_endpoint.get()] =
- _instance;
+ if (ILLEGAL_PORT == its_reliable_port
+ && ILLEGAL_PORT == its_unreliable_port) {
+ VSOMEIP_DEBUG << "Port configuration missing for ["
+ << std::hex << _service << "." << _instance
+ << "]. Service is internal.";
+ }
}
- if (ILLEGAL_PORT != its_reliable_port
- || ILLEGAL_PORT != its_unreliable_port) {
- std::string its_servicegroup = configuration_->get_group(_service,
- _instance);
- auto found_servicegroup = servicegroups_.find(its_servicegroup);
- if (found_servicegroup == servicegroups_.end()) {
- servicegroups_[its_servicegroup] =
- std::make_shared<servicegroup>(its_servicegroup,
- configuration_->is_local_servicegroup(its_servicegroup));
- }
- servicegroups_[its_servicegroup]->add_service(_service, _instance,
- its_info);
+ {
+ std::lock_guard<std::mutex> its_lock(services_mutex_);
services_[_service][_instance] = its_info;
- } else {
- VSOMEIP_DEBUG << "Port configuration missing. Assuming internal service.";
}
} else {
host_->on_error(error_code_e::CONFIGURATION_MISSING);
@@ -898,13 +1123,17 @@ std::shared_ptr<serviceinfo> routing_manager_impl::create_service(
std::shared_ptr<endpoint> routing_manager_impl::create_client_endpoint(
const boost::asio::ip::address &_address, uint16_t _port,
- bool _reliable, client_t _client) {
+ bool _reliable, client_t _client, bool _start) {
+ (void)_client;
+
std::shared_ptr<endpoint> its_endpoint;
try {
if (_reliable) {
its_endpoint = std::make_shared<tcp_client_endpoint_impl>(
shared_from_this(),
- boost::asio::ip::tcp::endpoint(_address, _port), io_);
+ boost::asio::ip::tcp::endpoint(_address, _port), io_,
+ configuration_->get_message_size_reliable(
+ _address.to_string(), _port));
if (configuration_->has_enabled_magic_cookies(_address.to_string(),
_port)) {
@@ -915,9 +1144,8 @@ std::shared_ptr<endpoint> routing_manager_impl::create_client_endpoint(
shared_from_this(),
boost::asio::ip::udp::endpoint(_address, _port), io_);
}
-
- client_endpoints_[_address][_port][_client][_reliable] = its_endpoint;
- its_endpoint->start();
+ if (_start)
+ its_endpoint->start();
} catch (...) {
host_->on_error(error_code_e::CLIENT_ENDPOINT_CREATION_FAILED);
}
@@ -925,63 +1153,38 @@ std::shared_ptr<endpoint> routing_manager_impl::create_client_endpoint(
return (its_endpoint);
}
-std::shared_ptr<endpoint> routing_manager_impl::find_client_endpoint(
- const boost::asio::ip::address &_address, uint16_t _port,
- bool _reliable, client_t _client) {
- std::shared_ptr<endpoint> its_endpoint;
- auto found_address = client_endpoints_.find(_address);
- if (found_address != client_endpoints_.end()) {
- auto found_port = found_address->second.find(_port);
- if (found_port != found_address->second.end()) {
- auto found_client = found_port->second.find(_client);
- if (found_client != found_port->second.end()) {
- auto found_endpoint = found_client->second.find(_reliable);
- if (found_endpoint != found_client->second.end()) {
- its_endpoint = found_endpoint->second;
- }
- }
- }
- }
- return (its_endpoint);
-}
-
-std::shared_ptr<endpoint> routing_manager_impl::find_or_create_client_endpoint(
- const boost::asio::ip::address &_address, uint16_t _port,
- bool _reliable, client_t _client) {
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
- std::shared_ptr<endpoint> its_endpoint = find_client_endpoint(_address,
- _port, _reliable, _client);
- if (0 == its_endpoint) {
- its_endpoint = create_client_endpoint(_address, _port, _reliable, _client);
- }
- return (its_endpoint);
-}
-
std::shared_ptr<endpoint> routing_manager_impl::create_server_endpoint(
- uint16_t _port, bool _reliable) {
+ uint16_t _port, bool _reliable, bool _start) {
+ std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
std::shared_ptr<endpoint> its_endpoint;
-
try {
- boost::asio::ip::address its_unicast = configuration_->get_unicast();
- if (_reliable) {
- its_endpoint = std::make_shared<tcp_server_endpoint_impl>(
- shared_from_this(),
- boost::asio::ip::tcp::endpoint(its_unicast, _port), io_);
- if (configuration_->has_enabled_magic_cookies(
- its_unicast.to_string(), _port)) {
- its_endpoint->enable_magic_cookies();
- }
- } else {
- // TODO: this should be more specific.
- if (its_unicast.is_v4()) {
- its_unicast = boost::asio::ip::address_v4::any();
+ boost::asio::ip::address its_unicast = configuration_->get_unicast_address();
+ if (_start) {
+ if (_reliable) {
+ its_endpoint = std::make_shared<tcp_server_endpoint_impl>(
+ shared_from_this(),
+ boost::asio::ip::tcp::endpoint(its_unicast, _port), io_,
+ configuration_->get_message_size_reliable(
+ its_unicast.to_string(), _port));
+ if (configuration_->has_enabled_magic_cookies(
+ its_unicast.to_string(), _port)) {
+ its_endpoint->enable_magic_cookies();
+ }
} else {
- // TODO: how is "ANY" specified in IPv6?
+ if (its_unicast.is_v4()) {
+ its_unicast = boost::asio::ip::address_v4::any();
+ } else if (its_unicast.is_v6()) {
+ its_unicast = boost::asio::ip::address_v6::any();
+ }
+ boost::asio::ip::udp::endpoint ep(its_unicast, _port);
+ its_endpoint = std::make_shared<udp_server_endpoint_impl>(
+ shared_from_this(),
+ ep, io_);
}
- boost::asio::ip::udp::endpoint ep(its_unicast, _port);
- its_endpoint = std::make_shared<udp_server_endpoint_impl>(
- shared_from_this(),
- ep, io_);
+
+ } else {
+ its_endpoint = std::make_shared<virtual_server_endpoint_impl>(
+ its_unicast.to_string(), _port, _reliable);
}
if (its_endpoint) {
@@ -999,6 +1202,7 @@ std::shared_ptr<endpoint> routing_manager_impl::create_server_endpoint(
std::shared_ptr<endpoint> routing_manager_impl::find_server_endpoint(
uint16_t _port, bool _reliable) {
std::shared_ptr<endpoint> its_endpoint;
+ std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
auto found_port = server_endpoints_.find(_port);
if (found_port != server_endpoints_.end()) {
auto found_endpoint = found_port->second.find(_reliable);
@@ -1010,12 +1214,11 @@ std::shared_ptr<endpoint> routing_manager_impl::find_server_endpoint(
}
std::shared_ptr<endpoint> routing_manager_impl::find_or_create_server_endpoint(
- uint16_t _port, bool _reliable) {
- std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
+ uint16_t _port, bool _reliable, bool _start) {
std::shared_ptr<endpoint> its_endpoint = find_server_endpoint(_port,
_reliable);
if (0 == its_endpoint) {
- its_endpoint = create_server_endpoint(_port, _reliable);
+ its_endpoint = create_server_endpoint(_port, _reliable, _start);
}
return (its_endpoint);
}
@@ -1038,7 +1241,7 @@ std::shared_ptr<endpoint> routing_manager_impl::create_local(client_t _client) {
#ifdef WIN32
boost::asio::ip::address address = boost::asio::ip::address::from_string("127.0.0.1");
- int port = 51235 + _client;
+ int port = VSOMEIP_INTERNAL_BASE_PORT + _client;
#endif
std::shared_ptr<endpoint> its_endpoint = std::make_shared<
@@ -1048,7 +1251,7 @@ std::shared_ptr<endpoint> routing_manager_impl::create_local(client_t _client) {
#else
boost::asio::local::stream_protocol::endpoint(its_path.str())
#endif
- , io_);
+ , io_, configuration_->get_max_message_size_local());
local_clients_[_client] = its_endpoint;
its_endpoint->start();
return (its_endpoint);
@@ -1144,26 +1347,35 @@ instance_t routing_manager_impl::find_instance(service_t _service,
std::shared_ptr<endpoint> routing_manager_impl::create_remote_client(
service_t _service, instance_t _instance, bool _reliable, client_t _client) {
std::shared_ptr<endpoint> its_endpoint;
- auto found_service = remote_services_.find(_service);
- if (found_service != remote_services_.end()) {
+ std::shared_ptr<endpoint_definition> its_endpoint_def;
+ auto found_service = remote_service_info_.find(_service);
+ if (found_service != remote_service_info_.end()) {
auto found_instance = found_service->second.find(_instance);
if (found_instance != found_service->second.end()) {
- for (auto its_client : found_instance->second) {
- auto found_reliability = its_client.second.find(_reliable);
- if (found_reliability != its_client.second.end()) {
- std::shared_ptr<endpoint> endpoint = found_reliability->second;
- boost::asio::ip::address address;
- endpoint->get_remote_address(address);
- its_endpoint = find_or_create_client_endpoint(address,
- endpoint->get_remote_port(), _reliable, _client);
- break;
- }
+ auto found_reliability = found_instance->second.find(_reliable);
+ if (found_reliability != found_instance->second.end()) {
+ its_endpoint_def = found_reliability->second;
+ its_endpoint = create_client_endpoint(
+ its_endpoint_def->get_address(),
+ its_endpoint_def->get_port(), _reliable, _client,
+ configuration_->is_someip(_service, _instance)
+ );
}
}
}
if (its_endpoint) {
- remote_services_[_service][_instance][_client][_reliable] = its_endpoint;
service_instances_[_service][its_endpoint.get()] = _instance;
+ remote_services_[_service][_instance][_client][_reliable] = its_endpoint;
+ if (_client == VSOMEIP_ROUTING_CLIENT) {
+ client_endpoints_by_ip_[its_endpoint_def->get_address()]
+ [its_endpoint_def->get_port()]
+ [_reliable] = its_endpoint;
+ // Set the basic route to the service in the service info
+ auto found_service_info = find_service(_service, _instance);
+ if (found_service_info) {
+ found_service_info->set_endpoint(its_endpoint, _reliable);
+ }
+ }
}
return its_endpoint;
}
@@ -1185,6 +1397,41 @@ std::shared_ptr<endpoint> routing_manager_impl::find_remote_client(
}
}
}
+ if(its_endpoint || _client != VSOMEIP_ROUTING_CLIENT) {
+ return its_endpoint;
+ }
+
+ // If another service is hosted on the same server_endpoint
+ // reuse the existing client_endpoint.
+ auto found_service_info = remote_service_info_.find(_service);
+ if(found_service_info != remote_service_info_.end()) {
+ auto found_instance = found_service_info->second.find(_instance);
+ if(found_instance != found_service_info->second.end()) {
+ auto found_reliable = found_instance->second.find(_reliable);
+ if(found_reliable != found_instance->second.end()) {
+ std::shared_ptr<endpoint_definition> its_ep_def =
+ found_reliable->second;
+ auto found_address = client_endpoints_by_ip_.find(
+ its_ep_def->get_address());
+ if(found_address != client_endpoints_by_ip_.end()) {
+ auto found_port = found_address->second.find(
+ its_ep_def->get_remote_port());
+ if(found_port != found_address->second.end()) {
+ auto found_reliable2 = found_port->second.find(
+ _reliable);
+ if(found_reliable2 != found_port->second.end()) {
+ its_endpoint = found_reliable2->second;
+ // store the endpoint under this service/instance id
+ // as well - needed for later cleanup
+ remote_services_[_service][_instance][_client][_reliable] =
+ its_endpoint;
+ service_instances_[_service][its_endpoint.get()] = _instance;
+ }
+ }
+ }
+ }
+ }
+ }
return its_endpoint;
}
@@ -1220,190 +1467,203 @@ std::set<std::shared_ptr<event> > routing_manager_impl::find_events(
return (its_events);
}
-void routing_manager_impl::add_routing_info(service_t _service,
- instance_t _instance, major_version_t _major, minor_version_t _minor,
- ttl_t _ttl, const boost::asio::ip::address &_address, uint16_t _port,
- bool _reliable) {
- std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance));
- if (!its_info) {
- its_info = create_service(_service, _instance, _major, _minor, _ttl);
- services_[_service][_instance] = its_info;
- }
- // If host doesn't have a specific endpoint we create it here
- if (specific_endpoint_clients.find(get_client()) == specific_endpoint_clients.end()) {
- std::shared_ptr<endpoint> its_endpoint(
- find_or_create_client_endpoint(_address, _port, _reliable, VSOMEIP_ROUTING_CLIENT));
- its_info->set_endpoint(its_endpoint, _reliable);
+bool routing_manager_impl::is_field(service_t _service, instance_t _instance,
+ event_t _event) const {
+ auto find_service = events_.find(_service);
+ if (find_service != events_.end()) {
+ auto find_instance = find_service->second.find(_instance);
+ if (find_instance != find_service->second.end()) {
+ auto find_event = find_instance->second.find(_event);
+ if (find_event != find_instance->second.end())
+ return find_event->second->is_field();
+ }
+ }
+ return false;
+}
- remote_services_[_service][_instance][VSOMEIP_ROUTING_CLIENT][_reliable] = its_endpoint;
- service_instances_[_service][its_endpoint.get()] = _instance;
+void routing_manager_impl::add_routing_info(
+ service_t _service, instance_t _instance,
+ major_version_t _major, minor_version_t _minor, ttl_t _ttl,
+ const boost::asio::ip::address &_reliable_address,
+ uint16_t _reliable_port,
+ const boost::asio::ip::address &_unreliable_address,
+ uint16_t _unreliable_port) {
- if (its_endpoint->is_connected()) {
- host_->on_availability(_service, _instance, true);
+ // Create/Update service info
+ std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance));
+ if (!its_info) {
+ boost::asio::ip::address its_unicast_address
+ = configuration_->get_unicast_address();
+ bool is_local(false);
+ if (_reliable_port != ILLEGAL_PORT
+ && its_unicast_address == _reliable_address)
+ is_local = true;
+ else if (_unreliable_port != ILLEGAL_PORT
+ && its_unicast_address == _unreliable_address)
+ is_local = true;
+
+ its_info = create_service_info(_service, _instance, _major, _minor, _ttl, is_local);
+ {
+ std::lock_guard<std::mutex> its_lock(services_mutex_);
+ services_[_service][_instance] = its_info;
}
+ } else {
+ its_info->set_ttl(_ttl);
}
- // Create all specific endpoints for proxies probably like them
- for (client_t client : specific_endpoint_clients) {
- std::shared_ptr<endpoint> its_endpoint(
- find_or_create_client_endpoint(_address, _port, _reliable, client));
+ // Check whether remote services are unchanged
+ bool is_reliable_known(false);
+ bool is_unreliable_known(false);
- if (client == get_client()) {
- its_info->set_endpoint(its_endpoint, _reliable);
+ auto found_service = remote_service_info_.find(_service);
+ if (found_service != remote_service_info_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ std::shared_ptr<endpoint_definition> its_definition;
+ if (_reliable_port != ILLEGAL_PORT) {
+ auto found_reliable = found_instance->second.find(true);
+ if (found_reliable != found_instance->second.end()) {
+ its_definition = found_reliable->second;
+ if (its_definition->get_address() == _reliable_address
+ && its_definition->get_port() == _reliable_port) {
+ is_reliable_known = true;
+ }
+ } else {
+ VSOMEIP_WARNING << "Reliable service endpoint has changed!";
+ }
+ }
+ if (_unreliable_port != ILLEGAL_PORT) {
+ auto found_unreliable = found_instance->second.find(false);
+ if (found_unreliable != found_instance->second.end()) {
+ its_definition = found_unreliable->second;
+ if (its_definition->get_address() == _unreliable_address
+ && its_definition->get_port() == _unreliable_port) {
+ is_unreliable_known = true;
+ } else {
+ VSOMEIP_WARNING << "Unreliable service endpoint has changed!";
+ }
+ }
+ }
}
+ }
- remote_services_[_service][_instance][client][_reliable] = its_endpoint;
- service_instances_[_service][its_endpoint.get()] = _instance;
+ // Add endpoint(s) if necessary
+ bool is_added(false);
+ if (_reliable_port != ILLEGAL_PORT && !is_reliable_known) {
+ std::shared_ptr<endpoint_definition> endpoint_def
+ = endpoint_definition::get(_reliable_address, _reliable_port, true);
+ remote_service_info_[_service][_instance][true] = endpoint_def;
+ is_added = !is_unreliable_known;
+ }
- if (its_endpoint->is_connected()) {
- host_->on_availability(_service, _instance, true);
- }
+ if (_unreliable_port != ILLEGAL_PORT && !is_unreliable_known) {
+ std::shared_ptr<endpoint_definition> endpoint_def
+ = endpoint_definition::get(_unreliable_address, _unreliable_port, false);
+ remote_service_info_[_service][_instance][false] = endpoint_def;
+ is_added = !is_reliable_known;
}
- stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance);
+ if (is_added) {
+ host_->on_availability(_service, _instance, true);
+ stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance);
+ }
}
-void routing_manager_impl::del_routing_info(service_t _service,
- instance_t _instance,
- bool _reliable) {
- std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance));
- if (its_info) {
- std::shared_ptr<endpoint> its_empty_endpoint;
+void routing_manager_impl::del_routing_info(service_t _service, instance_t _instance,
+ bool _has_reliable, bool _has_unreliable) {
- // TODO: only tell the application if the service is completely gone
- host_->on_availability(_service, _instance, false);
- stub_->on_stop_offer_service(VSOMEIP_ROUTING_CLIENT, _service,
- _instance);
+ host_->on_availability(_service, _instance, false);
+ stub_->on_stop_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance);
- // Implicit unsubscribe
- auto found_service = eventgroups_.find(_service);
- if (found_service != eventgroups_.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- for (auto &its_eventgroup : found_instance->second) {
- its_eventgroup.second->clear_targets();
- }
+ // Implicit unsubscribe
+ auto found_service = eventgroups_.find(_service);
+ if (found_service != eventgroups_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ for (auto &its_eventgroup : found_instance->second) {
+ its_eventgroup.second->clear_targets();
}
}
+ }
- std::shared_ptr<endpoint> its_endpoint = its_info->get_endpoint(
- _reliable);
- if (its_endpoint) {
- if (1 >= service_instances_[_service].size()) {
- service_instances_.erase(_service);
- } else {
- service_instances_[_service].erase(its_endpoint.get());
- }
+ if (_has_reliable)
+ clear_client_endpoints(_service, _instance, true);
+ if (_has_unreliable)
+ clear_client_endpoints(_service, _instance, false);
- remote_services_[_service][_instance].erase(_reliable);
- auto found_endpoint = remote_services_[_service][_instance].find(
- !_reliable);
- if (found_endpoint == remote_services_[_service][_instance].end()) {
- remote_services_[_service].erase(_instance);
- }
- if (1 >= remote_services_[_service].size()) {
- remote_services_.erase(_service);
- }
- }
+ clear_multicast_endpoints(_service, _instance);
- if (!its_info->get_endpoint(!_reliable)) {
- if (its_info->get_group()) {
- its_info->get_group()->remove_service(_service, _instance);
- if (1 >= services_[_service].size()) {
- services_.erase(_service);
+ if (_has_reliable)
+ clear_service_info(_service, _instance, true);
+ if (_has_unreliable)
+ clear_service_info(_service, _instance, false);
+}
+
+ttl_t routing_manager_impl::update_routing_info(ttl_t _elapsed) {
+ ttl_t its_smallest_ttl(DEFAULT_TTL);
+ std::map<service_t,
+ std::map<instance_t,
+ std::pair<bool, bool> > > its_expired_offers;
+
+ for (auto &s : services_) {
+ for (auto &i : s.second) {
+ ttl_t its_ttl = i.second->get_ttl();
+ if (its_ttl < DEFAULT_TTL) { // do not touch "forever"
+ if (its_ttl < _elapsed || its_ttl == 0) {
+ i.second->set_ttl(0);
+ 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
+ };
} else {
- services_[_service].erase(_instance);
+ ttl_t its_new_ttl(its_ttl - _elapsed);
+ i.second->set_ttl(its_new_ttl);
+ if (its_smallest_ttl > its_new_ttl)
+ its_smallest_ttl = its_new_ttl;
}
}
- } else {
- its_info->set_endpoint(its_empty_endpoint, _reliable);
}
}
-}
-
-void routing_manager_impl::init_routing_info() {
- VSOMEIP_INFO<< "Service Discovery disabled. Using static routing information.";
- for (auto i : configuration_->get_remote_services()) {
- std::string its_address = configuration_->get_unicast(i.first, i.second);
- uint16_t its_reliable = configuration_->get_reliable_port(i.first,
- i.second);
- uint16_t its_unreliable = configuration_->get_unreliable_port(i.first,
- i.second);
-
- if (VSOMEIP_INVALID_PORT != its_reliable) {
- VSOMEIP_DEBUG << "Initializing route to service ["
- << std::hex << i.first << "." << i.second << "]";
- add_routing_info(i.first, i.second, DEFAULT_MAJOR, DEFAULT_MINOR,
- DEFAULT_TTL,
- boost::asio::ip::address::from_string(its_address),
- its_reliable, true);
- }
- if (VSOMEIP_INVALID_PORT != its_unreliable) {
- add_routing_info(i.first, i.second, DEFAULT_MAJOR, DEFAULT_MINOR,
- DEFAULT_TTL,
- boost::asio::ip::address::from_string(its_address),
- its_unreliable, false);
+ for (auto &s : its_expired_offers) {
+ for (auto &i : s.second) {
+ del_routing_info(s.first, i.first, i.second.first, i.second.second);
}
}
+
+ return its_smallest_ttl;
}
-void routing_manager_impl::init_event_routing_info() {
- // TODO: the following should be done before(!) initializing
- // the configuration object to allow the configuration to
- // directly write to the target structure!
- std::map<service_t, std::map<instance_t, std::set<event_t> > > its_events =
- configuration_->get_events();
- for (auto i : its_events) {
- for (auto j : i.second) {
- for (auto k : j.second) {
- std::shared_ptr<event> its_event(std::make_shared<event>(this));
- its_event->set_service(i.first);
- its_event->set_instance(j.first);
- its_event->set_event(k);
- configuration_->set_event(its_event); // sets is_field/is_reliable
- events_[i.first][j.first][k] = its_event;
+void routing_manager_impl::init_routing_info() {
+ VSOMEIP_INFO<< "Service Discovery disabled. Using static routing information.";
+ for (auto i : configuration_->get_remote_services()) {
+ boost::asio::ip::address its_address(
+ boost::asio::ip::address::from_string(
+ configuration_->get_unicast_address(i.first, i.second)));
+ uint16_t its_reliable_port
+ = configuration_->get_reliable_port(i.first, i.second);
+ uint16_t its_unreliable_port
+ = configuration_->get_unreliable_port(i.first, i.second);
+
+ if (its_reliable_port != ILLEGAL_PORT
+ || its_unreliable_port != ILLEGAL_PORT) {
+
+ add_routing_info(i.first, i.second,
+ DEFAULT_MAJOR, DEFAULT_MINOR, DEFAULT_TTL,
+ its_address, its_reliable_port,
+ its_address, its_unreliable_port);
+
+ if(its_reliable_port != ILLEGAL_PORT) {
+ find_or_create_remote_client(i.first, i.second, true, VSOMEIP_ROUTING_CLIENT);
}
- }
- }
-
- std::map<service_t,
- std::map<instance_t, std::map<eventgroup_t, std::set<event_t> > > > its_eventgroups =
- configuration_->get_eventgroups();
- for (auto i : its_eventgroups) {
- for (auto j : i.second) {
- for (auto k : j.second) {
- eventgroups_[i.first][j.first][k.first] = std::make_shared<
- eventgroupinfo>();
- for (auto l : k.second) {
- std::shared_ptr<event> its_event = find_event(i.first,
- j.first, l);
- if (its_event) {
- eventgroups_[i.first][j.first][k.first]->add_event(
- its_event);
- its_event->add_eventgroup(k.first);
- }
- }
+ if(its_unreliable_port != ILLEGAL_PORT) {
+ find_or_create_remote_client(i.first, i.second, false, VSOMEIP_ROUTING_CLIENT);
}
}
}
-
-#if 0
- for (auto i : eventgroups_) {
- for (auto j : i.second) {
- for (auto k : j.second) {
- VSOMEIP_DEBUG<< "Eventgroup [" << std::hex << std::setw(4)
- << std::setfill('0') << i.first << "." << j.first << "." << k.first
- << "]";
- for (auto l : k.second->get_events()) {
- VSOMEIP_DEBUG << " Event " << std::hex << std::setw(4)
- << std::setfill('0') << l->get_event();
- }
- }
- }
- }
-#endif
}
void routing_manager_impl::on_subscribe(
@@ -1413,42 +1673,47 @@ void routing_manager_impl::on_subscribe(
std::shared_ptr<eventgroupinfo> its_eventgroup
= find_eventgroup(_service, _instance, _eventgroup);
if (its_eventgroup) {
- std::shared_ptr < eventgroupinfo > its_info = find_eventgroup(
- _service, _instance, _eventgroup);
-
client_t client = 0;
- if (!its_info->is_multicast()) {
+ if (!its_eventgroup->is_multicast()) {
if (!_target->is_reliable()) {
uint16_t unreliable_port = configuration_->get_unreliable_port(_service, _instance);
- auto endpoint = find_or_create_server_endpoint(unreliable_port, false);
- client = std::dynamic_pointer_cast<udp_server_endpoint_impl>(endpoint)->get_client(_target);
_target->set_remote_port(unreliable_port);
+ auto endpoint = find_server_endpoint(unreliable_port, false);
+ if (endpoint) {
+ client = std::dynamic_pointer_cast<udp_server_endpoint_impl>(endpoint)->
+ get_client(_target);
+ }
}
else {
uint16_t reliable_port = configuration_->get_reliable_port(_service, _instance);
- auto endpoint = find_or_create_server_endpoint(reliable_port, true);
- client = std::dynamic_pointer_cast<tcp_server_endpoint_impl>(endpoint)->get_client(_target);
+ auto endpoint = find_server_endpoint(reliable_port, true);
_target->set_remote_port(reliable_port);
+ if (endpoint) {
+ client = std::dynamic_pointer_cast<tcp_server_endpoint_impl>(endpoint)->
+ get_client(_target);
+ }
}
}
if(!host_->on_subscription(_service, _instance, _eventgroup, client, true)) {
VSOMEIP_INFO << "Subscription request for eventgroup " << _eventgroup
- << " rejected from application handler";
+ << " rejected from application handler";
return;
}
VSOMEIP_DEBUG << "on_subscribe: target=" << _target->get_address().to_string()
- << ":" <<_target->get_port() << ":Client=" << std::hex << client;
+ << ":" << std::dec <<_target->get_port() << ":Client=" << std::hex
+ << client << (_target->is_reliable() ? " reliable" : " unreliable");
- send_subscribe(client, _service, _instance, _eventgroup, 0, 0);
+ send_subscribe(client, _service, _instance, _eventgroup, its_eventgroup->get_major());
remote_subscriber_map_[client] = _target;
- its_eventgroup->add_target(_target); // unicast or multicast
- for (auto its_event : its_eventgroup->get_events()) {
- if (its_event->is_field()) {
- its_event->notify_one(_subscriber); // unicast
+ if (its_eventgroup->add_target(_target)) { // unicast or multicast
+ for (auto its_event : its_eventgroup->get_events()) {
+ if (its_event->is_field()) {
+ its_event->notify_one(_subscriber); // unicast
+ }
}
}
} else {
@@ -1462,28 +1727,30 @@ void routing_manager_impl::on_unsubscribe(service_t _service,
std::shared_ptr<eventgroupinfo> its_eventgroup = find_eventgroup(_service,
_instance, _eventgroup);
if (its_eventgroup) {
- std::shared_ptr < eventgroupinfo > its_info = find_eventgroup(
- _service, _instance, _eventgroup);
-
client_t client = 0;
- if (!its_info->is_multicast()) {
+ if (!its_eventgroup->is_multicast()) {
if (!_target->is_reliable()) {
- uint16_t unreliable_port = _target->get_remote_port();
- auto endpoint = find_or_create_server_endpoint(unreliable_port, false);
- client = std::dynamic_pointer_cast<udp_server_endpoint_impl>(endpoint)->
- get_client(_target);
+ uint16_t unreliable_port = configuration_->get_unreliable_port(_service, _instance);
+ auto endpoint = find_server_endpoint(unreliable_port, false);
+ if (endpoint) {
+ client = std::dynamic_pointer_cast<udp_server_endpoint_impl>(endpoint)->
+ get_client(_target);
+ }
} else {
- uint16_t reliable_port = _target->get_remote_port();
- auto endpoint = find_or_create_server_endpoint(reliable_port, true);
- client = std::dynamic_pointer_cast<tcp_server_endpoint_impl>(endpoint)->
- get_client(_target);
+ uint16_t reliable_port = configuration_->get_reliable_port(_service, _instance);
+ auto endpoint = find_server_endpoint(reliable_port, true);
+ if (endpoint) {
+ client = std::dynamic_pointer_cast<tcp_server_endpoint_impl>(endpoint)->
+ get_client(_target);
+ }
}
}
VSOMEIP_DEBUG << "on_unsubscribe: target=" << _target->get_address().to_string()
- << ":" <<_target->get_port() << ":Client=" << std::hex << client;
+ << ":" << std::dec <<_target->get_port() << ":Client=" << std::hex
+ << client << (_target->is_reliable() ? " reliable" : " unreliable");;
- its_eventgroup->del_target(_target);
+ its_eventgroup->remove_target(_target);
if (remote_subscriber_map_.find(client) != remote_subscriber_map_.end()) {
remote_subscriber_map_.erase(client);
@@ -1498,11 +1765,31 @@ void routing_manager_impl::on_unsubscribe(service_t _service,
void routing_manager_impl::on_subscribe_ack(service_t _service,
instance_t _instance, const boost::asio::ip::address &_address,
uint16_t _port) {
- // TODO: find a way of getting rid of the following endpoint in
- // case it is used for multicast exclusively and the subscription
- // is withdrawn or the service got lost
- std::shared_ptr<endpoint> its_endpoint = find_or_create_server_endpoint(
- _port, false);
+
+ if (multicast_info.find(_service) != multicast_info.end()) {
+ if (multicast_info[_service].find(_instance) != multicast_info[_service].end()) {
+ auto endpoint_def = multicast_info[_service][_instance];
+ if (endpoint_def->get_address() == _address &&
+ endpoint_def->get_port() == _port) {
+
+ // Multicast info and endpoint already created before
+ // This can happen when more than one client subscribe on the same instance!
+ return;
+ }
+ }
+ }
+
+ // Save multicast info to be able to delete the endpoint
+ // as soon as the instance stops offering its service
+ std::shared_ptr<endpoint_definition> endpoint_def =
+ endpoint_definition::get(_address, _port, false);
+ multicast_info[_service][_instance] = endpoint_def;
+
+ bool is_someip = configuration_->is_someip(_service, _instance);
+
+ // Create multicast endpoint & join multicase group
+ std::shared_ptr<endpoint> its_endpoint
+ = find_or_create_server_endpoint(_port, false, is_someip);
if (its_endpoint) {
service_instances_[_service][its_endpoint.get()] = _instance;
its_endpoint->join(_address.to_string());
@@ -1513,7 +1800,7 @@ void routing_manager_impl::on_subscribe_ack(service_t _service,
void routing_manager_impl::send_subscribe(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup,
- major_version_t _major, ttl_t _ttl) {
+ major_version_t _major) {
byte_t its_command[VSOMEIP_SUBSCRIBE_COMMAND_SIZE];
uint32_t its_size = VSOMEIP_SUBSCRIBE_COMMAND_SIZE
@@ -1531,8 +1818,6 @@ void routing_manager_impl::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], &_ttl,
- sizeof(_ttl));
std::shared_ptr<vsomeip::endpoint> target = find_local(_service, _instance);
if (target) {
@@ -1565,5 +1850,326 @@ void routing_manager_impl::send_unsubscribe(client_t _client, service_t _service
}
}
+bool routing_manager_impl::insert_subscription(
+ service_t _service, instance_t _instance, eventgroup_t _eventgroup,
+ client_t _client) {
+
+ auto found_service = eventgroup_clients_.find(_service);
+ if (found_service != eventgroup_clients_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ auto found_eventgroup = found_instance->second.find(_eventgroup);
+ if (found_eventgroup != found_instance->second.end()) {
+ if (found_eventgroup->second.find(_client)
+ != found_eventgroup->second.end())
+ return false;
+ }
+ }
+ }
+
+ eventgroup_clients_[_service][_instance][_eventgroup].insert(_client);
+ return true;
+}
+
+
+bool routing_manager_impl::deliver_specific_endpoint_message(service_t _service,
+ instance_t _instance, const byte_t *_data, length_t _size, endpoint *_receiver) {
+ // Try to deliver specific endpoint message (for selective subscribers)
+ auto found_servic = remote_services_.find(_service);
+ if (found_servic != remote_services_.end()) {
+ auto found_instance = found_servic->second.find(_instance);
+ if (found_instance != found_servic->second.end()) {
+ for (auto client_entry : found_instance->second) {
+ client_t client = client_entry.first;
+ if (!client) {
+ continue;
+ }
+ auto found_reliability = client_entry.second.find(_receiver->is_reliable());
+ if (found_reliability != client_entry.second.end()) {
+ auto found_enpoint = found_reliability->second;
+ if (found_enpoint.get() == _receiver) {
+ auto local_endpoint = find_local(client);
+ if (client != get_client()) {
+ send_local(local_endpoint, client, _data, _size, _instance, true, _receiver->is_reliable());
+ } else {
+ deliver_message(_data, _size, _instance, _receiver->is_reliable());
+ }
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+void routing_manager_impl::clear_client_endpoints(service_t _service, instance_t _instance,
+ bool _reliable) {
+ std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
+ std::shared_ptr<endpoint> deleted_endpoint;
+ // Clear client endpoints for remote services (generic and specific ones)
+ if (remote_services_.find(_service) != remote_services_.end()) {
+ if (remote_services_[_service].find(_instance) != remote_services_[_service].end()) {
+ auto endpoint = remote_services_[_service][_instance][VSOMEIP_ROUTING_CLIENT][_reliable];
+ if (endpoint) {
+ service_instances_[_service].erase(endpoint.get());
+ deleted_endpoint = endpoint;
+ }
+ remote_services_[_service][_instance][VSOMEIP_ROUTING_CLIENT].erase(_reliable);
+ auto found_endpoint = remote_services_[_service][_instance][VSOMEIP_ROUTING_CLIENT].find(
+ !_reliable);
+ if (found_endpoint == remote_services_[_service][_instance][VSOMEIP_ROUTING_CLIENT].end()) {
+ remote_services_[_service][_instance].erase(VSOMEIP_ROUTING_CLIENT);
+ }
+ }
+ }
+ for (client_t client : specific_endpoint_clients) {
+ if (remote_services_.find(_service) != remote_services_.end()) {
+ if (remote_services_[_service].find(_instance) != remote_services_[_service].end()) {
+ auto endpoint = remote_services_[_service][_instance][client][_reliable];
+ if (endpoint) {
+ service_instances_[_service].erase(endpoint.get());
+ endpoint->stop();
+ }
+ remote_services_[_service][_instance][client].erase(_reliable);
+ auto found_endpoint = remote_services_[_service][_instance][client].find(!_reliable);
+ if (found_endpoint == remote_services_[_service][_instance][client].end()) {
+ remote_services_[_service][_instance].erase(client);
+ }
+ }
+ }
+ }
+ if (remote_services_.find(_service) != remote_services_.end()) {
+ if (remote_services_[_service].find(_instance) != remote_services_[_service].end()) {
+ if (!remote_services_[_service][_instance].size()) {
+ remote_services_[_service].erase(_instance);
+ if (0 >= remote_services_[_service].size()) {
+ remote_services_.erase(_service);
+ }
+ }
+ }
+ }
+ // Clear remote_service_info_
+ if (remote_service_info_.find(_service) != remote_service_info_.end()) {
+ if (remote_service_info_[_service].find(_instance) != remote_service_info_[_service].end()) {
+ remote_service_info_[_service][_instance].erase(_reliable);
+ auto found_endpoint_def = remote_service_info_[_service][_instance].find(!_reliable);
+ if (found_endpoint_def == remote_service_info_[_service][_instance].end()) {
+ remote_service_info_[_service].erase(_instance);
+ if (0 >= remote_service_info_[_service].size()) {
+ remote_service_info_.erase(_service);
+ }
+ }
+ }
+ }
+
+ if (1 >= service_instances_[_service].size()) {
+ service_instances_.erase(_service);
+ }
+ if(deleted_endpoint) {
+ stop_and_delete_client_endpoint(deleted_endpoint);
+ }
+}
+
+void routing_manager_impl::stop_and_delete_client_endpoint(
+ std::shared_ptr<endpoint> _endpoint) {
+ // Only stop and delete the endpoint if none of the services
+ // reachable through it is online anymore.
+ bool delete_endpoint(true);
+
+ for (const auto& service : remote_services_) {
+ for (const auto& instance : service.second) {
+ const auto& client = instance.second.find(VSOMEIP_ROUTING_CLIENT);
+ if(client != instance.second.end()) {
+ for (const auto& reliable : client->second) {
+ if(reliable.second == _endpoint) {
+ delete_endpoint = false;
+ break;
+ }
+ }
+ }
+ if(!delete_endpoint) { break; }
+ }
+ if(!delete_endpoint) { break; }
+ }
+
+ if(delete_endpoint) {
+ _endpoint->stop();
+ for (auto address = client_endpoints_by_ip_.begin();
+ address != client_endpoints_by_ip_.end();) {
+ for (auto port = address->second.begin();
+ port != address->second.end();) {
+ for (auto reliable = port->second.begin();
+ reliable != port->second.end();) {
+ std::shared_ptr<endpoint> its_endpoint = reliable->second;
+ if (_endpoint == its_endpoint) {
+ reliable = port->second.erase(reliable);
+ } else {
+ ++reliable;
+ }
+ }
+ if (!port->second.size()) {
+ port = address->second.erase(port);
+ } else {
+ ++port;
+ }
+ }
+ if(!address->second.size()) {
+ address = client_endpoints_by_ip_.erase(address);
+ } else {
+ ++address;
+ }
+ }
+ }
+}
+
+void routing_manager_impl::clear_multicast_endpoints(service_t _service, instance_t _instance) {
+ std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_);
+ // Clear multicast info and endpoint and multicast instance (remote service)
+ if (multicast_info.find(_service) != multicast_info.end()) {
+ if (multicast_info[_service].find(_instance) != multicast_info[_service].end()) {
+ std::string address = multicast_info[_service][_instance]->get_address().to_string();
+ uint16_t port = multicast_info[_service][_instance]->get_port();
+ auto multicast_endpoint = server_endpoints_[port][false];
+ multicast_endpoint->leave(address);
+ multicast_endpoint->stop();
+ server_endpoints_[port].erase(false);
+ if (server_endpoints_[port].find(true) == server_endpoints_[port].end()) {
+ server_endpoints_.erase(port);
+ }
+ multicast_info[_service].erase(_instance);
+ if (0 >= multicast_info[_service].size()) {
+ multicast_info.erase(_service);
+ }
+ // Clear service_instances_ for multicase endpoint
+ if (1 >= service_instances_[_service].size()) {
+ service_instances_.erase(_service);
+ } else {
+ service_instances_[_service].erase(multicast_endpoint.get());
+ }
+ }
+ }
+}
+
+void routing_manager_impl::clear_service_info(service_t _service, instance_t _instance,
+ bool _reliable) {
+ std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance));
+ if (!its_info) {
+ return;
+ }
+ // Clear service_info and service_group
+ std::shared_ptr<endpoint> its_empty_endpoint;
+ if (!its_info->get_endpoint(!_reliable)) {
+ if (1 >= services_[_service].size()) {
+ services_.erase(_service);
+ } else {
+ services_[_service].erase(_instance);
+ }
+ } else {
+ its_info->set_endpoint(its_empty_endpoint, _reliable);
+ }
+}
+
+return_code_e routing_manager_impl::check_error(const byte_t *_data, length_t _size,
+ instance_t _instance) {
+
+ service_t its_service = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_SERVICE_POS_MIN],
+ _data[VSOMEIP_SERVICE_POS_MAX]);
+
+ if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) {
+ if (_size >= VSOMEIP_PAYLOAD_POS) {
+ if (_data[VSOMEIP_PROTOCOL_VERSION_POS] != VSOMEIP_PROTOCOL_VERSION) {
+ VSOMEIP_WARNING << "Received a message with unsupported protocol version for service 0x"
+ << std::hex << its_service;
+ return return_code_e::E_WRONG_PROTOCOL_VERSION;
+ }
+ if (_instance == 0xFFFF) {
+ VSOMEIP_WARNING << "Receiving endpoint is not configured for service 0x"
+ << 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;
+ }
+ 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!
+ return return_code_e::E_NOT_OK;
+ }
+ } else {
+ // Message shorter than vSomeIP message header
+ return return_code_e::E_MALFORMED_MESSAGE;
+ }
+ }
+ return return_code_e::E_OK;
+}
+
+void routing_manager_impl::send_error(return_code_e _return_code,
+ const byte_t *_data, length_t _size,
+ instance_t _instance, bool _reliable,
+ endpoint *_receiver) {
+
+ client_t its_client = 0;
+ service_t its_service = 0;
+ method_t its_method = 0;
+ session_t its_session = 0;
+
+ if (_size >= VSOMEIP_CLIENT_POS_MAX) {
+ its_client = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_CLIENT_POS_MIN],
+ _data[VSOMEIP_CLIENT_POS_MAX]);
+ }
+ if (_size >= VSOMEIP_SERVICE_POS_MAX) {
+ its_service = VSOMEIP_BYTES_TO_WORD(
+ _data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]);
+ }
+ if (_size >= VSOMEIP_METHOD_POS_MAX) {
+ its_method = VSOMEIP_BYTES_TO_WORD(
+ _data[VSOMEIP_METHOD_POS_MIN], _data[VSOMEIP_METHOD_POS_MAX]);
+ }
+ if (_size >= VSOMEIP_SESSION_POS_MAX) {
+ its_session = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_SESSION_POS_MIN],
+ _data[VSOMEIP_SESSION_POS_MAX]);
+ }
+
+ auto error_message = runtime::get()->create_message(_reliable);
+ error_message->set_client(its_client);
+ error_message->set_instance(_instance);
+ error_message->set_interface_version(0);
+ error_message->set_message_type(message_type_e::MT_ERROR);
+ error_message->set_method(its_method);
+ error_message->set_return_code(_return_code);
+ error_message->set_service(its_service);
+ error_message->set_session(its_session);
+
+ std::lock_guard<std::mutex> its_lock(serialize_mutex_);
+ if (serializer_->serialize(error_message.get())) {
+ if (_receiver) {
+ boost::asio::ip::address adr;
+ uint16_t port;
+ if (_receiver->is_reliable()) {
+ auto remote = static_cast<tcp_server_endpoint_impl*>(_receiver)->get_remote();
+ adr = remote.address();
+ port = remote.port();
+ } else {
+ auto remote = static_cast<udp_server_endpoint_impl*>(_receiver)->get_remote();
+ adr = remote.address();
+ port = remote.port();
+ }
+ auto its_endpoint_def =
+ std::make_shared<endpoint_definition>(adr, port, _receiver->is_reliable());
+ its_endpoint_def->set_remote_port(_receiver->get_local_port());
+ send_to(its_endpoint_def, serializer_->get_data(), serializer_->get_size());
+ } else {
+ send(get_client(), serializer_->get_data(), serializer_->get_size(),
+ _instance, true, _reliable);
+ }
+ serializer_->reset();
+ } else {
+ VSOMEIP_ERROR << "Failed to serialize error message.";
+ }
+}
+
}
// namespace vsomeip
diff --git a/implementation/routing/src/routing_manager_proxy.cpp b/implementation/routing/src/routing_manager_proxy.cpp
index 1df8b90..cbf14ff 100644
--- a/implementation/routing/src/routing_manager_proxy.cpp
+++ b/implementation/routing/src/routing_manager_proxy.cpp
@@ -6,17 +6,17 @@
#include <iomanip>
#include <mutex>
-#include <vsomeip/configuration.hpp>
#include <vsomeip/constants.hpp>
-#include <vsomeip/logger.hpp>
#include <vsomeip/runtime.hpp>
#include "../include/event.hpp"
#include "../include/routing_manager_host.hpp"
#include "../include/routing_manager_proxy.hpp"
+#include "../../configuration/include/configuration.hpp"
#include "../../configuration/include/internal.hpp"
#include "../../endpoints/include/local_client_endpoint_impl.hpp"
#include "../../endpoints/include/local_server_endpoint_impl.hpp"
+#include "../../logging/include/logger.hpp"
#include "../../message/include/deserializer.hpp"
#include "../../message/include/serializer.hpp"
#include "../../service_discovery/include/runtime.hpp"
@@ -26,10 +26,17 @@
namespace vsomeip {
routing_manager_proxy::routing_manager_proxy(routing_manager_host *_host) :
- io_(_host->get_io()), host_(_host), client_(_host->get_client()), sender_(
- 0), receiver_(0), serializer_(std::make_shared<serializer>()), deserializer_(
- std::make_shared<deserializer>()), is_connected_(false), is_started_(false),
- state_(event_type_e::ET_DEREGISTERED) {
+ io_(_host->get_io()),
+ is_connected_(false),
+ is_started_(false),
+ state_(state_type_e::ST_DEREGISTERED),
+ host_(_host),
+ client_(_host->get_client()),
+ configuration_(host_->get_configuration()),
+ serializer_(std::make_shared<serializer>()),
+ deserializer_(std::make_shared<deserializer>()),
+ sender_(0),
+ receiver_(0) {
}
routing_manager_proxy::~routing_manager_proxy() {
@@ -44,13 +51,7 @@ client_t routing_manager_proxy::get_client() const {
}
void routing_manager_proxy::init() {
- uint32_t its_max_message_size = VSOMEIP_MAX_LOCAL_MESSAGE_SIZE;
- if (VSOMEIP_MAX_TCP_MESSAGE_SIZE > its_max_message_size)
- its_max_message_size = VSOMEIP_MAX_TCP_MESSAGE_SIZE;
- if (VSOMEIP_MAX_UDP_MESSAGE_SIZE > its_max_message_size)
- its_max_message_size = VSOMEIP_MAX_UDP_MESSAGE_SIZE;
-
- serializer_->create_data(its_max_message_size);
+ serializer_->create_data(configuration_->get_max_message_size_local());
std::stringstream its_sender_path;
sender_ = create_local(VSOMEIP_ROUTING_CLIENT);
@@ -59,7 +60,7 @@ void routing_manager_proxy::init() {
its_client << VSOMEIP_BASE_PATH << std::hex << client_;
#ifdef WIN32
::_unlink(its_client.str().c_str());
- int port = 51235 + client_;
+ int port = VSOMEIP_INTERNAL_BASE_PORT + client_;
#else
::unlink(its_client.str().c_str());
#endif
@@ -69,7 +70,7 @@ void routing_manager_proxy::init() {
#else
boost::asio::local::stream_protocol::endpoint(its_client.str()),
#endif
- io_);
+ io_, configuration_->get_max_message_size_local());
#ifdef WIN32
VSOMEIP_DEBUG << "Listening at " << port;
@@ -110,13 +111,12 @@ 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,
- ttl_t _ttl) {
+ instance_t _instance, major_version_t _major, minor_version_t _minor) {
if (is_connected_) {
- send_offer_service(_client, _service, _instance, _major, _minor, _ttl);
+ send_offer_service(_client, _service, _instance, _major, _minor);
} else {
- service_data_t offer = { _service, _instance, _major, _minor, _ttl };
+ service_data_t offer = { _service, _instance, _major, _minor, false };
std::lock_guard<std::mutex> its_lock(pending_mutex_);
pending_offers_.insert(offer);
}
@@ -124,7 +124,8 @@ void routing_manager_proxy::offer_service(client_t _client, service_t _service,
void routing_manager_proxy::send_offer_service(client_t _client,
service_t _service, instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl) {
+ minor_version_t _minor) {
+ (void)_client;
byte_t its_command[VSOMEIP_OFFER_SERVICE_COMMAND_SIZE];
uint32_t its_size = VSOMEIP_OFFER_SERVICE_COMMAND_SIZE
@@ -142,14 +143,13 @@ void routing_manager_proxy::send_offer_service(client_t _client,
its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4] = _major;
std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 5], &_minor,
sizeof(_minor));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 9], &_ttl,
- sizeof(_ttl));
sender_->send(its_command, sizeof(its_command));
}
void routing_manager_proxy::stop_offer_service(client_t _client,
service_t _service, instance_t _instance) {
+ (void)_client;
if (is_connected_) {
byte_t its_command[VSOMEIP_STOP_OFFER_SERVICE_COMMAND_SIZE];
@@ -184,31 +184,109 @@ void routing_manager_proxy::stop_offer_service(client_t _client,
void routing_manager_proxy::request_service(client_t _client,
service_t _service, instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl, bool _has_selective) {
-
- is_selective_ = _has_selective;
- send_request_service(_client, _service, _instance, _major, _minor, _ttl, _has_selective);
+ minor_version_t _minor, bool _use_exclusive_proxy) {
+ send_request_service(_client, _service, _instance, _major, _minor,
+ _use_exclusive_proxy);
}
void routing_manager_proxy::release_service(client_t _client,
service_t _service, instance_t _instance) {
+ (void)_client;
+ (void)_service;
+ (void)_instance;
+}
+
+void routing_manager_proxy::register_event(client_t _client,
+ service_t _service, instance_t _instance,
+ event_t _event, std::set<eventgroup_t> _eventgroups,
+ bool _is_field, bool _is_provided) {
+ (void)_client;
+
+ if (_is_field)
+ fields_[_service][_instance].insert(_event);
+
+ send_register_event(client_, _service, _instance,
+ _event, _eventgroups, _is_field, _is_provided);
+}
+
+void routing_manager_proxy::unregister_event(client_t _client,
+ service_t _service, instance_t _instance, event_t _event,
+ bool _is_provided) {
+ (void)_client;
+ auto find_service = fields_.find(_service);
+ if (find_service != fields_.end()) {
+ auto find_instance = find_service->second.find(_instance);
+ if (find_instance != find_service->second.end()) {
+ find_instance->second.erase(_event);
+ if (find_instance->second.size() == 0)
+ find_service->second.erase(find_instance);
+ }
+ if (find_service->second.size() == 0)
+ fields_.erase(find_service);
+ }
+
+ if (is_connected_) {
+ byte_t its_command[VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE];
+ uint32_t its_size = VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE
+ - VSOMEIP_COMMAND_HEADER_SIZE;
+
+ its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_UNREGISTER_EVENT;
+ std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
+ sizeof(client_));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
+ sizeof(its_size));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
+ sizeof(_service));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
+ sizeof(_instance));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_event,
+ sizeof(_event));
+ its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 5]
+ = static_cast<byte_t>(_is_provided);
+
+ sender_->send(its_command, sizeof(its_command));
+ } else {
+ std::lock_guard<std::mutex> its_lock(pending_mutex_);
+ auto it = pending_event_registrations_.begin();
+ while (it != pending_event_registrations_.end()) {
+ if (it->service_ == _service
+ && it->instance_ == _instance
+ && it->event_ == _event) {
+ break;
+ }
+ it++;
+ }
+
+ if (it != pending_event_registrations_.end())
+ pending_event_registrations_.erase(it);
+ }
+}
+bool routing_manager_proxy::is_field(service_t _service, instance_t _instance,
+ event_t _event) const {
+ auto find_service = fields_.find(_service);
+ if (find_service != fields_.end()) {
+ auto find_instance = find_service->second.find(_instance);
+ if (find_instance != find_service->second.end())
+ return (find_instance->second.find(_event) != find_instance->second.end());
+ }
+ return false;
}
void routing_manager_proxy::subscribe(client_t _client, service_t _service,
- instance_t _instance, eventgroup_t _eventgroup, major_version_t _major,
- ttl_t _ttl) {
+ instance_t _instance, eventgroup_t _eventgroup, major_version_t _major) {
if (is_connected_) {
- send_subscribe(_client, _service, _instance, _eventgroup, _major, _ttl);
+ send_subscribe(_client, _service, _instance, _eventgroup, _major);
} else {
- eventgroup_data_t subscription = { _service, _instance, _eventgroup, _major, _ttl };
+ eventgroup_data_t subscription = { _service, _instance, _eventgroup, _major };
std::lock_guard<std::mutex> its_lock(pending_mutex_);
pending_subscriptions_.insert(subscription);
}
}
void routing_manager_proxy::send_subscribe(client_t _client, service_t _service,
- instance_t _instance, eventgroup_t _eventgroup, major_version_t _major,
- ttl_t _ttl) {
+ instance_t _instance, eventgroup_t _eventgroup, major_version_t _major) {
+ (void)_client;
+
byte_t its_command[VSOMEIP_SUBSCRIBE_COMMAND_SIZE];
uint32_t its_size = VSOMEIP_SUBSCRIBE_COMMAND_SIZE
- VSOMEIP_COMMAND_HEADER_SIZE;
@@ -225,14 +303,13 @@ 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], &_ttl,
- sizeof(_ttl));
sender_->send(its_command, sizeof(its_command));
}
void routing_manager_proxy::unsubscribe(client_t _client, service_t _service,
instance_t _instance, eventgroup_t _eventgroup) {
+ (void)_client;
if (is_connected_) {
byte_t its_command[VSOMEIP_UNSUBSCRIBE_COMMAND_SIZE];
@@ -278,6 +355,8 @@ bool routing_manager_proxy::send(client_t its_client,
serializer_->get_size(), _message->get_instance(),
_flush, _message->is_reliable());
serializer_->reset();
+ } else {
+ VSOMEIP_ERROR << "Failed to serialize message. Check message size!";
}
return (is_sent);
}
@@ -311,7 +390,10 @@ bool routing_manager_proxy::send(client_t _client, const byte_t *_data,
std::vector<byte_t> its_command(
VSOMEIP_COMMAND_HEADER_SIZE + _size + sizeof(instance_t)
+ sizeof(bool) + sizeof(bool));
- its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SEND;
+ its_command[VSOMEIP_COMMAND_TYPE_POS]
+ = utility::is_notification(_data[VSOMEIP_MESSAGE_TYPE_POS]) ?
+ VSOMEIP_NOTIFY : VSOMEIP_SEND;
+
std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client,
sizeof(client_t));
std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &_size,
@@ -323,16 +405,7 @@ bool routing_manager_proxy::send(client_t _client, const byte_t *_data,
_flush;
its_command[VSOMEIP_COMMAND_PAYLOAD_POS + _size + sizeof(instance_t)
+ sizeof(bool)] = _reliable;
-
-#if 0
- std::stringstream msg;
- msg << "rmp:send: ";
- for (int i = 0; i < its_command.size(); i++)
- msg << std::hex << std::setw(2) << std::setfill('0') << (int)its_command[i] << " ";
- VSOMEIP_DEBUG << msg.str();
-#endif
-
- is_sent = its_target->send(&its_command[0], its_command.size());
+ is_sent = its_target->send(&its_command[0], uint32_t(its_command.size()));
}
return (is_sent);
}
@@ -340,27 +413,32 @@ bool routing_manager_proxy::send(client_t _client, const byte_t *_data,
bool routing_manager_proxy::send_to(
const std::shared_ptr<endpoint_definition> &_target,
std::shared_ptr<message> _message) {
+ (void)_target;
+ (void)_message;
return (false);
}
bool routing_manager_proxy::send_to(
const std::shared_ptr<endpoint_definition> &_target,
const byte_t *_data, uint32_t _size) {
+ (void)_target;
+ (void)_data;
+ (void)_size;
return (false);
}
void routing_manager_proxy::notify(
service_t _service, instance_t _instance, event_t _event,
std::shared_ptr<payload> _payload) {
- std::shared_ptr<message> its_notification = runtime::get()->create_request();
- its_notification->set_message_type(message_type_e::MT_REQUEST_NO_RETURN);
+ std::shared_ptr<message> its_notification
+ = runtime::get()->create_notification();
its_notification->set_service(_service);
its_notification->set_instance(_instance);
its_notification->set_method(_event);
its_notification->set_payload(_payload);
if (is_connected_) {
send(VSOMEIP_ROUTING_CLIENT, its_notification, true);
- } else {
+ } else if (is_field(_service, _instance, _event)) {
std::lock_guard<std::mutex> its_lock(pending_mutex_);
pending_notifications_[_service][_instance][_event] = its_notification;
}
@@ -369,7 +447,8 @@ void routing_manager_proxy::notify(
void routing_manager_proxy::notify_one(service_t _service, instance_t _instance,
event_t _event, std::shared_ptr<payload> _payload, client_t _client) {
- std::shared_ptr<message> its_notification = runtime::get()->create_notification();
+ std::shared_ptr<message> its_notification
+ = runtime::get()->create_notification();
its_notification->set_service(_service);
its_notification->set_instance(_instance);
its_notification->set_method(_event);
@@ -388,12 +467,24 @@ void routing_manager_proxy::on_connect(std::shared_ptr<endpoint> _endpoint) {
void routing_manager_proxy::on_disconnect(std::shared_ptr<endpoint> _endpoint) {
is_connected_ = !(_endpoint == sender_);
if (!is_connected_) {
- host_->on_event(event_type_e::ET_DEREGISTERED);
+ host_->on_state(state_type_e::ST_DEREGISTERED);
}
}
+void routing_manager_proxy::on_error(const byte_t *_data, length_t _length,
+ endpoint *_receiver) {
+
+ // Implement me when needed
+
+ (void)(_data);
+ (void)(_length);
+ (void)(_receiver);
+}
+
+
void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
endpoint *_receiver) {
+ (void)_receiver;
#if 0
std::stringstream msg;
msg << "rmp::on_message: ";
@@ -407,9 +498,7 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
service_t its_service;
instance_t its_instance;
eventgroup_t its_eventgroup;
- //event_t its_event;
major_version_t its_major;
- minor_version_t its_minor;
ttl_t its_ttl;
if (_size > VSOMEIP_COMMAND_SIZE_POS_MAX) {
@@ -425,15 +514,19 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size,
std::memcpy(&its_instance,
&_data[_size - sizeof(instance_t) - sizeof(bool)
- sizeof(bool)], sizeof(instance_t));
+ bool its_reliable;
+ std::memcpy(&its_reliable, &_data[_size - sizeof(bool)],
+ sizeof(its_reliable));
deserializer_->set_data(&_data[VSOMEIP_COMMAND_PAYLOAD_POS],
its_length);
std::shared_ptr<message> its_message(
deserializer_->deserialize_message());
if (its_message) {
its_message->set_instance(its_instance);
+ its_message->set_reliable(its_reliable);
host_->on_message(its_message);
} else {
- // TODO: send_error(return_code_e::E_MALFORMED_MESSAGE);
+ VSOMEIP_ERROR << "Deserialization of vSomeIP message failed";
}
deserializer_->reset();
}
@@ -487,62 +580,64 @@ void routing_manager_proxy::on_routing_info(const byte_t *_data,
msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
VSOMEIP_DEBUG << msg.str();
#endif
- event_type_e its_state(event_type_e::ET_DEREGISTERED);
-
- std::map<service_t,
- std::map<instance_t, client_t> > old_local_services = local_services_;
- local_services_.clear();
-
- uint32_t i = 0;
- while (i + sizeof(uint32_t) <= _size) {
- uint32_t its_client_size;
- std::memcpy(&its_client_size, &_data[i], sizeof(uint32_t));
- i += sizeof(uint32_t);
-
- if (i + sizeof(client_t) <= _size) {
- client_t its_client;
- std::memcpy(&its_client, &_data[i], sizeof(client_t));
- i += sizeof(client_t);
-
- if (its_client != client_) {
- (void) find_or_create_local(its_client);
- } else {
- its_state = event_type_e::ET_REGISTERED;
- }
+ state_type_e its_state(state_type_e::ST_DEREGISTERED);
+ std::map<service_t, std::map<instance_t, client_t> > old_local_services;
+ {
+ std::lock_guard<std::mutex> its_lock(local_services_mutex_);
+ old_local_services = local_services_;
+ local_services_.clear();
+
+ uint32_t i = 0;
+ while (i + sizeof(uint32_t) <= _size) {
+ uint32_t its_client_size;
+ std::memcpy(&its_client_size, &_data[i], sizeof(uint32_t));
+ i += uint32_t(sizeof(uint32_t));
+
+ if (i + sizeof(client_t) <= _size) {
+ client_t its_client;
+ std::memcpy(&its_client, &_data[i], sizeof(client_t));
+ i += uint32_t(sizeof(client_t));
+
+ if (its_client != client_) {
+ (void) find_or_create_local(its_client);
+ } else {
+ its_state = state_type_e::ST_REGISTERED;
+ }
- uint32_t j = 0;
- while (j + sizeof(uint32_t) <= its_client_size) {
- uint32_t its_services_size;
- std::memcpy(&its_services_size, &_data[i + j], sizeof(uint32_t));
- j += sizeof(uint32_t);
+ uint32_t j = 0;
+ while (j + sizeof(uint32_t) <= its_client_size) {
+ uint32_t its_services_size;
+ std::memcpy(&its_services_size, &_data[i + j], sizeof(uint32_t));
+ j += uint32_t(sizeof(uint32_t));
- if (its_services_size >= sizeof(service_t) + sizeof(instance_t)) {
- its_services_size -= sizeof(service_t);
+ if (its_services_size >= sizeof(service_t) + sizeof(instance_t)) {
+ its_services_size -= uint32_t(sizeof(service_t));
- service_t its_service;
- std::memcpy(&its_service, &_data[i + j], sizeof(service_t));
- j += sizeof(service_t);
+ service_t its_service;
+ std::memcpy(&its_service, &_data[i + j], sizeof(service_t));
+ j += uint32_t(sizeof(service_t));
- while (its_services_size >= sizeof(instance_t)) {
- instance_t its_instance;
- std::memcpy(&its_instance, &_data[i + j], sizeof(instance_t));
- j += sizeof(instance_t);
+ while (its_services_size >= sizeof(instance_t)) {
+ instance_t its_instance;
+ std::memcpy(&its_instance, &_data[i + j], sizeof(instance_t));
+ j += uint32_t(sizeof(instance_t));
- if (its_client != client_)
- local_services_[its_service][its_instance] = its_client;
+ if (its_client != client_)
+ local_services_[its_service][its_instance] = its_client;
- its_services_size -= sizeof(instance_t);
+ its_services_size -= uint32_t(sizeof(instance_t));
+ }
}
}
- }
- i += j;
+ i += j;
+ }
}
}
// inform host about its own registration state changes
if (state_ != its_state) {
- host_->on_event(its_state);
+ host_->on_state(its_state);
state_ = its_state;
}
@@ -595,7 +690,12 @@ void routing_manager_proxy::register_application() {
for (auto &po : pending_offers_)
send_offer_service(client_, po.service_, po.instance_,
- po.major_, po.minor_, po.ttl_);
+ po.major_, po.minor_);
+
+ for (auto &per : pending_event_registrations_)
+ send_register_event(client_, per.service_, per.instance_,
+ per.event_, per.eventgroups_,
+ per.is_field_, per.is_provided_);
for (auto &s : pending_notifications_) {
for (auto &i : s.second) {
@@ -607,13 +707,13 @@ void routing_manager_proxy::register_application() {
for (auto &po : pending_requests_) {
send_request_service(client_, po.service_, po.instance_,
- po.major_, po.minor_, po.ttl_, is_selective_);
+ po.major_, po.minor_, po.use_exclusive_proxy_);
}
std::lock_guard<std::mutex> its_lock(pending_mutex_);
for (auto &ps : pending_subscriptions_)
send_subscribe(client_, ps.service_, ps.instance_,
- ps.eventgroup_, ps.major_, ps.ttl_);
+ ps.eventgroup_, ps.major_);
pending_offers_.clear();
pending_requests_.clear();
@@ -632,7 +732,7 @@ void routing_manager_proxy::deregister_application() {
std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
sizeof(its_size));
if (is_connected_)
- (void)sender_->send(&its_command[0], its_command.size());
+ (void)sender_->send(&its_command[0], uint32_t(its_command.size()));
}
std::shared_ptr<endpoint> routing_manager_proxy::find_local(client_t _client) {
@@ -651,7 +751,7 @@ std::shared_ptr<endpoint> routing_manager_proxy::create_local(
#ifdef WIN32
boost::asio::ip::address address = boost::asio::ip::address::from_string("127.0.0.1");
- int port = 51234;
+ int port = VSOMEIP_INTERNAL_BASE_PORT + _client;
VSOMEIP_DEBUG<< "Connecting to ["
<< std::hex << _client << "] at " << port;
#else
@@ -666,7 +766,7 @@ std::shared_ptr<endpoint> routing_manager_proxy::create_local(
#else
boost::asio::local::stream_protocol::endpoint(its_path.str()),
#endif
- io_);
+ io_, configuration_->get_max_message_size_local());
local_endpoints_[_client] = its_endpoint;
@@ -693,6 +793,7 @@ void routing_manager_proxy::remove_local(client_t _client) {
std::shared_ptr<endpoint> routing_manager_proxy::find_local(service_t _service,
instance_t _instance) {
client_t its_client(0);
+ std::lock_guard<std::mutex> its_lock(local_services_mutex_);
auto found_service = local_services_.find(_service);
if (found_service != local_services_.end()) {
auto found_instance = found_service->second.find(_instance);
@@ -716,35 +817,87 @@ void routing_manager_proxy::send_pong() const {
void routing_manager_proxy::send_request_service(client_t _client, service_t _service,
instance_t _instance, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl, bool _is_selective) {
+ minor_version_t _minor, bool _use_exclusive_proxy) {
+ (void)_client;
- byte_t its_command[VSOMEIP_REQUEST_SERVICE_COMMAND_SIZE];
- uint32_t its_size = VSOMEIP_REQUEST_SERVICE_COMMAND_SIZE
- - VSOMEIP_COMMAND_HEADER_SIZE;
+ if (is_connected_) {
+ byte_t its_command[VSOMEIP_REQUEST_SERVICE_COMMAND_SIZE];
+ uint32_t its_size = VSOMEIP_REQUEST_SERVICE_COMMAND_SIZE
+ - VSOMEIP_COMMAND_HEADER_SIZE;
- its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_REQUEST_SERVICE;
- std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
- sizeof(client_));
- std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
- sizeof(its_size));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
- sizeof(_service));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
- sizeof(_instance));
- its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4] = _major;
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 5], &_minor,
- sizeof(_minor));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 9], &_ttl,
- sizeof(_ttl));
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 13], &_is_selective,
- sizeof(_is_selective));
+ its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_REQUEST_SERVICE;
+ std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
+ sizeof(client_));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
+ sizeof(its_size));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
+ sizeof(_service));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
+ sizeof(_instance));
+ its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4] = _major;
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 5], &_minor,
+ sizeof(_minor));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 9], &_use_exclusive_proxy,
+ sizeof(_use_exclusive_proxy));
- if (is_connected_) {
sender_->send(its_command, sizeof(its_command));
} else {
- service_data_t offer = { _service, _instance, _major, _minor, _ttl };
+ service_data_t request = { _service, _instance, _major, _minor, _use_exclusive_proxy };
+ std::lock_guard<std::mutex> its_lock(pending_mutex_);
+ pending_requests_.insert(request);
+ }
+}
+
+void routing_manager_proxy::send_register_event(client_t _client,
+ service_t _service, instance_t _instance,
+ event_t _event, 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));
+ byte_t *its_command = new byte_t[VSOMEIP_REGISTER_EVENT_COMMAND_SIZE + its_eventgroups_size];
+ uint32_t its_size = VSOMEIP_REGISTER_EVENT_COMMAND_SIZE
+ + its_eventgroups_size
+ - VSOMEIP_COMMAND_HEADER_SIZE;
+
+ its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_REGISTER_EVENT;
+ std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &client_,
+ sizeof(_client));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
+ sizeof(its_size));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], &_service,
+ sizeof(_service));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 2], &_instance,
+ sizeof(_instance));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 4], &_event,
+ sizeof(_event));
+ its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 6]
+ = static_cast<byte_t>(_is_field);
+ its_command[VSOMEIP_COMMAND_PAYLOAD_POS + 7]
+ = static_cast<byte_t>(_is_provided);
+
+ std::size_t i = 8;
+ for (auto eg : _eventgroups) {
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + i], &eg,
+ sizeof(eventgroup_t));
+ i += sizeof(eventgroup_t);
+ }
+
+ sender_->send(its_command,
+ uint32_t(VSOMEIP_REGISTER_EVENT_COMMAND_SIZE
+ + its_eventgroups_size));
+
+ delete[] its_command;
+ } else {
+ event_data_t registration = {
+ _service,
+ _instance,
+ _event,
+ _is_field,
+ _is_provided,
+ _eventgroups
+ };
std::lock_guard<std::mutex> its_lock(pending_mutex_);
- pending_requests_.insert(offer);
+ pending_event_registrations_.insert(registration);
}
}
diff --git a/implementation/routing/src/routing_manager_stub.cpp b/implementation/routing/src/routing_manager_stub.cpp
index 1c3a53c..dfca76f 100644
--- a/implementation/routing/src/routing_manager_stub.cpp
+++ b/implementation/routing/src/routing_manager_stub.cpp
@@ -11,195 +11,217 @@
#include <boost/system/error_code.hpp>
#include <vsomeip/constants.hpp>
-#include <vsomeip/logger.hpp>
#include <vsomeip/primitive_types.hpp>
#include <vsomeip/runtime.hpp>
#include "../include/routing_manager_stub.hpp"
#include "../include/routing_manager_stub_host.hpp"
+#include "../../configuration/include/configuration.hpp"
#include "../../configuration/include/internal.hpp"
#include "../../endpoints/include/local_server_endpoint_impl.hpp"
+#include "../../logging/include/logger.hpp"
#include "../../utility/include/byteorder.hpp"
namespace vsomeip {
-routing_manager_stub::routing_manager_stub(routing_manager_stub_host *_host) :
- host_(_host), io_(_host->get_io()), watchdog_timer_(_host->get_io()) {
+routing_manager_stub::routing_manager_stub(
+ routing_manager_stub_host *_host,
+ std::shared_ptr<configuration> _configuration) :
+ host_(_host),
+ io_(_host->get_io()),
+ watchdog_timer_(_host->get_io()),
+ configuration_(_configuration) {
}
routing_manager_stub::~routing_manager_stub() {
}
void routing_manager_stub::init() {
- std::stringstream its_endpoint_path;
- its_endpoint_path << VSOMEIP_BASE_PATH << VSOMEIP_ROUTING_CLIENT;
- endpoint_path_ = its_endpoint_path.str();
+ std::stringstream its_endpoint_path;
+ its_endpoint_path << VSOMEIP_BASE_PATH << VSOMEIP_ROUTING_CLIENT;
+ endpoint_path_ = its_endpoint_path.str();
#if WIN32
- ::_unlink(endpoint_path_.c_str());
- int port = 51234;
- VSOMEIP_DEBUG << "Routing endpoint at " << port;
+ ::_unlink(endpoint_path_.c_str());
+ int port = VSOMEIP_INTERNAL_BASE_PORT;
+ VSOMEIP_DEBUG << "Routing endpoint at " << port;
#else
- ::unlink(endpoint_path_.c_str());
- VSOMEIP_DEBUG << "Routing endpoint at " << endpoint_path_;
+ ::unlink(endpoint_path_.c_str());
+ VSOMEIP_DEBUG << "Routing endpoint at " << endpoint_path_;
#endif
- endpoint_ =
- std::make_shared < local_server_endpoint_impl
- > (shared_from_this(),
- #ifdef WIN32
- boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port),
- #else
- boost::asio::local::stream_protocol::endpoint(endpoint_path_),
- #endif
- io_);
+ endpoint_ =
+ std::make_shared < local_server_endpoint_impl
+ > (shared_from_this(),
+ #ifdef WIN32
+ boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port),
+ #else
+ boost::asio::local::stream_protocol::endpoint(endpoint_path_),
+ #endif
+ io_, configuration_->get_max_message_size_local());
}
void routing_manager_stub::start() {
- endpoint_->start();
+ endpoint_->start();
- // Start watchdog (TODO: only if configured)
- start_watchdog();
+ // Start watchdog (TODO: only if configured)
+ start_watchdog();
}
void routing_manager_stub::stop() {
- watchdog_timer_.cancel();
- endpoint_->stop();
+ watchdog_timer_.cancel();
+ endpoint_->stop();
#ifdef WIN32
- ::_unlink(endpoint_path_.c_str());
+ ::_unlink(endpoint_path_.c_str());
#else
- ::unlink(endpoint_path_.c_str());
+ ::unlink(endpoint_path_.c_str());
#endif
}
void routing_manager_stub::on_connect(std::shared_ptr<endpoint> _endpoint) {
-
+ (void)_endpoint;
}
void routing_manager_stub::on_disconnect(std::shared_ptr<endpoint> _endpoint) {
+ (void)_endpoint;
+}
+
+void routing_manager_stub::on_error(const byte_t *_data, length_t _length,
+ endpoint *_receiver) {
+
+ // Implement me when needed
+ (void)(_data);
+ (void)(_length);
+ (void)(_receiver);
}
void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
- endpoint *_receiver) {
+ endpoint *_receiver) {
+ (void)_receiver;
#if 0
- std::stringstream msg;
- msg << "rms::on_message: ";
- for (int i = 0; i < _size; ++i)
- msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ std::stringstream msg;
+ msg << "rms::on_message: ";
+ for (length_t i = 0; i < _size; ++i)
+ msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
- if (VSOMEIP_COMMAND_SIZE_POS_MAX < _size) {
- byte_t its_command;
- client_t its_client;
- //session_t its_session;
- std::string its_client_endpoint;
- service_t its_service;
- instance_t its_instance;
- eventgroup_t its_eventgroup;
- //event_t its_event;
- major_version_t its_major;
- minor_version_t its_minor;
- ttl_t its_ttl;
- std::shared_ptr<payload> its_payload;
- const byte_t *its_data;
- uint32_t its_size;
- bool its_reliable(false);
- bool its_flush(true);
-
- its_command = _data[VSOMEIP_COMMAND_TYPE_POS];
- std::memcpy(&its_client, &_data[VSOMEIP_COMMAND_CLIENT_POS],
- sizeof(its_client));
-
- std::memcpy(&its_size, &_data[VSOMEIP_COMMAND_SIZE_POS_MIN],
- sizeof(its_size));
-
- if (its_size <= _size - VSOMEIP_COMMAND_HEADER_SIZE) {
- switch (its_command) {
- case VSOMEIP_REGISTER_APPLICATION:
- on_register_application(its_client);
- VSOMEIP_DEBUG << "Application/Client "
- << std::hex << std::setw(4) << std::setfill('0')
- << its_client << " got registered!";
- break;
-
- case VSOMEIP_DEREGISTER_APPLICATION:
- on_deregister_application(its_client);
- VSOMEIP_DEBUG << "Application/Client "
- << std::hex << std::setw(4) << std::setfill('0')
- << its_client << " got deregistered!";
- break;
-
- case VSOMEIP_PONG:
- on_pong(its_client);
- break;
-
- case VSOMEIP_OFFER_SERVICE:
- std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
- sizeof(its_service));
- std::memcpy(&its_instance,
- &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
- sizeof(its_instance));
- std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
- sizeof(its_major));
- std::memcpy(&its_minor, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 5],
- sizeof(its_minor));
- std::memcpy(&its_ttl, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 9],
- sizeof(its_ttl));
- host_->offer_service(its_client, its_service, its_instance,
- its_major, its_minor, its_ttl);
- on_offer_service(its_client, its_service, its_instance);
- break;
-
- case VSOMEIP_STOP_OFFER_SERVICE:
- std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
- sizeof(its_service));
- std::memcpy(&its_instance,
- &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
- sizeof(its_instance));
- host_->stop_offer_service(its_client, its_service, its_instance);
- on_stop_offer_service(its_client, its_service, its_instance);
- break;
-
- case VSOMEIP_SUBSCRIBE:
- std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
- sizeof(its_service));
- std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
- sizeof(its_instance));
- std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
- sizeof(its_eventgroup));
- std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
- sizeof(its_major));
- std::memcpy(&its_ttl, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 7],
- sizeof(its_ttl));
-
- host_->subscribe(its_client, its_service,
- its_instance, its_eventgroup, its_major, its_ttl);
- break;
-
- case VSOMEIP_UNSUBSCRIBE:
- std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
- sizeof(its_service));
- std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
- sizeof(its_instance));
- std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
- sizeof(its_eventgroup));
- host_->unsubscribe(its_client, its_service,
- its_instance, its_eventgroup);
- break;
-
- case VSOMEIP_SEND:
- its_data = &_data[VSOMEIP_COMMAND_PAYLOAD_POS];
- its_service = VSOMEIP_BYTES_TO_WORD(
- its_data[VSOMEIP_SERVICE_POS_MIN],
- its_data[VSOMEIP_SERVICE_POS_MAX]);
- std::memcpy(&its_instance, &_data[_size - 4], sizeof(its_instance));
- std::memcpy(&its_reliable, &_data[_size - 1], sizeof(its_reliable));
- host_->on_message(its_service, its_instance, its_data, its_size, its_reliable);
- break;
-
- case VSOMEIP_REQUEST_SERVICE:
- bool its_selective;
+ if (VSOMEIP_COMMAND_SIZE_POS_MAX < _size) {
+ byte_t its_command;
+ client_t its_client;
+ std::string its_client_endpoint;
+ service_t its_service;
+ instance_t its_instance;
+ eventgroup_t its_eventgroup;
+ std::set<eventgroup_t> its_eventgroups;
+ event_t its_event;
+ bool is_field(false);
+ bool is_provided(false);
+ major_version_t its_major;
+ minor_version_t its_minor;
+ std::shared_ptr<payload> its_payload;
+ const byte_t *its_data;
+ uint32_t its_size;
+ bool its_reliable(false);
+ bool use_exclusive_proxy(false);
+
+ its_command = _data[VSOMEIP_COMMAND_TYPE_POS];
+ std::memcpy(&its_client, &_data[VSOMEIP_COMMAND_CLIENT_POS],
+ sizeof(its_client));
+
+ std::memcpy(&its_size, &_data[VSOMEIP_COMMAND_SIZE_POS_MIN],
+ sizeof(its_size));
+
+ if (its_size <= _size - VSOMEIP_COMMAND_HEADER_SIZE) {
+ switch (its_command) {
+ case VSOMEIP_REGISTER_APPLICATION:
+ on_register_application(its_client);
+ VSOMEIP_DEBUG << "Application/Client "
+ << std::hex << std::setw(4) << std::setfill('0')
+ << its_client << " got registered!";
+ break;
+
+ case VSOMEIP_DEREGISTER_APPLICATION:
+ on_deregister_application(its_client);
+ VSOMEIP_DEBUG << "Application/Client "
+ << std::hex << std::setw(4) << std::setfill('0')
+ << its_client << " got deregistered!";
+ break;
+
+ case VSOMEIP_PONG:
+ on_pong(its_client);
+ break;
+
+ case VSOMEIP_OFFER_SERVICE:
+ std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
+ sizeof(its_service));
+ std::memcpy(&its_instance,
+ &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
+ sizeof(its_instance));
+ std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
+ sizeof(its_major));
+ std::memcpy(&its_minor, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 5],
+ sizeof(its_minor));
+ host_->offer_service(its_client, its_service, its_instance,
+ its_major, its_minor);
+ on_offer_service(its_client, its_service, its_instance);
+ break;
+
+ case VSOMEIP_STOP_OFFER_SERVICE:
+ std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
+ sizeof(its_service));
+ std::memcpy(&its_instance,
+ &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
+ sizeof(its_instance));
+ host_->stop_offer_service(its_client, its_service, its_instance);
+ on_stop_offer_service(its_client, its_service, its_instance);
+ break;
+
+ case VSOMEIP_SUBSCRIBE:
+ std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
+ sizeof(its_service));
+ std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
+ sizeof(its_instance));
+ std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
+ sizeof(its_eventgroup));
+ std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
+ sizeof(its_major));
+
+ host_->subscribe(its_client, its_service,
+ its_instance, its_eventgroup, its_major);
+ break;
+
+ case VSOMEIP_UNSUBSCRIBE:
+ std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
+ sizeof(its_service));
+ std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
+ sizeof(its_instance));
+ std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
+ sizeof(its_eventgroup));
+ host_->unsubscribe(its_client, its_service,
+ its_instance, its_eventgroup);
+ break;
+
+ case VSOMEIP_SEND:
+ its_data = &_data[VSOMEIP_COMMAND_PAYLOAD_POS];
+ its_service = VSOMEIP_BYTES_TO_WORD(
+ its_data[VSOMEIP_SERVICE_POS_MIN],
+ its_data[VSOMEIP_SERVICE_POS_MAX]);
+ std::memcpy(&its_instance, &_data[_size - 4], sizeof(its_instance));
+ std::memcpy(&its_reliable, &_data[_size - 1], sizeof(its_reliable));
+ host_->on_message(its_service, its_instance, its_data, its_size, its_reliable);
+ break;
+
+ case VSOMEIP_NOTIFY:
+ its_data = &_data[VSOMEIP_COMMAND_PAYLOAD_POS];
+ its_service = VSOMEIP_BYTES_TO_WORD(
+ its_data[VSOMEIP_SERVICE_POS_MIN],
+ its_data[VSOMEIP_SERVICE_POS_MAX]);
+ std::memcpy(&its_instance, &_data[_size - 4], sizeof(its_instance));
+ host_->on_notification(its_client, its_service, its_instance, its_data, its_size);
+ break;
+
+ case VSOMEIP_REQUEST_SERVICE:
std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
sizeof(its_service));
std::memcpy(&its_instance,
@@ -209,238 +231,286 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size,
sizeof(its_major));
std::memcpy(&its_minor, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 5],
sizeof(its_minor));
- std::memcpy(&its_ttl, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 9],
- sizeof(its_ttl));
- std::memcpy(&its_selective, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 13],
- sizeof(its_selective));
- host_->request_service(its_client, its_service, its_instance,
- its_major, its_minor, its_ttl, its_selective);
- break;
- }
- }
- }
+ std::memcpy(&use_exclusive_proxy, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 9],
+ sizeof(use_exclusive_proxy));
+ host_->request_service(its_client, its_service, its_instance,
+ its_major, its_minor, use_exclusive_proxy);
+ break;
+
+
+ case VSOMEIP_RELEASE_SERVICE:
+ break;
+
+ case VSOMEIP_REGISTER_EVENT:
+ std::memcpy(&its_service,
+ &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
+ sizeof(its_service));
+ std::memcpy(&its_instance,
+ &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
+ sizeof(its_instance));
+ std::memcpy(&its_event,
+ &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
+ sizeof(its_event));
+ std::memcpy(&is_field,
+ &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
+ sizeof(is_field));
+ std::memcpy(&is_provided,
+ &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 7],
+ sizeof(is_provided));
+ for (std::size_t i = 8; i+1 < its_size; i++) {
+ std::memcpy(&its_eventgroup,
+ &_data[VSOMEIP_COMMAND_PAYLOAD_POS + i],
+ sizeof(its_eventgroup));
+ its_eventgroups.insert(its_eventgroup);
+ }
+ host_->register_event(its_client, its_service,
+ its_instance, its_event, its_eventgroups,
+ is_field, is_provided);
+ break;
+
+ case VSOMEIP_UNREGISTER_EVENT:
+ std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS],
+ sizeof(its_service));
+ std::memcpy(&its_instance,
+ &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2],
+ sizeof(its_instance));
+ std::memcpy(&its_event, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4],
+ sizeof(its_event));
+ std::memcpy(&is_provided,
+ &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6],
+ sizeof(is_provided));
+ host_->unregister_event(its_client, its_service, its_instance,
+ its_event, is_provided);
+ break;
+ }
+ }
+ }
}
void routing_manager_stub::on_register_application(client_t _client) {
- std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
- (void)host_->find_or_create_local(_client);
- routing_info_[_client].first = 0;
- broadcast_routing_info();
+ std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
+ (void)host_->find_or_create_local(_client);
+ routing_info_[_client].first = 0;
+ broadcast_routing_info();
}
void routing_manager_stub::on_deregister_application(client_t _client) {
- routing_info_mutex_.lock();
- auto its_info = routing_info_.find(_client);
- if (its_info != routing_info_.end()) {
- for (auto &its_service : its_info->second.second) {
- for (auto &its_instance : its_service.second) {
- routing_info_mutex_.unlock();
- host_->on_stop_offer_service(its_service.first, its_instance);
- routing_info_mutex_.lock();
- }
- }
- }
- routing_info_mutex_.unlock();
-
- std::lock_guard<std::mutex> its_lock(routing_info_mutex_);
- host_->remove_local(_client);
- routing_info_.erase(_client);
- broadcast_routing_info();
+ routing_info_mutex_.lock();
+ auto its_info = routing_info_.find(_client);
+ if (its_info != routing_info_.end()) {
+ for (auto &its_service : its_info->second.second) {
+ for (auto &its_instance : its_service.second) {
+ routing_info_mutex_.unlock();
+ host_->on_stop_offer_service(its_service.first, its_instance);
+ routing_info_mutex_.lock();
+ }
+ }
+ }
+ routing_info_mutex_.unlock();
+
+ std::lock_guard<std::mutex> its_lock(routing_info_mutex_);
+ host_->remove_local(_client);
+ routing_info_.erase(_client);
+ broadcast_routing_info();
}
void routing_manager_stub::on_offer_service(client_t _client,
- service_t _service, instance_t _instance) {
- std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
- routing_info_[_client].second[_service].insert(_instance);
- broadcast_routing_info();
+ service_t _service, instance_t _instance) {
+ std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
+ routing_info_[_client].second[_service].insert(_instance);
+ broadcast_routing_info();
}
void routing_manager_stub::on_stop_offer_service(client_t _client,
- service_t _service, instance_t _instance) {
- std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
- auto found_client = routing_info_.find(_client);
- if (found_client != routing_info_.end()) {
- auto found_service = found_client->second.second.find(_service);
- if (found_service != found_client->second.second.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- found_service->second.erase(_instance);
- if (0 == found_service->second.size()) {
- found_client->second.second.erase(_service);
- }
- broadcast_routing_info();
- }
- }
- }
+ service_t _service, instance_t _instance) {
+ std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
+ auto found_client = routing_info_.find(_client);
+ if (found_client != routing_info_.end()) {
+ auto found_service = found_client->second.second.find(_service);
+ if (found_service != found_client->second.second.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ found_service->second.erase(_instance);
+ if (0 == found_service->second.size()) {
+ found_client->second.second.erase(_service);
+ }
+ broadcast_routing_info();
+ }
+ }
+ }
}
void routing_manager_stub::send_routing_info(client_t _client) {
- std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client);
- if (its_endpoint) {
- uint32_t its_capacity = 4096; // TODO: dynamic resizing
- std::vector<byte_t> its_command(its_capacity);
- its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_ROUTING_INFO;
- std::memset(&its_command[VSOMEIP_COMMAND_CLIENT_POS], 0,
- sizeof(client_t));
- uint32_t its_size = VSOMEIP_COMMAND_PAYLOAD_POS;
-
- for (auto &info : routing_info_) {
- uint32_t its_size_pos = its_size;
- uint32_t its_entry_size = its_size;
-
- its_size += sizeof(uint32_t); // placeholder
-
- if (info.first != host_->get_client()) {
- std::memcpy(&its_command[its_size], &info.first, sizeof(client_t));
- } else {
- std::memset(&its_command[its_size], 0x0, sizeof(client_t));
- }
-
- its_size += sizeof(client_t);
-
- for (auto &service : info.second.second) {
- uint32_t its_service_entry_size = sizeof(service_t)
- + service.second.size() * sizeof(instance_t);
-
- std::memcpy(&its_command[its_size], &its_service_entry_size,
- sizeof(uint32_t));
- its_size += sizeof(uint32_t);
-
- std::memcpy(&its_command[its_size], &service.first,
- sizeof(service_t));
- its_size += sizeof(service_t);
-
- for (auto &instance : service.second) {
- std::memcpy(&its_command[its_size], &instance,
- sizeof(instance_t));
- its_size += sizeof(instance_t);
- }
- }
-
- its_entry_size = its_size - its_entry_size - sizeof(uint32_t);
- std::memcpy(&its_command[its_size_pos], &its_entry_size,
- sizeof(uint32_t));
- }
-
- its_size -= VSOMEIP_COMMAND_PAYLOAD_POS;
- std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
- sizeof(its_size));
- its_size += VSOMEIP_COMMAND_PAYLOAD_POS;
+ std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client);
+ if (its_endpoint) {
+ uint32_t its_capacity = 4096; // TODO: dynamic resizing
+ std::vector<byte_t> its_command(its_capacity);
+ its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_ROUTING_INFO;
+ std::memset(&its_command[VSOMEIP_COMMAND_CLIENT_POS], 0,
+ sizeof(client_t));
+ uint32_t its_size = VSOMEIP_COMMAND_PAYLOAD_POS;
+
+ for (auto &info : routing_info_) {
+ uint32_t its_size_pos = its_size;
+ uint32_t its_entry_size = its_size;
+
+ its_size += uint32_t(sizeof(uint32_t)); // placeholder
+
+ if (info.first != host_->get_client()) {
+ std::memcpy(&its_command[its_size], &info.first, sizeof(client_t));
+ } else {
+ std::memset(&its_command[its_size], 0x0, sizeof(client_t));
+ }
+
+ its_size += uint32_t(sizeof(client_t));
+
+ for (auto &service : info.second.second) {
+ uint32_t its_service_entry_size = uint32_t(sizeof(service_t)
+ + service.second.size() * sizeof(instance_t));
+
+ std::memcpy(&its_command[its_size], &its_service_entry_size,
+ sizeof(uint32_t));
+ its_size += uint32_t(sizeof(uint32_t));
+
+ std::memcpy(&its_command[its_size], &service.first,
+ sizeof(service_t));
+ its_size += uint32_t(sizeof(service_t));
+
+ for (auto &instance : service.second) {
+ std::memcpy(&its_command[its_size], &instance,
+ sizeof(instance_t));
+ its_size += uint32_t(sizeof(instance_t));
+ }
+ }
+
+ its_entry_size = its_size - its_entry_size - uint32_t(sizeof(uint32_t));
+ std::memcpy(&its_command[its_size_pos], &its_entry_size,
+ sizeof(uint32_t));
+ }
+
+ its_size -= VSOMEIP_COMMAND_PAYLOAD_POS;
+ std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
+ sizeof(its_size));
+ its_size += VSOMEIP_COMMAND_PAYLOAD_POS;
#if 0
- std::stringstream msg;
- msg << "rms::send_routing_info ";
- for (int i = 0; i < its_size; ++i)
- msg << std::hex << std::setw(2) << std::setfill('0') << (int)its_command[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ std::stringstream msg;
+ msg << "rms::send_routing_info ";
+ for (int i = 0; i < its_size; ++i)
+ msg << std::hex << std::setw(2) << std::setfill('0') << (int)its_command[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
- its_endpoint->send(&its_command[0], its_size, true);
- }
+ its_endpoint->send(&its_command[0], its_size, true);
+ }
}
void routing_manager_stub::broadcast_routing_info() {
- for (auto& info : routing_info_) {
- if (info.first != host_->get_client())
- send_routing_info(info.first);
- }
+ for (auto& info : routing_info_) {
+ if (info.first != VSOMEIP_ROUTING_CLIENT)
+ send_routing_info(info.first);
+ }
}
void routing_manager_stub::broadcast(std::vector<byte_t> &_command) const {
- std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
- for (auto a : routing_info_) {
- if (a.first > 0) {
- std::shared_ptr<endpoint> its_endpoint
- = host_->find_local(a.first);
- if (its_endpoint) {
- its_endpoint->send(&_command[0], _command.size(), true);
- }
- }
- }
+ std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
+ for (auto a : routing_info_) {
+ if (a.first > 0) {
+ std::shared_ptr<endpoint> its_endpoint
+ = host_->find_local(a.first);
+ if (its_endpoint) {
+ its_endpoint->send(&_command[0], uint32_t(_command.size()), true);
+ }
+ }
+ }
}
// Watchdog
void routing_manager_stub::broadcast_ping() const {
- const byte_t its_ping[] = {
- VSOMEIP_PING, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
+ const byte_t its_ping[] = {
+ VSOMEIP_PING, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, };
- std::vector<byte_t> its_command(sizeof(its_ping));
- its_command.assign(its_ping, its_ping + sizeof(its_ping));
- broadcast(its_command);
+ std::vector<byte_t> its_command(sizeof(its_ping));
+ its_command.assign(its_ping, its_ping + sizeof(its_ping));
+ broadcast(its_command);
}
void routing_manager_stub::on_pong(client_t _client) {
- auto found_info = routing_info_.find(_client);
- if (found_info != routing_info_.end()) {
- found_info->second.first = 0;
- } else {
- VSOMEIP_ERROR << "Received PONG from unregistered application!";
- }
+ auto found_info = routing_info_.find(_client);
+ if (found_info != routing_info_.end()) {
+ found_info->second.first = 0;
+ } else {
+ VSOMEIP_ERROR << "Received PONG from unregistered application!";
+ }
}
void routing_manager_stub::start_watchdog() {
- watchdog_timer_.expires_from_now(
- std::chrono::milliseconds(VSOMEIP_DEFAULT_WATCHDOG_CYCLE)); // TODO: use config variable
+ watchdog_timer_.expires_from_now(
+ std::chrono::milliseconds(VSOMEIP_DEFAULT_WATCHDOG_CYCLE)); // TODO: use config variable
- std::function<void(boost::system::error_code const &)> its_callback =
- [this](boost::system::error_code const &_error) {
- if (!_error)
- check_watchdog();
- };
+ std::function<void(boost::system::error_code const &)> its_callback =
+ [this](boost::system::error_code const &_error) {
+ if (!_error)
+ check_watchdog();
+ };
- watchdog_timer_.async_wait(its_callback);
+ watchdog_timer_.async_wait(its_callback);
}
void routing_manager_stub::check_watchdog() {
- for (auto i = routing_info_.begin(); i != routing_info_.end(); ++i) {
- i->second.first++;
- }
- broadcast_ping();
-
- watchdog_timer_.expires_from_now(
- std::chrono::milliseconds(VSOMEIP_DEFAULT_WATCHDOG_TIMEOUT)); // TODO: use config variable
-
- std::function<void(boost::system::error_code const &)> its_callback =
- [this](boost::system::error_code const &_error) {
- std::list< client_t > lost;
- {
- std::lock_guard<std::mutex> its_lock(routing_info_mutex_);
- for (auto i : routing_info_) {
- if (i.first > 0 && i.first != host_->get_client()) {
- if (i.second.first > VSOMEIP_DEFAULT_MAX_MISSING_PONGS) { // TODO: use config variable
- VSOMEIP_WARNING << "Lost contact to application " << std::hex << (int)i.first;
- lost.push_back(i.first);
- }
- }
- }
-
- for (auto i : lost) {
- routing_info_.erase(i);
- }
- }
- if (0 < lost.size())
- send_application_lost(lost);
-
- start_watchdog();
- };
-
- watchdog_timer_.async_wait(its_callback);
+ {
+ std::lock_guard<std::mutex> its_guard(routing_info_mutex_);
+ for (auto i = routing_info_.begin(); i != routing_info_.end(); ++i) {
+ i->second.first++;
+ }
+ }
+ broadcast_ping();
+
+ watchdog_timer_.expires_from_now(
+ std::chrono::milliseconds(VSOMEIP_DEFAULT_WATCHDOG_TIMEOUT)); // TODO: use config variable
+
+ std::function<void(boost::system::error_code const &)> its_callback =
+ [this](boost::system::error_code const &_error) {
+ (void)_error;
+ std::list< client_t > lost;
+ {
+ std::lock_guard<std::mutex> its_lock(routing_info_mutex_);
+ for (auto i : routing_info_) {
+ if (i.first > 0 && i.first != host_->get_client()) {
+ if (i.second.first > VSOMEIP_DEFAULT_MAX_MISSING_PONGS) { // TODO: use config variable
+ VSOMEIP_WARNING << "Lost contact to application " << std::hex << (int)i.first;
+ lost.push_back(i.first);
+ }
+ }
+ }
+
+ for (auto i : lost) {
+ routing_info_.erase(i);
+ }
+ }
+ if (0 < lost.size())
+ send_application_lost(lost);
+
+ start_watchdog();
+ };
+
+ watchdog_timer_.async_wait(its_callback);
}
void routing_manager_stub::send_application_lost(std::list<client_t> &_lost) {
- uint32_t its_size = _lost.size() * sizeof(client_t);
- std::vector<byte_t> its_command(VSOMEIP_COMMAND_HEADER_SIZE + its_size);
- its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_APPLICATION_LOST;
- std::memset(&its_command[VSOMEIP_COMMAND_CLIENT_POS], 0, sizeof(client_t));
- std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
- sizeof(uint32_t));
-
- uint32_t its_offset = 0;
- for (auto i : _lost) {
- std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + its_offset], &i,
- sizeof(client_t));
- its_offset += sizeof(client_t);
- }
-
- broadcast(its_command);
+ uint32_t its_size = uint32_t(_lost.size() * sizeof(client_t));
+ std::vector<byte_t> its_command(VSOMEIP_COMMAND_HEADER_SIZE + its_size);
+ its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_APPLICATION_LOST;
+ std::memset(&its_command[VSOMEIP_COMMAND_CLIENT_POS], 0, sizeof(client_t));
+ std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size,
+ sizeof(uint32_t));
+
+ uint32_t its_offset = 0;
+ for (auto i : _lost) {
+ std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + its_offset], &i,
+ sizeof(client_t));
+ its_offset += uint32_t(sizeof(client_t));
+ }
+
+ broadcast(its_command);
}
} // namespace vsomeip
diff --git a/implementation/routing/src/servicegroup.cpp b/implementation/routing/src/servicegroup.cpp
deleted file mode 100644
index ce4739e..0000000
--- a/implementation/routing/src/servicegroup.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.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/servicegroup.hpp"
-#include "../include/serviceinfo.hpp"
-
-namespace vsomeip {
-
-servicegroup::servicegroup(const std::string &_name, bool _is_local)
- : name_(_name), is_local_(_is_local) {
-}
-
-servicegroup::~servicegroup() {
-}
-
-std::string servicegroup::get_name() const {
- return name_;
-}
-
-bool servicegroup::is_local() const {
- return is_local_;
-}
-
-bool servicegroup::add_service(
- service_t _service, instance_t _instance,
- std::shared_ptr< serviceinfo > _info) {
- bool its_result(true);
- auto find_service = services_.find(_service);
- if (find_service != services_.end()) {
- auto find_instance = find_service->second.find(_instance);
- if (find_instance != find_service->second.end()) {
- its_result = false;
- } else {
- find_service->second[_instance] = _info;
- }
- } else {
- services_[_service][_instance] = _info;
- }
-
- _info->set_group(this);
-
- return its_result;
-}
-
-bool servicegroup::remove_service(service_t _service, instance_t _instance) {
- bool its_result(false);
- auto find_service = services_.find(_service);
- if (find_service != services_.end()) {
- auto find_instance = find_service->second.find(_instance);
- if (find_instance != find_service->second.end()) {
- find_service->second.erase(_instance);
- if (0 == find_service->second.size()) {
- services_.erase(_service);
- }
- its_result = true;
- }
- }
- return its_result;
-}
-
-services_t servicegroup::get_services() const {
- return services_;
-}
-
-} // namespace vsomeip
-
-
-
diff --git a/implementation/routing/src/serviceinfo.cpp b/implementation/routing/src/serviceinfo.cpp
index 60704ad..75d11dd 100644
--- a/implementation/routing/src/serviceinfo.cpp
+++ b/implementation/routing/src/serviceinfo.cpp
@@ -8,14 +8,15 @@
namespace vsomeip {
serviceinfo::serviceinfo(major_version_t _major, minor_version_t _minor,
- ttl_t _ttl)
+ ttl_t _ttl, bool _is_local)
: group_(0),
major_(_major),
minor_(_minor),
ttl_(_ttl),
reliable_(nullptr),
unreliable_(nullptr),
- multicast_group_(0xFFFF) {
+ multicast_group_(0xFFFF),
+ is_local_(_is_local) {
}
serviceinfo::~serviceinfo() {
@@ -90,5 +91,9 @@ void serviceinfo::remove_client(client_t _client) {
requesters_.erase(_client);
}
+bool serviceinfo::is_local() const {
+ return is_local_;
+}
+
} // namespace vsomeip
diff --git a/implementation/runtime/include/application_impl.hpp b/implementation/runtime/include/application_impl.hpp
index 3b37df0..76d316e 100644
--- a/implementation/runtime/include/application_impl.hpp
+++ b/implementation/runtime/include/application_impl.hpp
@@ -37,30 +37,47 @@ public:
VSOMEIP_EXPORT application_impl(const std::string &_name);
VSOMEIP_EXPORT ~application_impl();
+ VSOMEIP_EXPORT void set_configuration(const std::shared_ptr<configuration> _configuration);
+
VSOMEIP_EXPORT bool init();
VSOMEIP_EXPORT void start();
VSOMEIP_EXPORT void stop();
+ // Provide services / events
VSOMEIP_EXPORT void offer_service(service_t _service, instance_t _instance,
- major_version_t _major, minor_version_t _minor, ttl_t _ttl);
+ major_version_t _major, minor_version_t _minor);
VSOMEIP_EXPORT void stop_offer_service(service_t _service,
instance_t _instance);
- // Consume services
+ VSOMEIP_EXPORT void offer_event(service_t _service,
+ instance_t _instance, event_t _event,
+ std::set<eventgroup_t> _eventgroups,
+ bool _is_field);
+ VSOMEIP_EXPORT void stop_offer_event(service_t _service,
+ instance_t _instance, event_t _event);
+
+ // Consume services / events
VSOMEIP_EXPORT void request_service(service_t _service,
- instance_t _instance, bool _has_selective, major_version_t _major,
- minor_version_t _minor, ttl_t _ttl);
+ instance_t _instance, major_version_t _major,
+ minor_version_t _minor, bool _use_exclusive_proxy);
VSOMEIP_EXPORT void release_service(service_t _service,
instance_t _instance);
+ VSOMEIP_EXPORT void request_event(service_t _service,
+ instance_t _instance, event_t _event,
+ 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, ttl_t _ttl);
+ eventgroup_t _eventgroup, major_version_t _major);
VSOMEIP_EXPORT void unsubscribe(service_t _service, instance_t _instance,
eventgroup_t _eventgroup);
- VSOMEIP_EXPORT bool is_available(service_t _service, instance_t _instance);
+ VSOMEIP_EXPORT bool is_available(service_t _service, instance_t _instance) const;
VSOMEIP_EXPORT void send(std::shared_ptr<message> _message, bool _flush);
@@ -70,8 +87,8 @@ public:
VSOMEIP_EXPORT void notify_one(service_t _service, instance_t _instance,
event_t _event, std::shared_ptr<payload> _payload, client_t _client) const;
- VSOMEIP_EXPORT void register_event_handler(event_handler_t _handler);
- VSOMEIP_EXPORT void unregister_event_handler();
+ VSOMEIP_EXPORT void register_state_handler(state_handler_t _handler);
+ VSOMEIP_EXPORT void unregister_state_handler();
VSOMEIP_EXPORT void register_message_handler(service_t _service,
instance_t _instance, method_t _method, message_handler_t _handler);
@@ -94,10 +111,9 @@ public:
VSOMEIP_EXPORT std::shared_ptr<configuration> get_configuration() const;
VSOMEIP_EXPORT boost::asio::io_service & get_io();
- VSOMEIP_EXPORT void on_event(event_type_e _event);
- VSOMEIP_EXPORT void on_availability(service_t _service,
- instance_t _instance,
- bool _is_available) const;
+ VSOMEIP_EXPORT void on_state(state_type_e _state);
+ VSOMEIP_EXPORT void on_availability(service_t _service, instance_t _instance,
+ bool _is_available) const;
VSOMEIP_EXPORT void on_message(std::shared_ptr<message> _message);
VSOMEIP_EXPORT void on_error(error_code_e _error);
VSOMEIP_EXPORT bool on_subscription(service_t _service, instance_t _instance,
@@ -116,24 +132,28 @@ private:
}
void dispatch();
+ void wait_for_stop();
private:
client_t client_; // unique application identifier
session_t session_;
+ std::mutex session_mutex_;
std::mutex initialize_mutex_;
bool is_initialized_;
std::string name_;
std::shared_ptr<configuration> configuration_;
+ std::string file_; // configuration file
+ std::string folder_; // configuration folder
boost::asio::io_service io_;
// Proxy to or the Routing Manager itself
std::shared_ptr<routing_manager> routing_;
- // (Non-SOME/IP) Event handler
- event_handler_t handler_;
+ // vsomeip state handler
+ state_handler_t handler_;
// Method/Event (=Member) handlers
std::map<service_t,
@@ -169,6 +189,11 @@ private:
// Workaround for destruction problem
std::shared_ptr<logger> logger_;
+
+ std::condition_variable stop_cv_;
+ std::mutex start_stop_mutex_;
+ bool stopped_;
+ std::thread stop_thread_;
};
} // namespace vsomeip
diff --git a/implementation/runtime/include/runtime_impl.hpp b/implementation/runtime/include/runtime_impl.hpp
index 6240969..123272b 100644
--- a/implementation/runtime/include/runtime_impl.hpp
+++ b/implementation/runtime/include/runtime_impl.hpp
@@ -7,6 +7,7 @@
#define VSOMEIP_RUNTIME_IMPL_HPP
#include <vsomeip/runtime.hpp>
+#include <map>
namespace vsomeip {
@@ -17,7 +18,7 @@ public:
virtual ~runtime_impl();
std::shared_ptr<application> create_application(
- const std::string &_name) const;
+ const std::string &_name);
std::shared_ptr<message> create_message(bool _reliable) const;
std::shared_ptr<message> create_request(bool _reliable) const;
@@ -30,6 +31,14 @@ public:
uint32_t _size) const;
std::shared_ptr<payload> create_payload(
const std::vector<byte_t> &_data) const;
+
+ std::shared_ptr<application> get_application(
+ const std::string &_name) const;
+
+private:
+ static std::shared_ptr<runtime> the_runtime_;
+
+ std::map<std::string, std::shared_ptr<application>> applications_;
};
} // namespace vsomeip
diff --git a/implementation/runtime/src/application_impl.cpp b/implementation/runtime/src/application_impl.cpp
index 77eef78..f713e28 100644
--- a/implementation/runtime/src/application_impl.cpp
+++ b/implementation/runtime/src/application_impl.cpp
@@ -3,70 +3,175 @@
// License, v. 2.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 <future>
#include <thread>
-#include <iostream>
+#include <iomanip>
-#include <vsomeip/configuration.hpp>
+#ifndef WIN32
+#include <dlfcn.h>
+#endif
+#include <iostream>
#include <vsomeip/defines.hpp>
-#include <vsomeip/logger.hpp>
#include "../include/application_impl.hpp"
+#include "../../configuration/include/configuration.hpp"
#include "../../configuration/include/internal.hpp"
+#include "../../logging/include/logger.hpp"
#include "../../message/include/serializer.hpp"
#include "../../routing/include/routing_manager_impl.hpp"
#include "../../routing/include/routing_manager_proxy.hpp"
#include "../../utility/include/utility.hpp"
+#include "../../configuration/include/configuration_impl.hpp"
namespace vsomeip {
application_impl::application_impl(const std::string &_name)
- : name_(_name), is_initialized_(false), routing_(0), signals_(io_,
- SIGINT, SIGTERM), num_dispatchers_(0), logger_(logger::get()) {
+ : is_initialized_(false), name_(_name),
+ file_(VSOMEIP_DEFAULT_CONFIGURATION_FILE),
+ folder_(VSOMEIP_DEFAULT_CONFIGURATION_FOLDER),
+ routing_(0),
+ signals_(io_, SIGINT, SIGTERM),
+ num_dispatchers_(0), logger_(logger::get()),
+ stopped_(false) {
}
application_impl::~application_impl() {
#ifdef WIN32
- // killemall
- exit(0);
+ exit(0); // TODO: clean solution...
#endif
+ stop_thread_.join();
}
-bool application_impl::init() {
- bool is_initialized(false);
+void application_impl::set_configuration(
+ const std::shared_ptr<configuration> _configuration) {
+ if(_configuration)
+ configuration_ = std::make_shared<cfg::configuration_impl>(*(std::static_pointer_cast<cfg::configuration_impl, configuration>(_configuration)));
+}
+bool application_impl::init() {
// Application name
if (name_ == "") {
const char *its_name = getenv(VSOMEIP_ENV_APPLICATION_NAME);
if (nullptr != its_name) {
name_ = its_name;
+ }
+ }
+
+ // load configuration from module
+ std::string config_module = "";
+ const char *its_config_module = getenv(VSOMEIP_ENV_CONFIGURATION_MODULE);
+ if(nullptr != its_config_module) {
+ config_module = its_config_module;
+ if (config_module.rfind(".so") != config_module.length() - 3) {
+ config_module += ".so";
+ }
+ VSOMEIP_INFO << "Loading configuration from module \"" << config_module << "\".";
+#ifdef WIN32
+ HMODULE config = LoadLibrary(config_module.c_str());
+ if (config != 0) {
+ VSOMEIP_INFO << "\"" << config_module << "\" was loaded";
+ if (!configuration_) {
+ VSOMEIP_ERROR << "Configuration not set.";
+ return false;
+ }
} else {
- VSOMEIP_ERROR<< "Missing application name. "
- "Please set environment variable VSOMEIP_APPLICATION_NAME.";
+ VSOMEIP_ERROR << "\"" << config_module << "\" could not be loaded (" << GetLastError() << ")";
return false;
}
+ FreeModule(config);
+#else
+ void *config = dlopen(config_module.c_str(), RTLD_LAZY | RTLD_GLOBAL);
+ if(config != 0) {
+ VSOMEIP_INFO << "\"" << config_module << "\" was loaded";
+ if(!configuration_) {
+ VSOMEIP_ERROR << "Configuration not set.";
+ return false;
+ }
+ } else {
+ VSOMEIP_ERROR << "\"" << config_module << "\" could not be loaded (" << dlerror() << ")";
+ return false;
+ }
+ dlclose(config);
+#endif
+ } else {
+ // Override with local file /folder
+ std::string its_local_file(VSOMEIP_LOCAL_CONFIGURATION_FILE);
+ if (utility::is_file(its_local_file)) {
+ file_ = its_local_file;
+ }
+
+ std::string its_local_folder(VSOMEIP_LOCAL_CONFIGURATION_FOLDER);
+ if (utility::is_folder(its_local_folder)) {
+ folder_ = its_local_folder;
+ }
+
+ // Finally, override with path from environment
+ const char *its_env = getenv(VSOMEIP_ENV_CONFIGURATION);
+ if (nullptr != its_env) {
+ if (utility::is_file(its_env)) {
+ file_ = its_env;
+ folder_ = "";
+ } else if (utility::is_folder(its_env)) {
+ folder_ = its_env;
+ file_ = "";
+ }
+ }
}
- // Set default path
- std::string its_path(VSOMEIP_DEFAULT_CONFIGURATION_FILE_PATH);
+ std::shared_ptr<configuration> its_configuration = get_configuration();
+ if (its_configuration) {
+ VSOMEIP_INFO << "Initializing vsomeip application \"" << name_ << "\"";
- // Override with path from environment
- const char *its_env_path = getenv(VSOMEIP_ENV_CONFIGURATION_FILE_PATH);
- if (nullptr != its_env_path && utility::exists(its_env_path))
- its_path = its_env_path;
+ if (utility::is_file(file_))
+ VSOMEIP_INFO << "Using configuration file: \"" << file_ << "\"";
- // Override with local path
- std::string its_local_path(VSOMEIP_LOCAL_CONFIGURATION_FILE_PATH);
- if (utility::exists(its_local_path))
- its_path = its_local_path;
+ if (utility::is_folder(folder_))
+ VSOMEIP_INFO << "Using configuration folder: \"" << folder_ << "\"";
- configuration_.reset(configuration::get(its_path));
- VSOMEIP_INFO<< "Using configuration file: " << its_path;
+ bool is_routing_manager_host(false);
+ client_ = its_configuration->get_id(name_);
+ std::string its_routing_host = its_configuration->get_routing_host();
- if (configuration_) {
- client_ = configuration_->get_id(name_);
+ if (client_ == 0 || its_routing_host == "") {
+#ifndef WIN32
+ if (!utility::auto_configuration_init()) {
+ VSOMEIP_ERROR << "Configuration incomplete and "
+ "Auto-configuration failed!";
+ return false;
+ }
+#else
+ return false;
+#endif
+ }
+ // Client ID
+ if (client_ == 0) {
+#ifndef WIN32
+ client_ = utility::get_client_id();
+ VSOMEIP_INFO << "No SOME/IP client identifier configured. "
+ << "Using auto-configured "
+ << std::hex << std::setfill('0') << std::setw(4)
+ << client_;
+#else
+ return false;
+#endif
+ }
// Routing
- if (name_ == configuration_->get_routing_host()) {
+ if (its_routing_host == "") {
+#ifndef WIN32
+ is_routing_manager_host = utility::is_routing_manager_host();
+ VSOMEIP_INFO << "No routing manager configured. "
+ << "Using auto-configuration ("
+ << (is_routing_manager_host ?
+ "Host" : "Proxy") << ")";
+#else
+ return false;
+#endif
+ } else {
+ is_routing_manager_host = (its_routing_host == name_);
+ }
+
+ if (is_routing_manager_host) {
routing_ = std::make_shared<routing_manager_impl>(this);
} else {
routing_ = std::make_shared<routing_manager_proxy>(this);
@@ -74,19 +179,22 @@ bool application_impl::init() {
routing_->init();
- num_dispatchers_ = configuration_->get_num_dispatchers(name_);
+ num_dispatchers_ = its_configuration->get_num_dispatchers(name_);
// Smallest allowed session identifier
session_ = 0x0001;
- VSOMEIP_DEBUG<< "Application(" << name_ << ", "
- << std::hex << client_ << ") is initialized (uses "
+ VSOMEIP_DEBUG<< "Application(" << (name_ != "" ? name_ : "unnamed")
+ << ", " << std::hex << client_ << ") is initialized (uses "
<< std::dec << num_dispatchers_ << " dispatcher threads).";
is_initialized_ = true;
}
if (is_initialized_) {
+ signals_.add(SIGINT);
+ signals_.add(SIGTERM);
+
// Register signal handler
std::function<void(boost::system::error_code const &, int)> its_signal_handler =
[this] (boost::system::error_code const &_error, int _signal) {
@@ -109,35 +217,60 @@ bool application_impl::init() {
}
void application_impl::start() {
- is_dispatching_ = true;
+ {
+ std::lock_guard<std::mutex> its_lock(start_stop_mutex_);
+ if(io_.stopped()) {
+ io_.reset();
+ } else if(stop_thread_.joinable()) {
+ VSOMEIP_ERROR << "Trying to start an already started application.";
+ return;
+ }
- for (size_t i = 0; i < num_dispatchers_; i++)
- dispatchers_.push_back(
- std::thread(std::bind(&application_impl::dispatch, this)));
+ is_dispatching_ = true;
- if (routing_)
- routing_->start();
+ for (size_t i = 0; i < num_dispatchers_; i++)
+ dispatchers_.push_back(
+ std::thread(std::bind(&application_impl::dispatch, this)));
+ if(stop_thread_.joinable()) {
+ stop_thread_.join();
+ }
+ stop_thread_= std::thread(&application_impl::wait_for_stop, this);
+
+ if (routing_)
+ routing_->start();
+ }
+ VSOMEIP_INFO << "Starting vsomeip application \"" << name_ << "\"";
io_.run();
}
void application_impl::stop() {
+ VSOMEIP_INFO << "Stopping vsomeip application \"" << name_ << "\"";
+ std::lock_guard<std::mutex> its_lock(start_stop_mutex_);
is_dispatching_ = false;
dispatch_condition_.notify_all();
- for (auto &t : dispatchers_)
- t.join();
+ for (auto &t : dispatchers_) {
+ if(t.get_id() == std::this_thread::get_id()) {
+ continue;
+ }
+ if(t.joinable()) {
+ t.join();
+ }
+ }
if (routing_)
routing_->stop();
-
- io_.stop();
+#ifndef WIN32
+ utility::auto_configuration_exit();
+#endif
+ stopped_ = true;
+ stop_cv_.notify_one();
}
void application_impl::offer_service(service_t _service, instance_t _instance,
- major_version_t _major, minor_version_t _minor, ttl_t _ttl) {
+ major_version_t _major, minor_version_t _minor) {
if (routing_)
- routing_->offer_service(client_, _service, _instance, _major, _minor,
- _ttl);
+ routing_->offer_service(client_, _service, _instance, _major, _minor);
}
void application_impl::stop_offer_service(service_t _service,
@@ -147,11 +280,10 @@ void application_impl::stop_offer_service(service_t _service,
}
void application_impl::request_service(service_t _service, instance_t _instance,
- bool _has_selective, major_version_t _major, minor_version_t _minor,
- ttl_t _ttl) {
+ major_version_t _major, minor_version_t _minor, bool _use_exclusive_proxy) {
if (routing_)
routing_->request_service(client_, _service, _instance, _major, _minor,
- _ttl, _has_selective);
+ _use_exclusive_proxy);
}
void application_impl::release_service(service_t _service,
@@ -161,10 +293,9 @@ 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, ttl_t _ttl) {
+ eventgroup_t _eventgroup, major_version_t _major) {
if (routing_)
- routing_->subscribe(client_, _service, _instance, _eventgroup, _major,
- _ttl);
+ routing_->subscribe(client_, _service, _instance, _eventgroup, _major);
}
void application_impl::unsubscribe(service_t _service, instance_t _instance,
@@ -173,7 +304,8 @@ void application_impl::unsubscribe(service_t _service, instance_t _instance,
routing_->unsubscribe(client_, _service, _instance, _eventgroup);
}
-bool application_impl::is_available(service_t _service, instance_t _instance) {
+bool application_impl::is_available(
+ service_t _service, instance_t _instance) const {
auto found_available = available_.find(_service);
if (found_available == available_.end())
return false;
@@ -183,6 +315,7 @@ bool application_impl::is_available(service_t _service, instance_t _instance) {
}
void application_impl::send(std::shared_ptr<message> _message, bool _flush) {
+ std::lock_guard<std::mutex> its_lock(session_mutex_);
if (routing_) {
// in case of requests set the request-id (client-id|session-id)
bool is_request = utility::is_request(_message);
@@ -214,18 +347,23 @@ void application_impl::notify_one(service_t _service, instance_t _instance,
}
}
-void application_impl::register_event_handler(event_handler_t _handler) {
+void application_impl::register_state_handler(state_handler_t _handler) {
handler_ = _handler;
}
-void application_impl::unregister_event_handler() {
+void application_impl::unregister_state_handler() {
handler_ = nullptr;
}
void application_impl::register_availability_handler(service_t _service,
instance_t _instance, availability_handler_t _handler) {
- std::unique_lock<std::mutex> its_lock(availability_mutex_);
- availability_[_service][_instance] = _handler;
+ {
+ std::unique_lock<std::mutex> its_lock(availability_mutex_);
+ availability_[_service][_instance] = _handler;
+ }
+ std::async(std::launch::async, [this, _service, _instance, _handler]() {
+ _handler(_service, _instance, is_available(_service, _instance));
+ });
}
void application_impl::unregister_availability_handler(service_t _service,
@@ -302,6 +440,32 @@ 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) {
+ if (routing_)
+ routing_->register_event(client_, _service, _instance, _event,
+ _eventgroups, _is_field, true);
+}
+
+void application_impl::stop_offer_event(service_t _service, instance_t _instance,
+ event_t _event) {
+ if (routing_)
+ routing_->unregister_event(client_, _service, _instance, _event, true);
+}
+
+void application_impl::request_event(service_t _service, instance_t _instance,
+ event_t _event, std::set<eventgroup_t> _eventgroups, bool _is_field) {
+ if (routing_)
+ routing_->register_event(client_, _service, _instance, _event,
+ _eventgroups, _is_field, false);
+ }
+
+void application_impl::release_event(service_t _service, instance_t _instance,
+ event_t _event) {
+ if (routing_)
+ routing_->unregister_event(client_, _service, _instance, _event, false);
+}
+
// Interface "routing_manager_host"
const std::string & application_impl::get_name() const {
return name_;
@@ -312,23 +476,36 @@ client_t application_impl::get_client() const {
}
std::shared_ptr<configuration> application_impl::get_configuration() const {
- return configuration_;
+ if(configuration_) {
+ return configuration_;
+ } else {
+ std::set<std::string> its_input;
+ std::shared_ptr<configuration> its_configuration;
+ if (file_ != "") {
+ its_input.insert(file_);
+ }
+ if (folder_ != "") {
+ its_input.insert(folder_);
+ }
+ its_configuration = configuration::get(its_input);
+ return its_configuration;
+ }
}
boost::asio::io_service & application_impl::get_io() {
return io_;
}
-void application_impl::on_event(event_type_e _event) {
+void application_impl::on_state(state_type_e _state) {
if (handler_) {
if (num_dispatchers_ > 0) {
std::unique_lock<std::mutex> its_lock(dispatch_mutex_);
- handlers_.push_back([this, _event]() {
- handler_(_event);
+ handlers_.push_back([this, _state]() {
+ handler_(_state);
});
dispatch_condition_.notify_one();
} else {
- handler_(_event);
+ handler_(_state);
}
}
}
@@ -346,6 +523,9 @@ void application_impl::on_availability(service_t _service, instance_t _instance,
{
std::unique_lock<std::mutex> its_lock(availability_mutex_);
+ if (_is_available == is_available(_service, _instance))
+ return;
+
if (_is_available) {
available_[_service].insert(_instance);
} else {
@@ -474,4 +654,19 @@ void application_impl::dispatch() {
}
}
+void application_impl::wait_for_stop() {
+ std::unique_lock<std::mutex> its_lock(start_stop_mutex_);
+ while(!stopped_) {
+ stop_cv_.wait(its_lock);
+ }
+ stopped_ = false;
+
+ for (auto &t : dispatchers_) {
+ if(t.joinable()) {
+ t.join();
+ }
+ }
+ io_.stop();
+}
+
} // namespace vsomeip
diff --git a/implementation/runtime/src/runtime_impl.cpp b/implementation/runtime/src/runtime_impl.cpp
index 896ed15..e50ceca 100644
--- a/implementation/runtime/src/runtime_impl.cpp
+++ b/implementation/runtime/src/runtime_impl.cpp
@@ -12,18 +12,20 @@
namespace vsomeip {
+std::shared_ptr<runtime> runtime_impl::the_runtime_ = std::make_shared<runtime_impl>();
+
std::shared_ptr<runtime> runtime_impl::get() {
- static std::shared_ptr<runtime> the_runtime =
- std::make_shared<runtime_impl>();
- return the_runtime;
+ return the_runtime_;
}
runtime_impl::~runtime_impl() {
}
std::shared_ptr<application> runtime_impl::create_application(
- const std::string &_name) const {
- return (std::make_shared<application_impl>(_name));
+ const std::string &_name) {
+ std::shared_ptr<application> application = std::make_shared<application_impl>(_name);
+ applications_[_name] = application;
+ return application;
}
std::shared_ptr<message> runtime_impl::create_message(bool _reliable) const {
@@ -86,4 +88,12 @@ std::shared_ptr<payload> runtime_impl::create_payload(
return (std::make_shared<payload_impl>(_data));
}
+std::shared_ptr<application> runtime_impl::get_application(
+ const std::string &_name) const {
+ auto found_application = applications_.find(_name);
+ if(found_application != applications_.end())
+ return found_application->second;
+ return nullptr;
+}
+
} // namespace vsomeip
diff --git a/implementation/service_discovery/include/defines.hpp b/implementation/service_discovery/include/defines.hpp
index a239f54..2d23c3c 100644
--- a/implementation/service_discovery/include/defines.hpp
+++ b/implementation/service_discovery/include/defines.hpp
@@ -15,11 +15,18 @@
#define VSOMEIP_SD_METHOD 0x8100
#define VSOMEIP_SD_CLIENT 0x0000
-#define VSOMEIP_SD_DEFAULT_MIN_INITIAL_DELAY 0
-#define VSOMEIP_SD_DEFAULT_MAX_INITIAL_DELAY 3000
-#define VSOMEIP_SD_DEFAULT_REPETITION_BASE_DELAY 10
-#define VSOMEIP_SD_DEFAULT_REPETITION_MAX 5
-#define VSOMEIP_SD_DEFAULT_CYCLIC_OFFER_DELAY 1000
-#define VSOMEIP_SD_DEFAULT_CYCLIC_REQUEST_DELAY 2000
+
+#define VSOMEIP_SD_DEFAULT_ENABLED true
+#define VSOMEIP_SD_DEFAULT_PROTOCOL "udp"
+#define VSOMEIP_SD_DEFAULT_MULTICAST "224.224.224.0"
+#define VSOMEIP_SD_DEFAULT_PORT 30490
+
+#define VSOMEIP_SD_DEFAULT_INITIAL_DELAY_MIN 0
+#define VSOMEIP_SD_DEFAULT_INITIAL_DELAY_MAX 3000
+#define VSOMEIP_SD_DEFAULT_REPETITIONS_BASE_DELAY 10
+#define VSOMEIP_SD_DEFAULT_REPETITIONS_MAX 3
+#define VSOMEIP_SD_DEFAULT_TTL 5
+#define VSOMEIP_SD_DEFAULT_CYCLIC_OFFER_DELAY 1000
+#define VSOMEIP_SD_DEFAULT_REQUEST_RESPONSE_DELAY 2000
#endif // VSOMEIP_SD_DEFINES_HPP
diff --git a/implementation/service_discovery/include/entry_impl.hpp b/implementation/service_discovery/include/entry_impl.hpp
index 2da3a5f..fde425c 100755
--- a/implementation/service_discovery/include/entry_impl.hpp
+++ b/implementation/service_discovery/include/entry_impl.hpp
@@ -10,12 +10,12 @@
#include <vector>
#include <vsomeip/primitive_types.hpp>
-#include <vsomeip/serializable.hpp>
+#include <vsomeip/internal/serializable.hpp>
#include "enumeration_types.hpp"
#include "message_element_impl.hpp"
-#define VSOMEIP_MAX_OPTION_RUN 2
+#define VSOMEIP_MAX_OPTION_RUN 2
namespace vsomeip {
@@ -57,6 +57,8 @@ public:
virtual bool serialize(vsomeip::serializer *_to) const;
virtual bool deserialize(vsomeip::deserializer *_from);
+ uint8_t get_num_options(uint8_t _run) const;
+
protected:
entry_type_e type_;
service_t service_;
@@ -66,6 +68,8 @@ protected:
std::vector<uint8_t> options_[VSOMEIP_MAX_OPTION_RUN];
+ uint8_t num_options_[VSOMEIP_MAX_OPTION_RUN];
+
entry_impl();
entry_impl(const entry_impl &entry_);
};
diff --git a/implementation/service_discovery/include/enumeration_types.hpp b/implementation/service_discovery/include/enumeration_types.hpp
index 8584bca..016fdae 100644
--- a/implementation/service_discovery/include/enumeration_types.hpp
+++ b/implementation/service_discovery/include/enumeration_types.hpp
@@ -39,6 +39,13 @@ enum class entry_type_e
UNKNOWN = 0xFF
};
+enum class layer_four_protocol_e
+ : uint8_t {
+ TCP = 0x06,
+ UDP = 0x11,
+ UNKNOWN = 0xFF
+};
+
} // namespace sd
} // namespace vsomeip
diff --git a/implementation/service_discovery/include/ip_option_impl.hpp b/implementation/service_discovery/include/ip_option_impl.hpp
new file mode 100644
index 0000000..8fd426b
--- /dev/null
+++ b/implementation/service_discovery/include/ip_option_impl.hpp
@@ -0,0 +1,41 @@
+// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef VSOMEIP_SD_IP_OPTION_IMPL_HPP
+#define VSOMEIP_SD_IP_OPTION_IMPL_HPP
+
+#include <vsomeip/primitive_types.hpp>
+
+#include "option_impl.hpp"
+
+namespace vsomeip {
+namespace sd {
+
+class ip_option_impl: public option_impl {
+public:
+ ip_option_impl();
+ virtual ~ip_option_impl();
+ bool operator ==(const option_impl &_option) const;
+
+ uint16_t get_port() const;
+ void set_port(uint16_t _port);
+
+ layer_four_protocol_e get_layer_four_protocol() const;
+ void set_layer_four_protocol(layer_four_protocol_e _protocol);
+
+ bool is_multicast() const;
+
+ virtual bool serialize(vsomeip::serializer *_to) const = 0;
+ virtual bool deserialize(vsomeip::deserializer *_from) = 0;
+
+protected:
+ layer_four_protocol_e protocol_;
+ uint16_t port_;
+};
+
+} // namespace sd
+} // namespace vsomeip
+
+#endif // VSOMEIP_SD_IP_OPTION_IMPL_HPP
diff --git a/implementation/service_discovery/include/ipv4_option_impl.hpp b/implementation/service_discovery/include/ipv4_option_impl.hpp
index 179d82f..b8051cc 100644
--- a/implementation/service_discovery/include/ipv4_option_impl.hpp
+++ b/implementation/service_discovery/include/ipv4_option_impl.hpp
@@ -8,35 +8,24 @@
#include <vsomeip/primitive_types.hpp>
-#include "option_impl.hpp"
+#include "ip_option_impl.hpp"
namespace vsomeip {
namespace sd {
-class ipv4_option_impl: public option_impl {
+class ipv4_option_impl: public ip_option_impl {
public:
ipv4_option_impl(bool _is_multicast);
virtual ~ipv4_option_impl();
- bool operator ==(const option_impl &_option) const;
const ipv4_address_t & get_address() const;
void set_address(const ipv4_address_t &_address);
- unsigned short get_port() const;
- void set_port(unsigned short _port);
-
- bool is_udp() const;
- void set_udp(bool _is_udp);
-
- bool is_multicast() const;
-
bool serialize(vsomeip::serializer *_to) const;
bool deserialize(vsomeip::deserializer *_from);
-protected:
+private:
ipv4_address_t address_;
- unsigned short port_;
- bool is_udp_;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/ipv6_option_impl.hpp b/implementation/service_discovery/include/ipv6_option_impl.hpp
index f1a7a1c..48938b0 100644
--- a/implementation/service_discovery/include/ipv6_option_impl.hpp
+++ b/implementation/service_discovery/include/ipv6_option_impl.hpp
@@ -6,39 +6,26 @@
#ifndef VSOMEIP_SD_IPV6_OPTION_IMPL_HPP
#define VSOMEIP_SD_IPV6_OPTION_IMPL_HPP
-#include <vector>
-
#include <vsomeip/primitive_types.hpp>
-#include "option_impl.hpp"
+#include "ip_option_impl.hpp"
namespace vsomeip {
namespace sd {
-class ipv6_option_impl: public option_impl {
+class ipv6_option_impl: public ip_option_impl {
public:
ipv6_option_impl(bool _is_multicast);
virtual ~ipv6_option_impl();
- bool operator ==(const option_impl &_option) const;
const ipv6_address_t & get_address() const;
void set_address(const ipv6_address_t &_address);
- unsigned short get_port() const;
- void set_port(unsigned short _port);
-
- bool is_udp() const;
- void set_udp(bool _is_udp);
-
- bool is_multicast() const;
-
bool serialize(vsomeip::serializer *_to) const;
bool deserialize(vsomeip::deserializer *_from);
-protected:
+private:
ipv6_address_t address_;
- unsigned short port_;
- bool is_udp_;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/message_impl.hpp b/implementation/service_discovery/include/message_impl.hpp
index e471ace..b0702df 100755
--- a/implementation/service_discovery/include/message_impl.hpp
+++ b/implementation/service_discovery/include/message_impl.hpp
@@ -55,6 +55,7 @@ public:
const std::vector<std::shared_ptr<option_impl> > & get_options() const;
int16_t get_option_index(const std::shared_ptr<option_impl> &_option) const;
+ uint32_t get_options_length();
std::shared_ptr<payload> get_payload() const;
void set_payload(std::shared_ptr<payload> _payload);
@@ -68,6 +69,7 @@ private:
private:
flags_t flags_;
+ uint32_t options_length_;
std::vector<std::shared_ptr<entry_impl> > entries_;
std::vector<std::shared_ptr<option_impl> > options_;
diff --git a/implementation/service_discovery/include/service_discovery.hpp b/implementation/service_discovery/include/service_discovery.hpp
index 0d10388..38b414f 100644
--- a/implementation/service_discovery/include/service_discovery.hpp
+++ b/implementation/service_discovery/include/service_discovery.hpp
@@ -35,13 +35,14 @@ public:
virtual void subscribe(service_t _service, instance_t _instance,
eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl, client_t _client) = 0;
virtual void unsubscribe(service_t _service, instance_t _instance,
- eventgroup_t _eventgroup) = 0;
+ eventgroup_t _eventgroup, client_t _client) = 0;
+ virtual void unsubscribe_all(service_t _service, instance_t _instance) = 0;
- virtual void send(const std::string &_name, bool _is_announcing) = 0;
+ virtual void send(bool _is_announcing) = 0;
virtual void on_message(const byte_t *_data, length_t _length) = 0;
- virtual void on_offer_change(const std::string &_name) = 0;
+ virtual void on_offer_change() = 0;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/service_discovery_fsm.hpp b/implementation/service_discovery/include/service_discovery_fsm.hpp
index d731b0b..f3fe7fd 100644
--- a/implementation/service_discovery/include/service_discovery_fsm.hpp
+++ b/implementation/service_discovery/include/service_discovery_fsm.hpp
@@ -43,8 +43,8 @@ struct fsm: sc::state_machine<fsm, inactive>, public fsm_base {
void timer_expired(const boost::system::error_code &_error);
uint32_t initial_delay_;
- uint32_t repetition_base_delay_;
- uint8_t repetition_max_;
+ uint32_t repetitions_base_delay_;
+ uint8_t repetitions_max_;
uint32_t cyclic_offer_delay_;
bool is_up_;
@@ -116,10 +116,7 @@ struct announce: sc::state<announce, active> {
class service_discovery_fsm: public std::enable_shared_from_this<
service_discovery_fsm> {
public:
- service_discovery_fsm(const std::string &_name,
- std::shared_ptr<service_discovery> _discovery);
-
- const std::string & get_name() const;
+ service_discovery_fsm(std::shared_ptr<service_discovery> _discovery);
void start();
void stop();
@@ -132,8 +129,6 @@ public:
}
private:
- std::string name_;
-
std::weak_ptr<service_discovery> discovery_;
std::shared_ptr<_sd::fsm> fsm_;
diff --git a/implementation/service_discovery/include/service_discovery_host.hpp b/implementation/service_discovery/include/service_discovery_host.hpp
index f9ad9e5..de1dd93 100644
--- a/implementation/service_discovery/include/service_discovery_host.hpp
+++ b/implementation/service_discovery/include/service_discovery_host.hpp
@@ -30,10 +30,10 @@ public:
virtual boost::asio::io_service & get_io() = 0;
virtual std::shared_ptr<configuration> get_configuration() const = 0;
- virtual void create_service_discovery_endpoint(const std::string &_address,
- uint16_t _port, bool _reliable) = 0;
+ virtual std::shared_ptr<endpoint> create_service_discovery_endpoint(
+ const std::string &_address, uint16_t _port, bool _reliable) = 0;
- virtual services_t get_offered_services(const std::string &_name) const = 0;
+ virtual services_t get_offered_services() const = 0;
virtual std::shared_ptr<eventgroupinfo> find_eventgroup(service_t _service,
instance_t _instance, eventgroup_t _eventgroup) const = 0;
@@ -45,11 +45,15 @@ public:
virtual void add_routing_info(service_t _service, instance_t _instance,
major_version_t _major, minor_version_t _minor, ttl_t _ttl,
- const boost::asio::ip::address &_address, uint16_t _port,
- bool _reliable) = 0;
+ const boost::asio::ip::address &_reliable_address,
+ uint16_t _reliable_port,
+ const boost::asio::ip::address &_unreliable_address,
+ uint16_t _unreliable_port) = 0;
virtual void del_routing_info(service_t _service, instance_t _instance,
- bool _reliable) = 0;
+ bool _has_reliable, bool _has_unreliable) = 0;
+
+ virtual ttl_t update_routing_info(ttl_t _elapsed) = 0;
virtual void on_subscribe(service_t _service, instance_t _instance,
eventgroup_t _eventgroup,
diff --git a/implementation/service_discovery/include/service_discovery_impl.hpp b/implementation/service_discovery/include/service_discovery_impl.hpp
index d07698e..0aceb02 100644
--- a/implementation/service_discovery/include/service_discovery_impl.hpp
+++ b/implementation/service_discovery/include/service_discovery_impl.hpp
@@ -11,10 +11,12 @@
#include <mutex>
#include <set>
+#include <boost/asio/system_timer.hpp>
#include <boost/asio/ip/address.hpp>
#include "service_discovery.hpp"
#include "../../routing/include/types.hpp"
+#include "ip_option_impl.hpp"
namespace vsomeip {
@@ -54,13 +56,14 @@ public:
void subscribe(service_t _service, instance_t _instance,
eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl, client_t _client);
void unsubscribe(service_t _service, instance_t _instance,
- eventgroup_t _eventgroup);
+ eventgroup_t _eventgroup, client_t _client);
+ void unsubscribe_all(service_t _service, instance_t _instance);
- void send(const std::string &_name, bool _is_announcing);
+ void send(bool _is_announcing);
void on_message(const byte_t *_data, length_t _length);
- void on_offer_change(const std::string &_name);
+ void on_offer_change();
private:
session_t get_session(const boost::asio::ip::address &_address);
@@ -74,22 +77,39 @@ private:
requests_t &_requests);
void insert_offer_entries(std::shared_ptr<message_impl> &_message,
services_t &_services);
+ void insert_offer_service(std::shared_ptr<message_impl> _message,
+ service_t _service, instance_t _instance,
+ const std::shared_ptr<const serviceinfo> &_info);
void insert_subscription(std::shared_ptr<message_impl> &_message,
service_t _service, instance_t _instance, eventgroup_t _eventgroup,
std::shared_ptr<subscription> &_subscription);
void insert_subscription_ack(std::shared_ptr<message_impl> &_message,
service_t _service, instance_t _instance, eventgroup_t _eventgroup,
+ std::shared_ptr<eventgroupinfo> &_info, ttl_t _ttl);
+ void insert_subscription_nack(std::shared_ptr<message_impl> &_message, service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup,
std::shared_ptr<eventgroupinfo> &_info);
void process_serviceentry(std::shared_ptr<serviceentry_impl> &_entry,
const std::vector<std::shared_ptr<option_impl> > &_options);
+ void process_offerservice_serviceentry(
+ service_t _service, instance_t _instance, major_version_t _major,
+ minor_version_t _minor, ttl_t _ttl,
+ const boost::asio::ip::address &_reliable_address,
+ uint16_t _reliable_port,
+ const boost::asio::ip::address &_unreliable_address,
+ uint16_t _unreliable_port);
+ void send_unicast_offer_service(const std::shared_ptr<const serviceinfo>& _info,
+ service_t _service, instance_t _instance,
+ major_version_t _major,
+ minor_version_t _minor);
+ void process_findservice_serviceentry(service_t _service,
+ instance_t _instance,
+ major_version_t _major,
+ minor_version_t _minor);
void process_eventgroupentry(std::shared_ptr<eventgroupentry_impl> &_entry,
const std::vector<std::shared_ptr<option_impl> > &_options);
- void handle_service_availability(service_t _service, instance_t _instance,
- major_version_t _major, minor_version_t _minor, ttl_t _ttl,
- const boost::asio::ip::address &_address, uint16_t _port,
- bool _reliable);
void handle_eventgroup_subscription(service_t _service,
instance_t _instance, eventgroup_t _eventgroup,
major_version_t _major, ttl_t _ttl,
@@ -99,6 +119,21 @@ private:
instance_t _instance, eventgroup_t _eventgroup,
major_version_t _major, ttl_t _ttl,
const boost::asio::ip::address &_address, uint16_t _port);
+ void serialize_and_send(std::shared_ptr<message_impl> _message,
+ const boost::asio::ip::address &_address);
+
+ void start_ttl_timer();
+ ttl_t stop_ttl_timer();
+ void check_ttl(const boost::system::error_code &_error);
+ boost::asio::ip::address get_current_remote_address() const;
+ bool check_static_header_fields(
+ const std::shared_ptr<const message> &_message) const;
+ void send_eventgroup_subscription_nack(service_t _service,
+ instance_t _instance,
+ eventgroup_t _eventgroup,
+ major_version_t _major);
+ bool check_layer_four_protocol(
+ const std::shared_ptr<const ip_option_impl> _ip_option) const;
private:
boost::asio::io_service &io_;
@@ -107,6 +142,7 @@ private:
boost::asio::ip::address unicast_;
uint16_t port_;
bool reliable_;
+ std::shared_ptr<endpoint> endpoint_;
std::shared_ptr<serializer> serializer_;
std::shared_ptr<deserializer> deserializer_;
@@ -119,6 +155,7 @@ private:
std::map<service_t,
std::map<instance_t,
std::map<eventgroup_t, std::map<client_t, std::shared_ptr<subscription> > > > > subscribed_;
+ std::mutex subscribed_mutex_;
std::mutex serialize_mutex_;
@@ -127,6 +164,11 @@ private:
// Runtime
std::weak_ptr<runtime> runtime_;
+
+ // TTL handling
+ boost::asio::system_timer ttl_timer_;
+ ttl_t smallest_ttl_;
+ ttl_t ttl_;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/subscription.hpp b/implementation/service_discovery/include/subscription.hpp
index c710b9d..bda9698 100644
--- a/implementation/service_discovery/include/subscription.hpp
+++ b/implementation/service_discovery/include/subscription.hpp
@@ -20,8 +20,7 @@ class subscription {
public:
subscription(major_version_t _major, ttl_t _ttl,
std::shared_ptr<endpoint> _reliable,
- std::shared_ptr<endpoint> _unreliable,
- client_t _target);
+ std::shared_ptr<endpoint> _unreliable);
~subscription();
major_version_t get_major() const;
@@ -30,7 +29,7 @@ public:
std::shared_ptr<endpoint> get_endpoint(bool _reliable) const;
void set_endpoint(std::shared_ptr<endpoint> _endpoint, bool _reliable);
- bool is_acknowleged() const;
+ bool is_acknowledged() const;
void set_acknowledged(bool _is_acknowledged);
private:
diff --git a/implementation/service_discovery/src/configuration_option_impl.cpp b/implementation/service_discovery/src/configuration_option_impl.cpp
index e6092da..67a9d4c 100755
--- a/implementation/service_discovery/src/configuration_option_impl.cpp
+++ b/implementation/service_discovery/src/configuration_option_impl.cpp
@@ -33,13 +33,13 @@ bool configuration_option_impl::operator ==(const option_impl &_other) const {
void configuration_option_impl::add_item(const std::string &_key,
const std::string &_value) {
configuration_[_key] = _value;
- length_ += (_key.length() + _value.length() + 2); // +2 for the '=' and length
+ length_ = uint16_t(length_ + _key.length() + _value.length() + 2u); // +2 for the '=' and length
}
void configuration_option_impl::remove_item(const std::string &_key) {
auto it = configuration_.find(_key);
if (it != configuration_.end()) {
- length_ -= (it->first.length() + it->second.length() + 2);
+ length_ = uint16_t(length_ - (it->first.length() + it->second.length() + 2u));
configuration_.erase(it);
}
}
@@ -72,7 +72,7 @@ bool configuration_option_impl::serialize(vsomeip::serializer *_to) const {
std::string configuration_string;
for (auto i = configuration_.begin(); i != configuration_.end(); ++i) {
- char l_length = 1 + i->first.length() + i->second.length();
+ char l_length = char(1 + i->first.length() + i->second.length());
configuration_string.push_back(l_length);
configuration_string.append(i->first);
configuration_string.push_back('=');
@@ -84,7 +84,7 @@ bool configuration_option_impl::serialize(vsomeip::serializer *_to) const {
if (is_successful) {
is_successful = _to->serialize(
reinterpret_cast<const uint8_t*>(configuration_string.c_str()),
- configuration_string.length());
+ uint32_t(configuration_string.length()));
}
return is_successful;
diff --git a/implementation/service_discovery/src/entry_impl.cpp b/implementation/service_discovery/src/entry_impl.cpp
index 735f120..ea7a511 100755
--- a/implementation/service_discovery/src/entry_impl.cpp
+++ b/implementation/service_discovery/src/entry_impl.cpp
@@ -20,6 +20,8 @@ entry_impl::entry_impl() {
service_ = 0x0;
instance_ = 0x0;
ttl_ = 0x0;
+ num_options_[0] = 0;
+ num_options_[1] = 0;
}
entry_impl::entry_impl(const entry_impl &_entry) {
@@ -28,6 +30,8 @@ entry_impl::entry_impl(const entry_impl &_entry) {
service_ = _entry.service_;
instance_ = _entry.instance_;
ttl_ = _entry.ttl_;
+ num_options_[0] = _entry.num_options_[0];
+ num_options_[1] = _entry.num_options_[1];
}
entry_impl::~entry_impl() {
@@ -86,7 +90,7 @@ void entry_impl::assign_option(const std::shared_ptr<option_impl> &_option,
if (_run > 0 && _run <= VSOMEIP_MAX_OPTION_RUN) {
_run--; // Index = Run-1
- uint8_t option_index = get_owning_message()->get_option_index(_option);
+ uint8_t option_index = uint8_t(get_owning_message()->get_option_index(_option));
if (0x10 > option_index) { // as we have only a nibble for the option counter
options_[_run].push_back(option_index);
std::sort(options_[_run].begin(), options_[_run].end());
@@ -112,7 +116,7 @@ bool entry_impl::serialize(vsomeip::serializer *_to) const {
index_second_option_run = options_[1][0];
is_successful = is_successful && _to->serialize(index_second_option_run);
- uint8_t number_of_options = ((((uint8_t) options_[0].size()) << 4)
+ uint8_t number_of_options = uint8_t((((uint8_t) options_[0].size()) << 4)
| (((uint8_t) options_[1].size()) & 0x0F));
is_successful = is_successful && _to->serialize(number_of_options);
@@ -128,7 +132,7 @@ bool entry_impl::serialize(vsomeip::serializer *_to) const {
bool entry_impl::deserialize(vsomeip::deserializer *_from) {
bool is_successful = (0 != _from);
- uint8_t its_type;
+ uint8_t its_type(0);
is_successful = is_successful && _from->deserialize(its_type);
type_ = static_cast<entry_type_e>(its_type);
@@ -141,13 +145,13 @@ bool entry_impl::deserialize(vsomeip::deserializer *_from) {
uint8_t its_numbers;
is_successful = is_successful && _from->deserialize(its_numbers);
- uint8_t its_numbers1 = (its_numbers >> 4);
- uint8_t its_numbers2 = (its_numbers & 0xF);
+ num_options_[0] = uint8_t(its_numbers >> 4);
+ num_options_[1] = uint8_t(its_numbers & 0xF);
- for (uint8_t i = its_index1; i < its_index1 + its_numbers1; ++i)
+ for (uint8_t i = its_index1; i < its_index1 + num_options_[0]; ++i)
options_[0].push_back(i);
- for (uint8_t i = its_index2; i < its_index2 + its_numbers2; ++i)
+ for (uint8_t i = its_index2; i < its_index2 + num_options_[1]; ++i)
options_[1].push_back(i);
uint16_t its_id;
@@ -169,5 +173,12 @@ bool entry_impl::is_eventgroup_entry() const {
&& type_ <= entry_type_e::SUBSCRIBE_EVENTGROUP_ACK);
}
+uint8_t entry_impl::get_num_options(uint8_t _run) const {
+ if (_run < 1 || _run > VSOMEIP_MAX_OPTION_RUN) {
+ return 0x0;
+ }
+ return num_options_[_run-1];
+}
+
} // namespace sd
} // namespace vsomeip
diff --git a/implementation/service_discovery/src/eventgroupentry_impl.cpp b/implementation/service_discovery/src/eventgroupentry_impl.cpp
index ba303d9..024756d 100755
--- a/implementation/service_discovery/src/eventgroupentry_impl.cpp
+++ b/implementation/service_discovery/src/eventgroupentry_impl.cpp
@@ -34,7 +34,7 @@ void eventgroupentry_impl::set_eventgroup(eventgroup_t _eventgroup) {
bool eventgroupentry_impl::serialize(vsomeip::serializer *_to) const {
bool is_successful = entry_impl::serialize(_to);
- is_successful = is_successful && _to->serialize(protocol::reserved_byte);
+ is_successful = is_successful && _to->serialize(major_version_);
is_successful = is_successful
&& _to->serialize(static_cast<uint32_t>(ttl_), true);
@@ -50,8 +50,9 @@ bool eventgroupentry_impl::serialize(vsomeip::serializer *_to) const {
bool eventgroupentry_impl::deserialize(vsomeip::deserializer *_from) {
bool is_successful = entry_impl::deserialize(_from);
- uint8_t its_reserved0;
- is_successful = is_successful && _from->deserialize(its_reserved0);
+ uint8_t tmp_major_version;
+ is_successful = is_successful && _from->deserialize(tmp_major_version);
+ major_version_ = static_cast<major_version_t>(tmp_major_version);
uint32_t its_ttl;
is_successful = is_successful && _from->deserialize(its_ttl, true);
diff --git a/implementation/service_discovery/src/ip_option_impl.cpp b/implementation/service_discovery/src/ip_option_impl.cpp
new file mode 100644
index 0000000..3fcffac
--- /dev/null
+++ b/implementation/service_discovery/src/ip_option_impl.cpp
@@ -0,0 +1,59 @@
+// Copyright (C) 2014-2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <vsomeip/constants.hpp>
+
+#include "../include/constants.hpp"
+#include "../include/ip_option_impl.hpp"
+#include "../../message/include/deserializer.hpp"
+#include "../../message/include/serializer.hpp"
+
+namespace vsomeip {
+namespace sd {
+
+ip_option_impl::ip_option_impl() :
+ protocol_(layer_four_protocol_e::UNKNOWN),
+ port_(0xFFFF) {
+}
+
+ip_option_impl::~ip_option_impl() {
+}
+
+bool ip_option_impl::operator ==(const option_impl &_other) const {
+ if (type_ != _other.get_type())
+ return false;
+
+#ifdef VSOMEIP_TODO
+ const ip_option_impl & other =
+ dynamic_cast<const ip_option_impl &>(_other);
+#endif
+ return true;
+}
+
+unsigned short ip_option_impl::get_port() const {
+ return port_;
+}
+
+void ip_option_impl::set_port(unsigned short _port) {
+ port_ = _port;
+}
+
+layer_four_protocol_e ip_option_impl::get_layer_four_protocol() const {
+ return protocol_;
+}
+
+void ip_option_impl::set_layer_four_protocol(
+ layer_four_protocol_e _protocol) {
+ protocol_ = _protocol;
+}
+
+bool ip_option_impl::is_multicast() const {
+ return (type_ == option_type_e::IP4_MULTICAST
+ || type_ == option_type_e::IP6_MULTICAST);
+}
+
+} // namespace sd
+} // namespace vsomeip
+
diff --git a/implementation/service_discovery/src/ipv4_option_impl.cpp b/implementation/service_discovery/src/ipv4_option_impl.cpp
index 6416cf0..ca5a2c5 100644
--- a/implementation/service_discovery/src/ipv4_option_impl.cpp
+++ b/implementation/service_discovery/src/ipv4_option_impl.cpp
@@ -13,26 +13,17 @@
namespace vsomeip {
namespace sd {
-ipv4_option_impl::ipv4_option_impl(bool _is_multicast) {
+ipv4_option_impl::ipv4_option_impl(bool _is_multicast) :
+ address_({0}) {
length_ = (1 + 4 + 1 + 1 + 2);
type_ = (
_is_multicast ?
option_type_e::IP4_MULTICAST : option_type_e::IP4_ENDPOINT);
- is_udp_ = _is_multicast;
}
ipv4_option_impl::~ipv4_option_impl() {
}
-bool ipv4_option_impl::operator ==(const option_impl &_other) const {
- if (type_ != _other.get_type())
- return false;
-
- const ipv4_option_impl & other =
- dynamic_cast<const ipv4_option_impl &>(_other);
- return true;
-}
-
const ipv4_address_t & ipv4_option_impl::get_address() const {
return address_;
}
@@ -41,31 +32,11 @@ void ipv4_option_impl::set_address(const ipv4_address_t &_address) {
address_ = _address;
}
-unsigned short ipv4_option_impl::get_port() const {
- return port_;
-}
-
-void ipv4_option_impl::set_port(unsigned short _port) {
- port_ = _port;
-}
-
-bool ipv4_option_impl::is_udp() const {
- return is_udp_;
-}
-
-void ipv4_option_impl::set_udp(bool _is_udp) {
- is_udp_ = _is_udp;
-}
-
-bool ipv4_option_impl::is_multicast() const {
- return (type_ == option_type_e::IP4_MULTICAST);
-}
-
bool ipv4_option_impl::serialize(vsomeip::serializer *_to) const {
bool is_successful = option_impl::serialize(_to);
- _to->serialize(&address_[0], address_.size());
+ _to->serialize(&address_[0], uint32_t(address_.size()));
_to->serialize(protocol::reserved_byte);
- _to->serialize(is_udp_ ? protocol::udp : protocol::tcp);
+ _to->serialize(static_cast<uint8_t>(protocol_));
_to->serialize(port_);
return is_successful;
}
@@ -76,7 +47,14 @@ bool ipv4_option_impl::deserialize(vsomeip::deserializer *_from) {
_from->deserialize(address_.data(), 4);
_from->deserialize(its_reserved);
_from->deserialize(its_reserved);
- is_udp_ = (protocol::udp == its_reserved);
+ switch (static_cast<layer_four_protocol_e>(its_reserved)) {
+ case layer_four_protocol_e::TCP:
+ case layer_four_protocol_e::UDP:
+ protocol_ = static_cast<layer_four_protocol_e>(its_reserved);
+ break;
+ default:
+ protocol_ = layer_four_protocol_e::UNKNOWN;
+ }
_from->deserialize(port_);
return is_successful;
}
diff --git a/implementation/service_discovery/src/ipv6_option_impl.cpp b/implementation/service_discovery/src/ipv6_option_impl.cpp
index 556045c..1aa2570 100755
--- a/implementation/service_discovery/src/ipv6_option_impl.cpp
+++ b/implementation/service_discovery/src/ipv6_option_impl.cpp
@@ -13,27 +13,17 @@
namespace vsomeip {
namespace sd {
-ipv6_option_impl::ipv6_option_impl(bool _is_multicast) {
+ipv6_option_impl::ipv6_option_impl(bool _is_multicast) :
+ address_({0}) {
length_ = (1 + 16 + 1 + 1 + 2);
type_ = (
_is_multicast ?
option_type_e::IP6_MULTICAST : option_type_e::IP6_ENDPOINT);
- is_udp_ = _is_multicast;
}
ipv6_option_impl::~ipv6_option_impl() {
}
-bool ipv6_option_impl::operator ==(const option_impl &_other) const {
- if (_other.get_type() != option_type_e::IP6_ENDPOINT)
- return false;
-
- const ipv6_option_impl& other =
- dynamic_cast<const ipv6_option_impl &>(_other);
-
- return true; // TODO:
-}
-
const ipv6_address_t & ipv6_option_impl::get_address() const {
return address_;
}
@@ -42,27 +32,11 @@ void ipv6_option_impl::set_address(const ipv6_address_t &_address) {
address_ = _address;
}
-unsigned short ipv6_option_impl::get_port() const {
- return port_;
-}
-
-void ipv6_option_impl::set_port(unsigned short _port) {
- port_ = _port;
-}
-
-bool ipv6_option_impl::is_udp() const {
- return is_udp_;
-}
-
-void ipv6_option_impl::set_udp(bool _is_udp) {
- is_udp_ = _is_udp;
-}
-
bool ipv6_option_impl::serialize(vsomeip::serializer *_to) const {
bool is_successful = option_impl::serialize(_to);
- _to->serialize(&address_[0], address_.size());
+ _to->serialize(&address_[0], uint32_t(address_.size()));
_to->serialize(protocol::reserved_byte);
- _to->serialize(is_udp_ ? protocol::udp : protocol::tcp);
+ _to->serialize(static_cast<uint8_t>(protocol_));
_to->serialize(port_);
return is_successful;
}
@@ -73,7 +47,14 @@ bool ipv6_option_impl::deserialize(vsomeip::deserializer *_from) {
_from->deserialize(address_.data(), 16);
_from->deserialize(its_reserved);
_from->deserialize(its_reserved);
- is_udp_ = (protocol::udp == its_reserved);
+ switch (static_cast<layer_four_protocol_e>(its_reserved)) {
+ case layer_four_protocol_e::TCP:
+ case layer_four_protocol_e::UDP:
+ protocol_ = static_cast<layer_four_protocol_e>(its_reserved);
+ break;
+ default:
+ protocol_ = layer_four_protocol_e::UNKNOWN;
+ }
_from->deserialize(port_);
return is_successful;
}
diff --git a/implementation/service_discovery/src/message_impl.cpp b/implementation/service_discovery/src/message_impl.cpp
index 6736b50..3130dda 100755
--- a/implementation/service_discovery/src/message_impl.cpp
+++ b/implementation/service_discovery/src/message_impl.cpp
@@ -7,7 +7,6 @@
#include <vsomeip/constants.hpp>
#include <vsomeip/defines.hpp>
-#include <vsomeip/logger.hpp>
#include "../include/constants.hpp"
#include "../include/defines.hpp"
@@ -19,6 +18,7 @@
#include "../include/load_balancing_option_impl.hpp"
#include "../include/protection_option_impl.hpp"
#include "../include/message_impl.hpp"
+#include "../../logging/include/logger.hpp"
#include "../../message/include/deserializer.hpp"
#include "../../message/include/payload_impl.hpp"
#include "../../message/include/serializer.hpp"
@@ -31,15 +31,16 @@ message_impl::message_impl() {
header_.method_ = 0x8100;
header_.protocol_version_ = 0x01;
flags_ = 0x00;
+ options_length_ = 0x0000;
}
message_impl::~message_impl() {
}
length_t message_impl::get_length() const {
- length_t current_length = VSOMEIP_SOMEIP_HEADER_SIZE
- + VSOMEIP_SOMEIP_SD_DATA_SIZE;
- current_length += (entries_.size() * VSOMEIP_SOMEIP_SD_ENTRY_SIZE);
+ length_t current_length = (VSOMEIP_SOMEIP_HEADER_SIZE
+ + VSOMEIP_SOMEIP_SD_DATA_SIZE);
+ current_length += uint32_t(entries_.size() * VSOMEIP_SOMEIP_SD_ENTRY_SIZE);
for (size_t i = 0; i < options_.size(); ++i) {
current_length += (options_[i]->get_length()
+ VSOMEIP_SOMEIP_SD_OPTION_HEADER_SIZE);
@@ -55,9 +56,9 @@ bool message_impl::get_reboot_flag() const {
void message_impl::set_reboot_flag(bool _is_set) {
if (_is_set)
- flags_ |= VSOMEIP_REBOOT_FLAG;
+ flags_ |= flags_t(VSOMEIP_REBOOT_FLAG);
else
- flags_ &= ~VSOMEIP_REBOOT_FLAG;
+ flags_ &= flags_t(~VSOMEIP_REBOOT_FLAG);
}
#define VSOMEIP_UNICAST_FLAG 0x40
@@ -68,12 +69,13 @@ bool message_impl::get_unicast_flag() const {
void message_impl::set_unicast_flag(bool _is_set) {
if (_is_set)
- flags_ |= VSOMEIP_UNICAST_FLAG;
+ flags_ |= flags_t(VSOMEIP_UNICAST_FLAG);
else
- flags_ &= ~VSOMEIP_UNICAST_FLAG;
+ flags_ &= flags_t(~VSOMEIP_UNICAST_FLAG);
}
void message_impl::set_length(length_t _length) {
+ (void)_length;
}
std::shared_ptr<eventgroupentry_impl> message_impl::create_eventgroup_entry() {
@@ -154,7 +156,7 @@ int16_t message_impl::get_option_index(
const std::shared_ptr<option_impl> &_option) const {
int16_t i = 0;
- while (i < options_.size()) {
+ while (i < int16_t(options_.size())) {
if (options_[i] == _option)
return i;
i++;
@@ -163,11 +165,16 @@ int16_t message_impl::get_option_index(
return -1;
}
+uint32_t message_impl::get_options_length() {
+ return options_length_;
+}
+
std::shared_ptr<payload> message_impl::get_payload() const {
return std::make_shared<payload_impl>();
}
void message_impl::set_payload(std::shared_ptr<payload> _payload) {
+ (void)_payload;
}
bool message_impl::serialize(vsomeip::serializer *_to) const {
@@ -177,7 +184,7 @@ bool message_impl::serialize(vsomeip::serializer *_to) const {
is_successful = is_successful
&& _to->serialize(protocol::reserved_long, true);
- uint32_t entries_length = (entries_.size() * VSOMEIP_SOMEIP_SD_ENTRY_SIZE);
+ uint32_t entries_length = uint32_t(entries_.size() * VSOMEIP_SOMEIP_SD_ENTRY_SIZE);
is_successful = is_successful && _to->serialize(entries_length);
for (auto it = entries_.begin(); it != entries_.end(); ++it)
@@ -213,7 +220,7 @@ bool message_impl::deserialize(vsomeip::deserializer *_from) {
is_successful = is_successful && _from->deserialize(entries_length);
// backup the current remaining length
- uint32_t save_remaining = _from->get_remaining();
+ uint32_t save_remaining = uint32_t(_from->get_remaining());
// set remaining bytes to length of entries array
_from->set_remaining(entries_length);
@@ -231,9 +238,18 @@ bool message_impl::deserialize(vsomeip::deserializer *_from) {
// set length to remaining bytes after entries array
_from->set_remaining(save_remaining - entries_length);
+ // Don't try to deserialize options if there aren't any
+ if(_from->get_remaining() == 0) {
+ return is_successful;
+ }
+
// deserialize the options
- uint32_t options_length = 0;
- is_successful = is_successful && _from->deserialize(options_length);
+ is_successful = is_successful && _from->deserialize(options_length_);
+
+ // check if there is unreferenced data behind the last option and discard it
+ if(_from->get_remaining() > options_length_) {
+ _from->set_remaining(options_length_);
+ }
while (is_successful && _from->get_remaining()) {
std::shared_ptr < option_impl > its_option(deserialize_option(_from));
@@ -279,6 +295,7 @@ entry_impl * message_impl::deserialize_entry(vsomeip::deserializer *_from) {
// deserialize object
if (0 != deserialized_entry) {
+ deserialized_entry->set_owning_message(this);
if (!deserialized_entry->deserialize(_from)) {
delete deserialized_entry;
deserialized_entry = 0;
@@ -323,6 +340,7 @@ option_impl * message_impl::deserialize_option(vsomeip::deserializer *_from) {
break;
default:
+ deserialized_option = new option_impl();
break;
};
diff --git a/implementation/service_discovery/src/option_impl.cpp b/implementation/service_discovery/src/option_impl.cpp
index a9ac4a9..71bbc6a 100755
--- a/implementation/service_discovery/src/option_impl.cpp
+++ b/implementation/service_discovery/src/option_impl.cpp
@@ -20,6 +20,7 @@ option_impl::~option_impl() {
}
bool option_impl::operator ==(const option_impl &_other) const {
+ (void)_other;
return false;
}
@@ -43,7 +44,25 @@ bool option_impl::deserialize(vsomeip::deserializer *_from) {
&& _from->deserialize(its_type) && _from->deserialize(reserved));
if (l_result) {
- type_ = static_cast<option_type_e>(its_type);
+ switch(static_cast<option_type_e>(its_type)) {
+ case option_type_e::CONFIGURATION:
+ case option_type_e::LOAD_BALANCING:
+ case option_type_e::PROTECTION:
+ case option_type_e::IP4_ENDPOINT:
+ case option_type_e::IP6_ENDPOINT:
+ case option_type_e::IP4_MULTICAST:
+ case option_type_e::IP6_MULTICAST:
+ type_ = static_cast<option_type_e>(its_type);
+ 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));
+ }
}
return l_result;
diff --git a/implementation/service_discovery/src/service_discovery_fsm.cpp b/implementation/service_discovery/src/service_discovery_fsm.cpp
index 8b2cb17..d2428dd 100644
--- a/implementation/service_discovery/src/service_discovery_fsm.cpp
+++ b/implementation/service_discovery/src/service_discovery_fsm.cpp
@@ -6,12 +6,11 @@
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
-#include <vsomeip/configuration.hpp>
-#include <vsomeip/logger.hpp>
-
#include "../include/defines.hpp"
#include "../include/service_discovery.hpp"
#include "../include/service_discovery_fsm.hpp"
+#include "../../configuration/include/configuration.hpp"
+#include "../../logging/include/logger.hpp"
namespace vsomeip {
namespace sd {
@@ -48,12 +47,14 @@ inactive::inactive(my_context context)
std::shared_ptr < service_discovery_fsm > fsm =
outermost_context().fsm_.lock();
if (fsm) {
- VSOMEIP_TRACE << "sd<" << fsm->get_name() << ">::inactive";
+ VSOMEIP_TRACE << "sd::inactive";
outermost_context().run_ = 0;
}
}
sc::result inactive::react(const ev_none &_event) {
+ (void)_event;
+
if (outermost_context().is_up_) {
return transit<active>();
}
@@ -62,6 +63,8 @@ sc::result inactive::react(const ev_none &_event) {
}
sc::result inactive::react(const ev_status_change &_event) {
+ (void)_event;
+
outermost_context().is_up_ = _event.is_up_;
if (outermost_context().is_up_) {
return transit<active>();
@@ -78,7 +81,7 @@ active::active(my_context _context)
std::shared_ptr < service_discovery_fsm > fsm =
outermost_context().fsm_.lock();
if (fsm) {
- VSOMEIP_TRACE << "sd<" << fsm->get_name() << ">::active";
+ VSOMEIP_TRACE << "sd::active";
}
}
@@ -86,6 +89,8 @@ active::~active() {
}
sc::result active::react(const ev_status_change &_event) {
+ (void)_event;
+
outermost_context().stop_timer();
outermost_context().is_up_ = _event.is_up_;
if (!outermost_context().is_up_)
@@ -102,12 +107,13 @@ initial::initial(my_context _context)
std::shared_ptr < service_discovery_fsm > fsm =
outermost_context().fsm_.lock();
if (fsm) {
- VSOMEIP_TRACE << "sd<" << fsm->get_name() << ">::active.initial";
+ VSOMEIP_TRACE << "sd::active.initial";
outermost_context().start_timer(outermost_context().initial_delay_);
}
}
sc::result initial::react(const ev_timeout &_event) {
+ (void)_event;
return transit<repeat>();
}
@@ -119,8 +125,8 @@ repeat::repeat(my_context _context)
std::shared_ptr < service_discovery_fsm > fsm =
outermost_context().fsm_.lock();
if (fsm) {
- VSOMEIP_TRACE << "sd<" << fsm->get_name() << ">::active.repeat";
- uint32_t its_timeout = (outermost_context().repetition_base_delay_
+ VSOMEIP_TRACE << "sd::active.repeat";
+ uint32_t its_timeout = (outermost_context().repetitions_base_delay_
<< outermost_context().run_);
outermost_context().run_++;
fsm->send(false);
@@ -129,13 +135,16 @@ repeat::repeat(my_context _context)
}
sc::result repeat::react(const ev_timeout &_event) {
- if (outermost_context().run_ < outermost_context().repetition_max_)
+ (void)_event;
+
+ if (outermost_context().run_ < outermost_context().repetitions_max_)
return transit<repeat>();
return transit<announce>();
}
sc::result repeat::react(const ev_find_service &_event) {
+ (void)_event;
return discard_event();
}
@@ -147,7 +156,7 @@ announce::announce(my_context _context)
std::shared_ptr < service_discovery_fsm > fsm =
outermost_context().fsm_.lock();
if (fsm) {
- VSOMEIP_TRACE << "sd<" << fsm->get_name() << ">::active.announce";
+ VSOMEIP_TRACE << "sd::active.announce";
outermost_context().start_timer(
outermost_context().cyclic_offer_delay_);
fsm->send(true);
@@ -155,14 +164,17 @@ announce::announce(my_context _context)
}
sc::result announce::react(const ev_timeout &_event) {
+ (void)_event;
return transit<announce>();
}
sc::result announce::react(const ev_find_service &_event) {
+ (void)_event;
return discard_event();
}
sc::result announce::react(const ev_offer_change &_event) {
+ (void)_event;
return transit<announce>();
}
@@ -171,9 +183,9 @@ sc::result announce::react(const ev_offer_change &_event) {
///////////////////////////////////////////////////////////////////////////////
// Interface
///////////////////////////////////////////////////////////////////////////////
-service_discovery_fsm::service_discovery_fsm(const std::string &_name,
+service_discovery_fsm::service_discovery_fsm(
std::shared_ptr<service_discovery> _discovery)
- : name_(_name), discovery_(_discovery), fsm_(
+ : discovery_(_discovery), fsm_(
std::make_shared < _sd::fsm > (_discovery->get_io())) {
std::shared_ptr < service_discovery > discovery = discovery_.lock();
@@ -181,57 +193,54 @@ service_discovery_fsm::service_discovery_fsm(const std::string &_name,
std::shared_ptr < configuration > its_configuration =
discovery->get_configuration();
- int32_t its_min_initial_delay =
- its_configuration->get_min_initial_delay(name_);
- if (its_min_initial_delay < 0)
- its_min_initial_delay = VSOMEIP_SD_DEFAULT_MIN_INITIAL_DELAY;
+ int32_t its_initial_delay_min
+ = its_configuration->get_sd_initial_delay_min();
+ if (its_initial_delay_min < 0)
+ its_initial_delay_min = VSOMEIP_SD_DEFAULT_INITIAL_DELAY_MIN;
- int32_t its_max_initial_delay =
- its_configuration->get_max_initial_delay(name_);
- if (its_max_initial_delay <= 0)
- its_max_initial_delay = VSOMEIP_SD_DEFAULT_MAX_INITIAL_DELAY;
+ int32_t its_initial_delay_max
+ = its_configuration->get_sd_initial_delay_max();
+ if (its_initial_delay_max <= 0)
+ its_initial_delay_max = VSOMEIP_SD_DEFAULT_INITIAL_DELAY_MAX;
- if (its_min_initial_delay > its_max_initial_delay) {
- int32_t tmp_initial_delay = its_min_initial_delay;
- its_min_initial_delay = its_max_initial_delay;
- its_max_initial_delay = its_min_initial_delay;
+ if (its_initial_delay_min > its_initial_delay_max) {
+ int32_t tmp_initial_delay = its_initial_delay_min;
+ its_initial_delay_min = its_initial_delay_max;
+ its_initial_delay_max = tmp_initial_delay;
}
- VSOMEIP_TRACE << "Inital delay [" << its_min_initial_delay << ", "
- << its_max_initial_delay << "]";
+ VSOMEIP_TRACE << "Inital delay [" << its_initial_delay_min << ", "
+ << its_initial_delay_max << "]";
boost::random::mt19937 its_generator;
boost::random::uniform_int_distribution<> its_distribution(
- its_min_initial_delay, its_max_initial_delay);
+ its_initial_delay_min, its_initial_delay_max);
fsm_->initial_delay_ = its_distribution(its_generator);
- fsm_->repetition_base_delay_ =
- its_configuration->get_repetition_base_delay(name_);
- if (fsm_->repetition_base_delay_ <= 0)
- fsm_->repetition_base_delay_
- = VSOMEIP_SD_DEFAULT_REPETITION_BASE_DELAY;
- fsm_->repetition_max_ = its_configuration->get_repetition_max(name_);
- if (fsm_->repetition_max_ <= 0)
- fsm_->repetition_max_ = VSOMEIP_SD_DEFAULT_REPETITION_MAX;
-
- fsm_->cyclic_offer_delay_ =
- its_configuration->get_cyclic_offer_delay(name_);
+ fsm_->repetitions_base_delay_
+ = its_configuration->get_sd_repetitions_base_delay();
+ if (fsm_->repetitions_base_delay_ <= 0)
+ fsm_->repetitions_base_delay_
+ = VSOMEIP_SD_DEFAULT_REPETITIONS_BASE_DELAY;
+ fsm_->repetitions_max_
+ = its_configuration->get_sd_repetitions_max();
+ if (fsm_->repetitions_max_ <= 0)
+ fsm_->repetitions_max_ = VSOMEIP_SD_DEFAULT_REPETITIONS_MAX;
+
+ fsm_->cyclic_offer_delay_
+ = its_configuration->get_sd_cyclic_offer_delay();
if (fsm_->cyclic_offer_delay_ <= 0)
fsm_->cyclic_offer_delay_ = VSOMEIP_SD_DEFAULT_CYCLIC_OFFER_DELAY;
VSOMEIP_INFO << "SD configuration [" << fsm_->initial_delay_ << ":"
- << fsm_->repetition_base_delay_ << ":"
- << (int) fsm_->repetition_max_ << ":"
+ << fsm_->repetitions_base_delay_ << ":"
+ << (int) fsm_->repetitions_max_ << ":"
<< fsm_->cyclic_offer_delay_ << "]";
} else {
VSOMEIP_ERROR << "SD initialization failed";
}
}
-const std::string & service_discovery_fsm::get_name() const {
- return name_;
-}
-
void service_discovery_fsm::start() {
fsm_->set_fsm(shared_from_this());
fsm_->initiate();
@@ -243,7 +252,7 @@ void service_discovery_fsm::stop() {
void service_discovery_fsm::send(bool _is_announcing) {
std::shared_ptr < service_discovery > discovery = discovery_.lock();
if (discovery)
- discovery->send(name_, _is_announcing);
+ discovery->send(_is_announcing);
}
} // namespace sd
diff --git a/implementation/service_discovery/src/service_discovery_impl.cpp b/implementation/service_discovery/src/service_discovery_impl.cpp
index 42d93b6..38975fb 100644
--- a/implementation/service_discovery/src/service_discovery_impl.cpp
+++ b/implementation/service_discovery/src/service_discovery_impl.cpp
@@ -3,8 +3,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-#include <vsomeip/configuration.hpp>
-#include <vsomeip/logger.hpp>
+#include <vsomeip/constants.hpp>
#include "../include/constants.hpp"
#include "../include/defines.hpp"
@@ -21,23 +20,27 @@
#include "../include/service_discovery_impl.hpp"
#include "../include/serviceentry_impl.hpp"
#include "../include/subscription.hpp"
+#include "../../configuration/include/configuration.hpp"
#include "../../configuration/include/internal.hpp"
#include "../../endpoints/include/endpoint.hpp"
#include "../../endpoints/include/endpoint_definition.hpp"
#include "../../endpoints/include/tcp_server_endpoint_impl.hpp"
#include "../../endpoints/include/udp_server_endpoint_impl.hpp"
+#include "../../logging/include/logger.hpp"
#include "../../message/include/serializer.hpp"
#include "../../routing/include/eventgroupinfo.hpp"
-#include "../../routing/include/servicegroup.hpp"
#include "../../routing/include/serviceinfo.hpp"
namespace vsomeip {
namespace sd {
service_discovery_impl::service_discovery_impl(service_discovery_host *_host)
- : host_(_host), io_(_host->get_io()), serializer_(
- std::make_shared<serializer>()), deserializer_(
- std::make_shared<deserializer>()) {
+ : io_(_host->get_io()),
+ host_(_host),
+ serializer_(std::make_shared<serializer>()),
+ deserializer_(std::make_shared<deserializer>()),
+ ttl_timer_(_host->get_io()),
+ smallest_ttl_(DEFAULT_TTL) {
}
service_discovery_impl::~service_discovery_impl() {
@@ -53,27 +56,15 @@ boost::asio::io_service & service_discovery_impl::get_io() {
void service_discovery_impl::init() {
runtime_ = runtime::get();
- default_ = std::make_shared < service_discovery_fsm
- > ("default", shared_from_this());
+ default_ = std::make_shared<service_discovery_fsm>(shared_from_this());
std::shared_ptr < configuration > its_configuration =
host_->get_configuration();
if (its_configuration) {
- unicast_ = its_configuration->get_unicast();
-
- std::set < std::string > its_servicegroups =
- its_configuration->get_servicegroups();
- for (auto its_group : its_servicegroups) {
- if (its_group != "default"
- && its_configuration->is_local_servicegroup(its_group)) {
- additional_[its_group] = std::make_shared
- < service_discovery_fsm
- > (its_group, shared_from_this());
- }
- }
+ unicast_ = its_configuration->get_unicast_address();
- port_ = its_configuration->get_service_discovery_port();
- reliable_ = (its_configuration->get_service_discovery_protocol()
+ port_ = its_configuration->get_sd_port();
+ reliable_ = (its_configuration->get_sd_protocol()
== "tcp");
serializer_->create_data(
@@ -81,10 +72,10 @@ void service_discovery_impl::init() {
VSOMEIP_MAX_TCP_MESSAGE_SIZE :
VSOMEIP_MAX_UDP_MESSAGE_SIZE);
- host_->create_service_discovery_endpoint(
- its_configuration->get_service_discovery_multicast(), port_,
- reliable_);
+ endpoint_ = host_->create_service_discovery_endpoint(
+ its_configuration->get_sd_multicast(), port_, reliable_);
+ ttl_ = its_configuration->get_sd_ttl();
} else {
VSOMEIP_ERROR << "SD: no configuration found!";
}
@@ -134,6 +125,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) {
+ std::lock_guard<std::mutex> its_lock(subscribed_mutex_);
+
auto found_service = subscribed_.find(_service);
if (found_service != subscribed_.end()) {
auto found_instance = found_service->second.find(_instance);
@@ -155,70 +148,108 @@ 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, _client);
+ < subscription > (_major, _ttl, its_reliable, its_unreliable);
subscribed_[_service][_instance][_eventgroup][_client] = its_subscription;
- if (!its_subscription->is_acknowleged()) {
- bool has_address(false);
- boost::asio::ip::address its_address;
-
- std::shared_ptr<endpoint> its_endpoint
- = host_->find_or_create_remote_client(_service, _instance, false, _client);
+ bool has_address(false);
+ boost::asio::ip::address its_address;
- if (its_endpoint) {
- has_address = its_endpoint->get_remote_address(its_address);
- its_subscription->set_endpoint(its_endpoint, false);
- }
+ std::shared_ptr<endpoint> its_endpoint
+ = host_->find_or_create_remote_client(_service, _instance, false, _client);
- its_endpoint = host_->find_or_create_remote_client(_service, _instance, true, _client);
- if (its_endpoint) {
- has_address = has_address || its_endpoint->get_remote_address(its_address);
- its_subscription->set_endpoint(its_endpoint, true);
- }
+ if (its_endpoint) {
+ has_address = its_endpoint->get_remote_address(its_address);
+ its_subscription->set_endpoint(its_endpoint, false);
+ }
- if (has_address) {
- std::shared_ptr < runtime > its_runtime = runtime_.lock();
- if (!its_runtime)
- return;
+ 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);
+ }
- std::shared_ptr < message_impl > its_message
- = its_runtime->create_message();
+ if (has_address) {
+ std::shared_ptr<runtime> its_runtime = runtime_.lock();
+ if (!its_runtime)
+ return;
- // TODO: consume major & ttl
- insert_subscription(its_message, _service, _instance, _eventgroup,
- its_subscription);
- its_message->set_session(get_session(its_address));
+ std::shared_ptr<message_impl> its_message
+ = its_runtime->create_message();
- serializer_->serialize(its_message.get());
+ // TODO: consume major & ttl
+ insert_subscription(its_message, _service, _instance, _eventgroup,
+ its_subscription);
+ serialize_and_send(its_message, its_address);
- if (host_->send_to(
- std::make_shared<endpoint_definition>(
- its_address, port_, reliable_),
- serializer_->get_data(),
- serializer_->get_size())) {
- increment_session(its_address);
- }
- serializer_->reset();
- }
+ its_subscription->set_acknowledged(false);
}
}
void service_discovery_impl::unsubscribe(service_t _service,
- instance_t _instance, eventgroup_t _eventgroup) {
- // TODO: add client_id!!!
+ instance_t _instance, eventgroup_t _eventgroup, client_t _client) {
+
+ std::lock_guard<std::mutex> its_lock(subscribed_mutex_);
+
auto found_service = subscribed_.find(_service);
if (found_service != subscribed_.end()) {
auto found_instance = found_service->second.find(_instance);
if (found_instance != found_service->second.end()) {
auto found_eventgroup = found_instance->second.find(_eventgroup);
if (found_eventgroup != found_instance->second.end()) {
- for (auto its_client : found_eventgroup->second) {
- its_client.second->set_ttl(0); // is read once and removed afterwards!
+ auto found_client = found_eventgroup->second.find(_client);
+ if (found_client != found_eventgroup->second.end()) {
+ found_client->second->set_ttl(0);
+ }
+ }
+ }
+ }
+
+ boost::asio::ip::address its_address;
+
+ std::shared_ptr < runtime > its_runtime = runtime_.lock();
+ if (!its_runtime)
+ return;
+
+ std::shared_ptr < subscription > its_subscription =
+ subscribed_[_service][_instance][_eventgroup][_client];
+
+ auto endpoint = its_subscription->get_endpoint(false);
+ if (endpoint) {
+ endpoint->get_remote_address(its_address);
+ } else {
+ endpoint = its_subscription->get_endpoint(true);
+ if (endpoint) {
+ endpoint->get_remote_address(its_address);
+ }
+ }
+
+ std::shared_ptr < message_impl > its_message
+ = its_runtime->create_message();
+
+ insert_subscription(its_message, _service, _instance, _eventgroup,
+ its_subscription);
+ its_message->set_session(get_session(its_address));
+
+ serialize_and_send(its_message, its_address);
+}
+
+void service_discovery_impl::unsubscribe_all(service_t _service, instance_t _instance) {
+ std::lock_guard<std::mutex> its_lock(subscribed_mutex_);
+ auto found_service = subscribed_.find(_service);
+ if (found_service != subscribed_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ for (auto &its_eventgroup : found_instance->second) {
+ for (auto its_client : its_eventgroup.second) {
+ its_client.second->set_acknowledged(true);
+ its_client.second->set_endpoint(nullptr, true);
+ its_client.second->set_endpoint(nullptr, false);
}
}
}
@@ -262,7 +293,9 @@ void service_discovery_impl::insert_option(
if (its_option) {
its_option->set_address(its_address);
its_option->set_port(_port);
- its_option->set_udp(!_is_reliable);
+ 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 {
@@ -272,7 +305,9 @@ void service_discovery_impl::insert_option(
if (its_option) {
its_option->set_address(its_address);
its_option->set_port(_port);
- its_option->set_udp(!_is_reliable);
+ its_option->set_layer_four_protocol(
+ _is_reliable ? layer_four_protocol_e::TCP :
+ layer_four_protocol_e::UDP);
_entry->assign_option(its_option, 1);
}
}
@@ -325,40 +360,8 @@ void service_discovery_impl::insert_offer_entries(
std::shared_ptr<message_impl> &_message, services_t &_services) {
for (auto its_service : _services) {
for (auto its_instance : its_service.second) {
- auto its_info = its_instance.second;
- std::shared_ptr < serviceentry_impl > its_entry =
- _message->create_service_entry();
- if (its_entry) {
- its_entry->set_type(entry_type_e::OFFER_SERVICE);
- its_entry->set_service(its_service.first);
- its_entry->set_instance(its_instance.first);
- its_entry->set_major_version(its_info->get_major());
- its_entry->set_minor_version(its_info->get_minor());
- its_entry->set_ttl(its_info->get_ttl());
-
- std::shared_ptr < endpoint > its_endpoint =
- its_info->get_endpoint(true);
- if (its_endpoint) {
- insert_option(_message, its_entry, unicast_,
- its_endpoint->get_local_port(), true);
- if (0 == its_info->get_ttl()) {
- host_->del_routing_info(its_service.first,
- its_instance.first, true);
- }
- }
-
- its_endpoint = its_info->get_endpoint(false);
- if (its_endpoint) {
- insert_option(_message, its_entry, unicast_,
- its_endpoint->get_local_port(), false);
- if (0 == its_info->get_ttl()) {
- host_->del_routing_info(its_service.first,
- its_instance.first, false);
- }
- }
- } else {
- VSOMEIP_ERROR << "Failed to create service entry.";
- }
+ insert_offer_service(_message, its_service.first,
+ its_instance.first, its_instance.second);
}
}
}
@@ -391,7 +394,7 @@ void service_discovery_impl::insert_subscription(
void service_discovery_impl::insert_subscription_ack(
std::shared_ptr<message_impl> &_message, service_t _service,
instance_t _instance, eventgroup_t _eventgroup,
- std::shared_ptr<eventgroupinfo> &_info) {
+ std::shared_ptr<eventgroupinfo> &_info, ttl_t _ttl) {
std::shared_ptr < eventgroupentry_impl > its_entry =
_message->create_eventgroup_entry();
its_entry->set_type(entry_type_e::SUBSCRIBE_EVENTGROUP_ACK);
@@ -399,7 +402,8 @@ void service_discovery_impl::insert_subscription_ack(
its_entry->set_instance(_instance);
its_entry->set_eventgroup(_eventgroup);
its_entry->set_major_version(_info->get_major());
- its_entry->set_ttl(_info->get_ttl());
+ // SWS_SD_00315
+ its_entry->set_ttl(_ttl);
boost::asio::ip::address its_address;
uint16_t its_port;
@@ -408,8 +412,29 @@ void service_discovery_impl::insert_subscription_ack(
}
}
-void service_discovery_impl::send(const std::string &_name,
- bool _is_announcing) {
+void service_discovery_impl::insert_subscription_nack(
+ std::shared_ptr<message_impl> &_message, service_t _service,
+ instance_t _instance, eventgroup_t _eventgroup,
+ std::shared_ptr<eventgroupinfo> &_info) {
+ std::shared_ptr < eventgroupentry_impl > its_entry =
+ _message->create_eventgroup_entry();
+ // SWS_SD_00316 and SWS_SD_00385
+ its_entry->set_type(entry_type_e::STOP_SUBSCRIBE_EVENTGROUP_ACK);
+ its_entry->set_service(_service);
+ its_entry->set_instance(_instance);
+ its_entry->set_eventgroup(_eventgroup);
+ its_entry->set_major_version(_info->get_major());
+ // SWS_SD_00432
+ its_entry->set_ttl(0x0);
+
+ boost::asio::ip::address its_address;
+ uint16_t its_port;
+ if (_info->get_multicast(its_address, its_port)) {
+ insert_option(_message, its_entry, its_address, its_port, false);
+ }
+}
+
+void service_discovery_impl::send(bool _is_announcing) {
std::shared_ptr < runtime > its_runtime = runtime_.lock();
if (!its_runtime)
@@ -420,13 +445,13 @@ void service_discovery_impl::send(const std::string &_name,
// TODO: optimize building of SD message (common options, utilize the two runs)
- // If we are the default group and not in main phase, include "FindOffer"-entries
- if (_name == "default" && !_is_announcing) {
+ // If we are not in main phase, include "FindOffer"-entries
+ if (!_is_announcing) {
insert_find_entries(its_message, requested_);
}
// Always include the "OfferService"-entries for the service group
- services_t its_offers = host_->get_offered_services(_name);
+ services_t its_offers = host_->get_offered_services();
insert_offer_entries(its_message, its_offers);
// Serialize and send
@@ -451,6 +476,13 @@ void service_discovery_impl::on_message(const byte_t *_data, length_t _length) {
std::shared_ptr < message_impl
> its_message(deserializer_->deserialize_sd_message());
if (its_message) {
+ // ignore all messages which are sent with invalid header fields
+ if(!check_static_header_fields(its_message)) {
+ return;
+ }
+ ttl_t expired = stop_ttl_timer();
+ smallest_ttl_ = host_->update_routing_info(expired);
+
std::vector < std::shared_ptr<option_impl> > its_options =
its_message->get_options();
for (auto its_entry : its_message->get_entries()) {
@@ -466,35 +498,42 @@ void service_discovery_impl::on_message(const byte_t *_data, length_t _length) {
process_eventgroupentry(its_eventgroup_entry, its_options);
}
}
+ start_ttl_timer();
+ } else {
+ VSOMEIP_ERROR << "service_discovery_impl::on_message: deserialization error.";
+ return;
}
}
-void service_discovery_impl::on_offer_change(const std::string &_name) {
- if (_name == "default") {
- default_->process(ev_offer_change());
- } else {
- auto found_group = additional_.find(_name);
- if (found_group != additional_.end()) {
- found_group->second->process(ev_offer_change());
- }
- }
+void service_discovery_impl::on_offer_change() {
+ default_->process(ev_offer_change());
}
// Entry processing
void service_discovery_impl::process_serviceentry(
std::shared_ptr<serviceentry_impl> &_entry,
const std::vector<std::shared_ptr<option_impl> > &_options) {
+
+ // Read service info from entry
+ entry_type_e its_type = _entry->get_type();
service_t its_service = _entry->get_service();
instance_t its_instance = _entry->get_instance();
major_version_t its_major = _entry->get_major_version();
minor_version_t its_minor = _entry->get_minor_version();
ttl_t its_ttl = _entry->get_ttl();
+ // Read address info from options
+ boost::asio::ip::address its_reliable_address;
+ uint16_t its_reliable_port(ILLEGAL_PORT);
+
+ boost::asio::ip::address its_unreliable_address;
+ uint16_t its_unreliable_port(ILLEGAL_PORT);
+
+
for (auto i : { 1, 2 }) {
- for (auto its_index : _entry->get_options(i)) {
- std::vector < byte_t > its_option_address;
- uint16_t its_option_port = VSOMEIP_INVALID_PORT;
+ for (auto its_index : _entry->get_options(uint8_t(i))) {
std::shared_ptr < option_impl > its_option = _options[its_index];
+
switch (its_option->get_type()) {
case option_type_e::IP4_ENDPOINT: {
std::shared_ptr < ipv4_option_impl > its_ipv4_option =
@@ -503,12 +542,15 @@ void service_discovery_impl::process_serviceentry(
boost::asio::ip::address_v4 its_ipv4_address(
its_ipv4_option->get_address());
- boost::asio::ip::address its_address(its_ipv4_address);
- its_option_port = its_ipv4_option->get_port();
- handle_service_availability(its_service, its_instance,
- its_major, its_minor, its_ttl, its_address,
- its_option_port, !its_ipv4_option->is_udp());
+ if (its_ipv4_option->get_layer_four_protocol()
+ == layer_four_protocol_e::UDP) {
+ its_unreliable_address = its_ipv4_address;
+ its_unreliable_port = its_ipv4_option->get_port();
+ } else {
+ its_reliable_address = its_ipv4_address;
+ its_reliable_port = its_ipv4_option->get_port();
+ }
break;
}
case option_type_e::IP6_ENDPOINT: {
@@ -518,24 +560,211 @@ void service_discovery_impl::process_serviceentry(
boost::asio::ip::address_v6 its_ipv6_address(
its_ipv6_option->get_address());
- boost::asio::ip::address its_address(its_ipv6_address);
- its_option_port = its_ipv6_option->get_port();
- handle_service_availability(its_service, its_instance,
- its_major, its_minor, its_ttl, its_address,
- its_option_port, !its_ipv6_option->is_udp());
+ if (its_ipv6_option->get_layer_four_protocol()
+ == layer_four_protocol_e::UDP) {
+ its_unreliable_address = its_ipv6_address;
+ its_unreliable_port = its_ipv6_option->get_port();
+ } else {
+ its_reliable_address = its_ipv6_address;
+ its_reliable_port = its_ipv6_option->get_port();
+ }
break;
}
case option_type_e::IP4_MULTICAST:
case option_type_e::IP6_MULTICAST:
VSOMEIP_ERROR << "Invalid service option (Multicast)";
break;
+ case option_type_e::UNKNOWN:
default:
- VSOMEIP_WARNING << "Unsupported service option";
+ VSOMEIP_ERROR << "Unsupported service option";
break;
}
}
}
+
+ if (0 < its_ttl) {
+ switch(its_type) {
+ case entry_type_e::FIND_SERVICE:
+ process_findservice_serviceentry(its_service, its_instance,
+ its_major, its_minor);
+ break;
+ case entry_type_e::OFFER_SERVICE:
+ process_offerservice_serviceentry(its_service, its_instance,
+ its_major, its_minor, its_ttl,
+ its_reliable_address, its_reliable_port,
+ its_unreliable_address, its_unreliable_port);
+ break;
+ case entry_type_e::UNKNOWN:
+ default:
+ VSOMEIP_ERROR << "Unsupported serviceentry type";
+ }
+
+ } else {
+ unsubscribe_all(its_service, its_instance);
+ host_->del_routing_info(its_service, its_instance,
+ (its_reliable_port != ILLEGAL_PORT),
+ (its_unreliable_port != ILLEGAL_PORT));
+ }
+}
+
+void service_discovery_impl::process_offerservice_serviceentry(
+ service_t _service, instance_t _instance, major_version_t _major,
+ minor_version_t _minor, ttl_t _ttl,
+ const boost::asio::ip::address &_reliable_address,
+ uint16_t _reliable_port,
+ const boost::asio::ip::address &_unreliable_address,
+ uint16_t _unreliable_port) {
+ std::shared_ptr < runtime > its_runtime = runtime_.lock();
+ if (!its_runtime)
+ return;
+
+ host_->add_routing_info(_service, _instance,
+ _major, _minor, _ttl,
+ _reliable_address, _reliable_port,
+ _unreliable_address, _unreliable_port);
+
+ std::lock_guard<std::mutex> its_lock(subscribed_mutex_);
+ auto found_service = subscribed_.find(_service);
+ if (found_service != subscribed_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ if (0 < found_instance->second.size()) {
+ std::shared_ptr<message_impl> its_message
+ = its_runtime->create_message();
+
+ for (auto its_eventgroup : found_instance->second) {
+ for (auto its_client : its_eventgroup.second) {
+ std::shared_ptr<subscription> its_subscription(its_client.second);
+ if (its_subscription->is_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);
+
+ // TODO: consume major & ttl
+ insert_subscription(its_message,
+ _service, _instance,
+ its_eventgroup.first,
+ its_subscription);
+
+ its_subscription->set_acknowledged(false);
+ }
+ }
+ }
+
+ if (0 < its_message->get_entries().size()) {
+ std::shared_ptr<endpoint_definition> its_target;
+ session_t its_session(0);
+ if (_reliable_port != ILLEGAL_PORT) {
+ its_target = endpoint_definition::get(
+ _reliable_address, port_, reliable_);
+ its_session = get_session(_reliable_address);
+ } else if (_unreliable_port != ILLEGAL_PORT) {
+ its_target = endpoint_definition::get(
+ _unreliable_address, port_, reliable_);
+ its_session = get_session(_unreliable_address);
+ }
+
+ if (its_target) {
+ its_message->set_session(its_session);
+ serializer_->serialize(its_message.get());
+ if (host_->send_to(its_target,
+ serializer_->get_data(),
+ serializer_->get_size())) {
+ increment_session(its_target->get_address());
+ }
+ serializer_->reset();
+ }
+ }
+ }
+ }
+ }
+}
+
+void service_discovery_impl::process_findservice_serviceentry(
+ service_t _service, instance_t _instance, major_version_t _major,
+ minor_version_t _minor) {
+ services_t offered_services = host_->get_offered_services();
+ auto found_service = offered_services.find(_service);
+ if (found_service != offered_services.end()) {
+ if (_instance != ANY_INSTANCE) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ std::shared_ptr<serviceinfo> its_info = found_instance->second;
+ send_unicast_offer_service(its_info, _service, _instance,
+ _major, _minor);
+ }
+ } else {
+ // send back all available instances
+ for (const auto &found_instance : found_service->second) {
+ send_unicast_offer_service(found_instance.second, _service,
+ _instance, _major, _minor);
+ }
+ }
+ }
+}
+
+void service_discovery_impl::send_unicast_offer_service(
+ const std::shared_ptr<const serviceinfo> &_info, service_t _service,
+ instance_t _instance, major_version_t _major, minor_version_t _minor) {
+ if (_major == ANY_MAJOR || _major == _info->get_major()) {
+ if (_minor == 0xFFFFFFFF || _minor == _info->get_minor()) {
+ std::shared_ptr<runtime> its_runtime = runtime_.lock();
+ if (!its_runtime) {
+ return;
+ }
+ std::shared_ptr<message_impl> its_message =
+ its_runtime->create_message();
+ insert_offer_service(its_message, _service, _instance, _info);
+
+ serialize_and_send(its_message, get_current_remote_address());
+ }
+ }
+}
+
+void service_discovery_impl::insert_offer_service(
+ std::shared_ptr < message_impl > _message, service_t _service,
+ instance_t _instance, const std::shared_ptr<const serviceinfo> &_info) {
+ std::shared_ptr < serviceentry_impl > its_entry =
+ _message->create_service_entry();
+ if (its_entry) {
+ its_entry->set_type(entry_type_e::OFFER_SERVICE);
+ its_entry->set_service(_service);
+ its_entry->set_instance(_instance);
+ its_entry->set_major_version(_info->get_major());
+ its_entry->set_minor_version(_info->get_minor());
+
+ ttl_t its_ttl = _info->get_ttl();
+ if (its_ttl > 0)
+ its_ttl = ttl_;
+ its_entry->set_ttl(its_ttl);
+
+ std::shared_ptr < endpoint > its_endpoint =
+ _info->get_endpoint(true);
+ if (its_endpoint) {
+ insert_option(_message, its_entry, unicast_,
+ its_endpoint->get_local_port(), true);
+ if (0 == _info->get_ttl()) {
+ host_->del_routing_info(_service,
+ _instance, true, false);
+ }
+ }
+
+ its_endpoint = _info->get_endpoint(false);
+ if (its_endpoint) {
+ insert_option(_message, its_entry, unicast_,
+ its_endpoint->get_local_port(), false);
+ if (0 == _info->get_ttl()) {
+ host_->del_routing_info(_service,
+ _instance, false, true);
+ }
+ }
+ } else {
+ VSOMEIP_ERROR << "Failed to create service entry.";
+ }
}
void service_discovery_impl::process_eventgroupentry(
@@ -548,27 +777,74 @@ void service_discovery_impl::process_eventgroupentry(
major_version_t its_major = _entry->get_major_version();
ttl_t its_ttl = _entry->get_ttl();
+ if (_entry->get_owning_message()->get_return_code() != return_code) {
+ VSOMEIP_ERROR << "Invalid return code in SD header";
+ send_eventgroup_subscription_nack(its_service, its_instance,
+ its_eventgroup, its_major);
+ return;
+ }
+
+ if(its_type == entry_type_e::SUBSCRIBE_EVENTGROUP) {
+ if (_entry->get_num_options(1) == 0
+ && _entry->get_num_options(2) == 0) {
+ VSOMEIP_ERROR << "Invalid number of options in SubscribeEventGroup entry";
+ send_eventgroup_subscription_nack(its_service, its_instance,
+ its_eventgroup, its_major);
+ return;
+ }
+ if(_entry->get_owning_message()->get_options_length() < 12) {
+ VSOMEIP_ERROR << "Invalid options length in SD message";
+ send_eventgroup_subscription_nack(its_service, its_instance,
+ its_eventgroup, its_major);
+ return;
+ }
+ if (_options.size()
+ < (_entry->get_num_options(1) + _entry->get_num_options(2))) {
+ VSOMEIP_ERROR << "Fewer options in SD message than "
+ "referenced in EventGroup entry";
+ send_eventgroup_subscription_nack(its_service, its_instance,
+ its_eventgroup, its_major);
+ return;
+ }
+ }
+
boost::asio::ip::address its_reliable_address;
- uint16_t its_reliable_port = VSOMEIP_INVALID_PORT;
+ uint16_t its_reliable_port(ILLEGAL_PORT);
boost::asio::ip::address its_unreliable_address;
- uint16_t its_unreliable_port = VSOMEIP_INVALID_PORT;
+ uint16_t its_unreliable_port(ILLEGAL_PORT);
for (auto i : { 1, 2 }) {
- for (auto its_index : _entry->get_options(i)) {
- std::vector < byte_t > its_option_address;
- std::shared_ptr < option_impl > its_option = _options[its_index];
+ for (auto its_index : _entry->get_options(uint8_t(i))) {
+ std::shared_ptr < option_impl > its_option;
+ try {
+ its_option = _options.at(its_index);
+ } catch(const std::out_of_range& e) {
+ VSOMEIP_ERROR << "Fewer options in SD message than "
+ "referenced in EventGroup entry for "
+ "option run number: " << i;
+ if (entry_type_e::SUBSCRIBE_EVENTGROUP == its_type) {
+ send_eventgroup_subscription_nack(its_service, its_instance,
+ its_eventgroup, its_major);
+ }
+ return;
+ }
switch (its_option->get_type()) {
case option_type_e::IP4_ENDPOINT: {
- if (entry_type_e::SUBSCRIBE_EVENTGROUP == _entry->get_type()) {
+ if (entry_type_e::SUBSCRIBE_EVENTGROUP == its_type) {
std::shared_ptr < ipv4_option_impl > its_ipv4_option =
std::dynamic_pointer_cast < ipv4_option_impl
> (its_option);
boost::asio::ip::address_v4 its_ipv4_address(
its_ipv4_option->get_address());
-
+ if (!check_layer_four_protocol(its_ipv4_option)) {
+ send_eventgroup_subscription_nack(its_service,
+ its_instance, its_eventgroup, its_major);
+ return;
+ }
// TODO: add error handling (port already set) here
- if (its_ipv4_option->is_udp()) {
+ if (its_ipv4_option->get_layer_four_protocol()
+ == layer_four_protocol_e::UDP) {
its_unreliable_address = its_ipv4_address;
its_unreliable_port = its_ipv4_option->get_port();
} else {
@@ -582,20 +858,25 @@ void service_discovery_impl::process_eventgroupentry(
break;
}
case option_type_e::IP6_ENDPOINT: {
- if (entry_type_e::SUBSCRIBE_EVENTGROUP == _entry->get_type()) {
+ if (entry_type_e::SUBSCRIBE_EVENTGROUP == its_type) {
std::shared_ptr < ipv6_option_impl > its_ipv6_option =
std::dynamic_pointer_cast < ipv6_option_impl
> (its_option);
boost::asio::ip::address_v6 its_ipv6_address(
its_ipv6_option->get_address());
-
+ if (!check_layer_four_protocol(its_ipv6_option)) {
+ send_eventgroup_subscription_nack(its_service,
+ its_instance, its_eventgroup, its_major);
+ return;
+ }
// TODO: add error handling (port already set) here
- if (its_ipv6_option->is_udp()) {
+ if (its_ipv6_option->get_layer_four_protocol()
+ == layer_four_protocol_e::UDP) {
its_unreliable_address = its_ipv6_address;
its_unreliable_port = its_ipv6_option->get_port();
} else {
- its_unreliable_address = its_ipv6_address;
+ its_reliable_address = its_ipv6_address;
its_reliable_port = its_ipv6_option->get_port();
}
} else {
@@ -605,8 +886,7 @@ void service_discovery_impl::process_eventgroupentry(
break;
}
case option_type_e::IP4_MULTICAST:
- if (entry_type_e::SUBSCRIBE_EVENTGROUP_ACK
- == _entry->get_type()) {
+ if (entry_type_e::SUBSCRIBE_EVENTGROUP_ACK == its_type) {
std::shared_ptr < ipv4_option_impl > its_ipv4_option =
std::dynamic_pointer_cast < ipv4_option_impl
> (its_option);
@@ -622,8 +902,7 @@ void service_discovery_impl::process_eventgroupentry(
}
break;
case option_type_e::IP6_MULTICAST:
- if (entry_type_e::SUBSCRIBE_EVENTGROUP_ACK
- == _entry->get_type()) {
+ if (entry_type_e::SUBSCRIBE_EVENTGROUP_ACK == its_type) {
std::shared_ptr < ipv6_option_impl > its_ipv6_option =
std::dynamic_pointer_cast < ipv6_option_impl
> (its_option);
@@ -638,8 +917,11 @@ void service_discovery_impl::process_eventgroupentry(
<< "Invalid eventgroup option (IPv6 Multicast)";
}
break;
+ case option_type_e::UNKNOWN:
default:
VSOMEIP_WARNING << "Unsupported eventgroup option";
+ send_eventgroup_subscription_nack(its_service, its_instance,
+ its_eventgroup, its_major);
break;
}
}
@@ -648,7 +930,7 @@ void service_discovery_impl::process_eventgroupentry(
if (entry_type_e::SUBSCRIBE_EVENTGROUP == its_type) {
handle_eventgroup_subscription(its_service, its_instance,
its_eventgroup, its_major, its_ttl,
- (its_reliable_port != VSOMEIP_INVALID_PORT ?
+ (its_reliable_port != ILLEGAL_PORT ?
its_reliable_address : its_unreliable_address),
its_reliable_port, its_unreliable_port);
} else {
@@ -658,78 +940,6 @@ void service_discovery_impl::process_eventgroupentry(
}
}
-void service_discovery_impl::handle_service_availability(service_t _service,
- instance_t _instance, major_version_t _major, minor_version_t _minor,
- ttl_t _ttl, const boost::asio::ip::address &_address, uint16_t _port,
- bool _reliable) {
-
- std::shared_ptr < runtime > its_runtime = runtime_.lock();
- if (!its_runtime)
- return;
-
- if (0 < _ttl) {
- host_->add_routing_info(_service, _instance, _major, _minor, _ttl,
- _address, _port, _reliable);
-
- auto found_service = subscribed_.find(_service);
- if (found_service != subscribed_.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- if (0 < found_instance->second.size()) {
- std::shared_ptr < message_impl > its_message =
- its_runtime->create_message();
- for (auto its_eventgroup : found_instance->second) {
- for (auto its_client : its_eventgroup.second) {
- std::shared_ptr < subscription
- > its_subscription(its_client.second);
- if (!its_subscription->is_acknowleged()) {
- its_subscription->set_endpoint(
- host_->find_or_create_remote_client(_service,
- _instance, true, its_client.first), true);
- its_subscription->set_endpoint(
- host_->find_or_create_remote_client(_service,
- _instance, false, its_client.first), false);
-
- // TODO: consume major & ttl
- insert_subscription(its_message, _service,
- _instance, its_eventgroup.first,
- its_subscription);
- }
- }
-
- }
-
- if (0 < its_message->get_entries().size()) {
- its_message->set_session(get_session(_address));
- serializer_->serialize(its_message.get());
- if (host_->send_to(
- std::make_shared < endpoint_definition
- > (_address, port_, reliable_),
- serializer_->get_data(),
- serializer_->get_size())) {
- increment_session(_address);
- }
- serializer_->reset();
- }
- }
- }
- }
- } else {
- auto found_service = subscribed_.find(_service);
- if (found_service != subscribed_.end()) {
- auto found_instance = found_service->second.find(_instance);
- if (found_instance != found_service->second.end()) {
- for (auto &its_eventgroup : found_instance->second) {
- for (auto its_client : its_eventgroup.second) {
- its_client.second->set_acknowledged(false);
- }
- }
- }
- }
- host_->del_routing_info(_service, _instance, _reliable);
- }
-}
-
void service_discovery_impl::handle_eventgroup_subscription(service_t _service,
instance_t _instance, eventgroup_t _eventgroup, major_version_t _major,
ttl_t _ttl, const boost::asio::ip::address &_address,
@@ -746,51 +956,67 @@ void service_discovery_impl::handle_eventgroup_subscription(service_t _service,
_service, _instance, _eventgroup);
bool is_nack(false);
- std::shared_ptr < endpoint_definition > its_subscriber;
- std::shared_ptr < endpoint_definition > its_target;
-
- // Could not find eventgroup --> send Nack
- if (!its_info || _major > its_info->get_major()
- || _ttl > its_info->get_ttl()) {
+ std::shared_ptr < endpoint_definition > its_reliable_subscriber,
+ its_unreliable_subscriber;
+ std::shared_ptr < endpoint_definition > its_reliable_target,
+ its_unreliable_target;
+
+ // Could not find eventgroup or wrong version
+ if (!its_info || _major != its_info->get_major()) {
+ // Create a temporary info object with TTL=0 --> send NACK
its_info = std::make_shared < eventgroupinfo > (_major, 0);
is_nack = true;
+ insert_subscription_nack(its_message, _service, _instance, _eventgroup,
+ its_info);
+ serialize_and_send(its_message, _address);
+ //TODO add check if required tcp connection is open
+ return;
} else {
boost::asio::ip::address its_target_address;
uint16_t its_target_port;
- if (VSOMEIP_INVALID_PORT != _unreliable_port) {
- its_subscriber = std::make_shared < endpoint_definition
- > (_address, _unreliable_port, false);
+ if (ILLEGAL_PORT != _unreliable_port) {
+ its_unreliable_subscriber = endpoint_definition::get(
+ _address, _unreliable_port, false);
if (its_info->get_multicast(its_target_address,
its_target_port)) {
- its_target = std::make_shared < endpoint_definition
- > (its_target_address, its_target_port, false);
+ its_unreliable_target = endpoint_definition::get(
+ its_target_address, its_target_port, false);
} else {
- its_target = its_subscriber;
+ its_unreliable_target = its_unreliable_subscriber;
}
- } else {
- its_subscriber = std::make_shared < endpoint_definition
- > (_address, _reliable_port, true);
- its_target = its_subscriber;
}
+ if (ILLEGAL_PORT != _reliable_port) {
+ its_reliable_subscriber = endpoint_definition::get(
+ _address, _reliable_port, true);
+ its_reliable_target = its_reliable_subscriber;
+ }
+ }
+
+ if (_ttl == 0) { // --> unsubscribe
+ if (its_unreliable_target) {
+ host_->on_unsubscribe(_service, _instance, _eventgroup, its_unreliable_target);
+ }
+ if (its_reliable_target) {
+ host_->on_unsubscribe(_service, _instance, _eventgroup, its_reliable_target);
+ }
+ return;
}
insert_subscription_ack(its_message, _service, _instance, _eventgroup,
- its_info);
+ its_info, _ttl);
- its_message->set_session(get_session(_address));
- serializer_->serialize(its_message.get());
- if (host_->send_to(
- std::make_shared < endpoint_definition
- > (_address, port_, reliable_), serializer_->get_data(),
- serializer_->get_size())) {
- increment_session(_address);
- }
- serializer_->reset();
+ serialize_and_send(its_message, _address);
// Finally register the new subscriber and send him all the fields(!)
if (!is_nack) {
- host_->on_subscribe(_service, _instance, _eventgroup,
- its_subscriber, its_target);
+ if (its_unreliable_target && its_unreliable_subscriber) {
+ host_->on_subscribe(_service, _instance, _eventgroup,
+ its_unreliable_subscriber, its_unreliable_target);
+ }
+ if (its_reliable_target && its_reliable_subscriber) {
+ host_->on_subscribe(_service, _instance, _eventgroup,
+ its_reliable_subscriber, its_reliable_target);
+ }
}
}
}
@@ -799,6 +1025,9 @@ void service_discovery_impl::handle_eventgroup_subscription_ack(
service_t _service, instance_t _instance, eventgroup_t _eventgroup,
major_version_t _major, ttl_t _ttl,
const boost::asio::ip::address &_address, uint16_t _port) {
+ (void)_major;
+ (void)_ttl;
+
auto found_service = subscribed_.find(_service);
if (found_service != subscribed_.end()) {
auto found_instance = found_service->second.find(_instance);
@@ -818,5 +1047,96 @@ 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));
+ if(!serializer_->serialize(_message.get())) {
+ VSOMEIP_ERROR << "service_discovery_impl::serialize_and_send: serialization error.";
+ return;
+ }
+ if (host_->send_to(endpoint_definition::get(_address, port_, reliable_),
+ serializer_->get_data(), serializer_->get_size())) {
+ increment_session(_address);
+ }
+ serializer_->reset();
+}
+
+void service_discovery_impl::start_ttl_timer() {
+ ttl_timer_.expires_from_now(std::chrono::seconds(smallest_ttl_));
+ ttl_timer_.async_wait(
+ std::bind(&service_discovery_impl::check_ttl, shared_from_this(),
+ std::placeholders::_1));
+}
+
+ttl_t service_discovery_impl::stop_ttl_timer() {
+ ttl_t remaining = ttl_t(std::chrono::duration_cast<
+ std::chrono::seconds
+ >(ttl_timer_.expires_from_now()).count());
+ ttl_timer_.cancel();
+ return (smallest_ttl_ - remaining);
+}
+
+void service_discovery_impl::check_ttl(const boost::system::error_code &_error) {
+ if (!_error) {
+ smallest_ttl_ = host_->update_routing_info(smallest_ttl_);
+ start_ttl_timer();
+ }
+}
+
+boost::asio::ip::address service_discovery_impl::get_current_remote_address() const {
+ if (reliable_) {
+ return std::static_pointer_cast<tcp_server_endpoint_impl>(endpoint_)->get_remote().address();
+ } else {
+ return std::static_pointer_cast<udp_server_endpoint_impl>(endpoint_)->get_remote().address();
+ }
+}
+
+bool service_discovery_impl::check_static_header_fields(
+ const std::shared_ptr<const message> &_message) const {
+ if(_message->get_protocol_version() != protocol_version) {
+ VSOMEIP_ERROR << "Invalid protocol version in SD header";
+ return false;
+ }
+ if(_message->get_interface_version() != interface_version) {
+ VSOMEIP_ERROR << "Invalid interface version in SD header";
+ return false;
+ }
+ if(_message->get_message_type() != message_type) {
+ VSOMEIP_ERROR << "Invalid message type in SD header";
+ return false;
+ }
+ return true;
+}
+
+void service_discovery_impl::send_eventgroup_subscription_nack(
+ service_t _service, instance_t _instance, eventgroup_t _eventgroup, major_version_t _major) {
+ std::shared_ptr<runtime> its_runtime = runtime_.lock();
+ if (!its_runtime) {
+ return;
+ }
+ std::shared_ptr<message_impl> its_message = its_runtime->create_message();
+ if (its_message) {
+ std::shared_ptr<eventgroupinfo> its_info = host_->find_eventgroup(
+ _service, _instance, _eventgroup);
+ if(!its_info) {
+ // Create a temporary info object with TTL=0
+ its_info = std::make_shared < eventgroupinfo > (_major, 0);
+ }
+ insert_subscription_nack(its_message, _service, _instance, _eventgroup,
+ its_info);
+ serialize_and_send(its_message, get_current_remote_address());
+ }
+}
+
+bool service_discovery_impl::check_layer_four_protocol(
+ const std::shared_ptr<const ip_option_impl> _ip_option) const {
+ if (_ip_option->get_layer_four_protocol() == layer_four_protocol_e::UNKNOWN) {
+ VSOMEIP_ERROR << "Invalid layer 4 protocol in IP endpoint option";
+ return false;
+ }
+ return true;
+}
+
} // namespace sd
} // namespace vsomeip
diff --git a/implementation/service_discovery/src/subscription.cpp b/implementation/service_discovery/src/subscription.cpp
index 4b823be..76b9c9f 100644
--- a/implementation/service_discovery/src/subscription.cpp
+++ b/implementation/service_discovery/src/subscription.cpp
@@ -10,10 +10,10 @@ namespace sd {
subscription::subscription(major_version_t _major, ttl_t _ttl,
std::shared_ptr<endpoint> _reliable,
- std::shared_ptr<endpoint> _unreliable,
- client_t _target)
- : major_(_major), ttl_(_ttl), reliable_(_reliable), unreliable_(
- _unreliable), is_acknowledged_(false) {
+ std::shared_ptr<endpoint> _unreliable)
+ : major_(_major), ttl_(_ttl),
+ reliable_(_reliable), unreliable_(_unreliable),
+ is_acknowledged_(true) {
}
subscription::~subscription() {
@@ -43,7 +43,7 @@ void subscription::set_endpoint(std::shared_ptr<endpoint> _endpoint,
unreliable_ = _endpoint;
}
-bool subscription::is_acknowleged() const {
+bool subscription::is_acknowledged() const {
return is_acknowledged_;
}
diff --git a/implementation/utility/include/byteorder.hpp b/implementation/utility/include/byteorder.hpp
index 55088f1..baea175 100644
--- a/implementation/utility/include/byteorder.hpp
+++ b/implementation/utility/include/byteorder.hpp
@@ -17,37 +17,37 @@
#if __BYTE_ORDER == __LITTLE_ENDIAN
-#define VSOMEIP_BYTES_TO_WORD(x0, x1) ((x0) << 8 | (x1))
-#define VSOMEIP_BYTES_TO_LONG(x0, x1, x2, x3) ((x0) << 24 | (x1) << 16 | (x2) << 8 | (x3))
+#define VSOMEIP_BYTES_TO_WORD(x0, x1) (uint16_t((x0) << 8 | (x1)))
+#define VSOMEIP_BYTES_TO_LONG(x0, x1, x2, x3) (uint32_t((x0) << 24 | (x1) << 16 | (x2) << 8 | (x3)))
-#define VSOMEIP_WORDS_TO_LONG(x0, x1) ((x0) << 16 | (x1))
+#define VSOMEIP_WORDS_TO_LONG(x0, x1) (uint32_t((x0) << 16 | (x1)))
-#define VSOMEIP_WORD_BYTE0(x) ((x) & 0xFF)
-#define VSOMEIP_WORD_BYTE1(x) ((x) >> 8)
+#define VSOMEIP_WORD_BYTE0(x) (uint8_t((x) & 0xFF))
+#define VSOMEIP_WORD_BYTE1(x) (uint8_t((x) >> 8))
-#define VSOMEIP_LONG_BYTE0(x) ((x) & 0xFF)
-#define VSOMEIP_LONG_BYTE1(x) (((x) >> 8) & 0xFF)
-#define VSOMEIP_LONG_BYTE2(x) (((x) >> 16) & 0xFF)
-#define VSOMEIP_LONG_BYTE3(x) (((x) >> 24) & 0xFF)
+#define VSOMEIP_LONG_BYTE0(x) (uint8_t((x) & 0xFF))
+#define VSOMEIP_LONG_BYTE1(x) (uint8_t(((x) >> 8) & 0xFF))
+#define VSOMEIP_LONG_BYTE2(x) (uint8_t(((x) >> 16) & 0xFF))
+#define VSOMEIP_LONG_BYTE3(x) (uint8_t(((x) >> 24) & 0xFF))
-#define VSOMEIP_LONG_WORD0(x) ((x) & 0xFFFF)
-#define VSOMEIP_LONG_WORD1(x) (((x) >> 16) & 0xFFFF)
+#define VSOMEIP_LONG_WORD0(x) (uint16_t((x) & 0xFFFF))
+#define VSOMEIP_LONG_WORD1(x) (uint16_t(((x) >> 16) & 0xFFFF))
#elif __BYTE_ORDER == __BIG_ENDIAN
-#define VSOMEIP_BYTES_TO_WORD(x0, x1) ((x1) << 8 | (x0))
-#define VSOMEIP_BYTES_TO_LONG(x0, x1, x2, x3) ((x3) << 24 | (x2) << 16 | (x1) << 8 | (x0))
+#define VSOMEIP_BYTES_TO_WORD(x0, x1) (uint16_t((x1) << 8 | (x0)))
+#define VSOMEIP_BYTES_TO_LONG(x0, x1, x2, x3) (uint32_t((x3) << 24 | (x2) << 16 | (x1) << 8 | (x0)))
-#define VSOMEIP_WORD_BYTE0(x) ((x) >> 8)
-#define VSOMEIP_WORD_BYTE1(x) ((x) & 0xFF)
+#define VSOMEIP_WORD_BYTE0(x) (uint8_t((x) >> 8))
+#define VSOMEIP_WORD_BYTE1(x) (uint8_t((x) & 0xFF))
-#define VSOMEIP_LONG_BYTE0(x) (((x) >> 24) & 0xFF)
-#define VSOMEIP_LONG_BYTE1(x) (((x) >> 16) & 0xFF)
-#define VSOMEIP_LONG_BYTE2(x) (((x) >> 8) & 0xFF)
-#define VSOMEIP_LONG_BYTE3(x) ((x) & 0xFF)
+#define VSOMEIP_LONG_BYTE0(x) (uint8_t(((x) >> 24) & 0xFF))
+#define VSOMEIP_LONG_BYTE1(x) (uint8_t(((x) >> 16) & 0xFF))
+#define VSOMEIP_LONG_BYTE2(x) (uint8_t(((x) >> 8) & 0xFF))
+#define VSOMEIP_LONG_BYTE3(x) (uint8_t((x) & 0xFF))
-#define VSOMEIP_LONG_WORD0(x) ((((x) >> 16) & 0xFFFF)
-#define VSOMEIP_LONG_WORD1(x) (((x) & 0xFFFF)
+#define VSOMEIP_LONG_WORD0(x) (uint16_t((((x) >> 16) & 0xFFFF))
+#define VSOMEIP_LONG_WORD1(x) (uint16_t(((x) & 0xFFFF))
#else
diff --git a/implementation/utility/include/utility.hpp b/implementation/utility/include/utility.hpp
index 000ca9b..a366075 100644
--- a/implementation/utility/include/utility.hpp
+++ b/implementation/utility/include/utility.hpp
@@ -61,7 +61,7 @@ public:
static uint32_t get_message_size(const byte_t *_data, uint32_t _size);
static inline uint32_t get_message_size(std::vector<byte_t> &_data) {
if (_data.size() > 0) {
- return (get_message_size(&_data[0], _data.size()));
+ return (get_message_size(&_data[0], uint32_t(_data.size())));
}
return 0;
}
@@ -69,6 +69,17 @@ public:
static uint32_t get_payload_size(const byte_t *_data, uint32_t _size);
static bool exists(const std::string &_path);
+ static bool is_file(const std::string &_path);
+ static bool is_folder(const std::string &_path);
+
+ static struct configuration_data_t *the_configuration_data__;
+ static bool auto_configuration_init();
+ static void auto_configuration_exit();
+
+ static bool is_routing_manager_host__;
+ static bool is_routing_manager_host();
+
+ static client_t get_client_id();
};
} // namespace vsomeip
diff --git a/implementation/utility/src/utility.cpp b/implementation/utility/src/utility.cpp
index 28eef27..e2cbde4 100644
--- a/implementation/utility/src/utility.cpp
+++ b/implementation/utility/src/utility.cpp
@@ -8,15 +8,21 @@
#include <iostream>
#else
#include <dlfcn.h>
+#include <sys/mman.h>
#endif
#include <sys/stat.h>
+#ifndef WIN32
+#include <fcntl.h>
+#endif
+
#include <vsomeip/defines.hpp>
-#include <vsomeip/logger.hpp>
#include "../include/byteorder.hpp"
#include "../include/utility.hpp"
+#include "../../configuration/include/internal.hpp"
+#include "../../logging/include/logger.hpp"
namespace vsomeip {
@@ -83,4 +89,84 @@ bool utility::exists(const std::string &_path) {
return (stat(_path.c_str(), &its_stat) == 0);
}
+bool utility::is_file(const std::string &_path) {
+ struct stat its_stat;
+ if (stat(_path.c_str(), &its_stat) == 0) {
+ if (its_stat.st_mode & S_IFREG)
+ return true;
+ }
+ return false;
+}
+
+bool utility::is_folder(const std::string &_path) {
+ struct stat its_stat;
+ if (stat(_path.c_str(), &its_stat) == 0) {
+ if (its_stat.st_mode & S_IFDIR)
+ return true;
+ }
+ return false;
+}
+
+configuration_data_t *utility::the_configuration_data__(nullptr);
+bool utility::is_routing_manager_host__(false);
+
+bool utility::auto_configuration_init() {
+#ifndef WIN32
+ int its_descriptor = shm_open(VSOMEIP_SHM_NAME, O_RDWR|O_CREAT|O_EXCL, 0660);
+ if (its_descriptor > -1) {
+ if (0 == ftruncate(its_descriptor, sizeof(configuration_data_t))) {
+ void *its_segment = mmap(0, sizeof(configuration_data_t),
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ its_descriptor, 0);
+ the_configuration_data__
+ = reinterpret_cast<configuration_data_t *>(its_segment);
+ if (the_configuration_data__ != nullptr) {
+ std::lock_guard<std::mutex> its_lock(the_configuration_data__->mutex_);
+ the_configuration_data__->ref_ = 0;
+ the_configuration_data__->next_client_id_ = (VSOMEIP_DIAGNOSIS_ADDRESS << 8);
+ is_routing_manager_host__ = true;
+ }
+ } else {
+ // TODO: an error message
+ }
+ } else {
+ its_descriptor = shm_open(VSOMEIP_SHM_NAME, O_RDWR, 0660);
+ if (its_descriptor > -1) {
+ void *its_segment = mmap(0, sizeof(configuration_data_t),
+ PROT_READ | PROT_WRITE, MAP_SHARED,
+ its_descriptor, 0);
+ the_configuration_data__
+ = reinterpret_cast<configuration_data_t *>(its_segment);
+ } else {
+ // TODO: an error message
+ }
+ }
+#endif
+ return (the_configuration_data__ != nullptr);
+}
+
+void utility::auto_configuration_exit() {
+#ifndef WIN32
+ if (the_configuration_data__) {
+ munmap(the_configuration_data__, sizeof(configuration_data_t));
+ if (is_routing_manager_host__) {
+ shm_unlink(VSOMEIP_SHM_NAME);
+ }
+ }
+#endif
+}
+
+client_t utility::get_client_id() {
+ if (the_configuration_data__ != nullptr) {
+ std::lock_guard<std::mutex> its_lock(the_configuration_data__->mutex_);
+ the_configuration_data__->next_client_id_++;
+ return the_configuration_data__->next_client_id_;
+ }
+ return VSOMEIP_DIAGNOSIS_ADDRESS;
+}
+
+bool utility::is_routing_manager_host() {
+ return is_routing_manager_host__;
+}
+
} // namespace vsomeip