diff options
author | Juergen Gehring <juergen.gehring@bmw.de> | 2018-01-25 00:40:03 -0800 |
---|---|---|
committer | Juergen Gehring <juergen.gehring@bmw.de> | 2018-01-25 00:40:03 -0800 |
commit | 686cb94032c12be4981eac46efe5f62c2ba4d0e8 (patch) | |
tree | 2ef421866a7e7db6d598a7c3b14da58d5dc6e767 | |
parent | e9c35d34fb58c4a68d2c2fdbd78b69a0ad0ac320 (diff) | |
download | vSomeIP-686cb94032c12be4981eac46efe5f62c2ba4d0e8.tar.gz |
vsomeip 2.9.02.9.0
58 files changed, 3323 insertions, 284 deletions
@@ -1,8 +1,17 @@ Changes ======= -v2.8.1 -- Support negative filter in trace connector +v2.9.0 +- Added get_offered_services_async method to application interface to + read the currently offered services +- Added set_watchdog_handler method to application interface which can + be used to register a handler invoked in a given interval. +- Optimize processing time of incoming service discovery messages +- Events are now sent based on their configuration in the json file +- If a remote service is offered reliable and unreliable subscriptions + are now done always with both endpoint options. +- Incoming subscriptions are now not acknowledged if not all events of + the eventgroup can be served with the given endpoint options. v2.8.0 - Change behaviour of register_subscription_status_handler method of diff --git a/CMakeLists.txt b/CMakeLists.txt index 596b2ca..3976336 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,8 +7,8 @@ cmake_minimum_required (VERSION 2.8.12) project (vsomeip) set (VSOMEIP_MAJOR_VERSION 2) -set (VSOMEIP_MINOR_VERSION 8) -set (VSOMEIP_PATCH_VERSION 1) +set (VSOMEIP_MINOR_VERSION 9) +set (VSOMEIP_PATCH_VERSION 0) set (VSOMEIP_VERSION ${VSOMEIP_MAJOR_VERSION}.${VSOMEIP_MINOR_VERSION}.${VSOMEIP_PATCH_VERSION}) set (PACKAGE_VERSION ${VSOMEIP_VERSION}) # Used in documentatin/doxygen.in set (CMAKE_VERBOSE_MAKEFILE off) diff --git a/implementation/configuration/include/configuration.hpp b/implementation/configuration/include/configuration.hpp index 6f18300..85b4019 100644 --- a/implementation/configuration/include/configuration.hpp +++ b/implementation/configuration/include/configuration.hpp @@ -94,6 +94,8 @@ public: virtual bool is_local_service(service_t _service, instance_t _instance) const = 0; + virtual bool is_event_reliable(service_t _service, instance_t _instance, event_t _event) const = 0; + // Service Discovery configuration virtual bool is_sd_enabled() const = 0; diff --git a/implementation/configuration/include/configuration_impl.hpp b/implementation/configuration/include/configuration_impl.hpp index c519f05..1775f00 100644 --- a/implementation/configuration/include/configuration_impl.hpp +++ b/implementation/configuration/include/configuration_impl.hpp @@ -111,6 +111,8 @@ public: VSOMEIP_EXPORT bool is_local_service(service_t _service, instance_t _instance) const; + VSOMEIP_EXPORT bool is_event_reliable(service_t _service, instance_t _instance, event_t _event) const; + // Service Discovery configuration VSOMEIP_EXPORT bool is_sd_enabled() const; diff --git a/implementation/configuration/include/internal.hpp.in b/implementation/configuration/include/internal.hpp.in index b16cc01..ea35e9d 100644 --- a/implementation/configuration/include/internal.hpp.in +++ b/implementation/configuration/include/internal.hpp.in @@ -18,7 +18,7 @@ #define VSOMEIP_DEFAULT_CONFIGURATION_FILE "/etc/vsomeip.json" #define VSOMEIP_LOCAL_CONFIGURATION_FILE "./vsomeip.json" -#define VSOMEIP_MANDATORY_CONFIGURATION_FILES "vsomeip_std.json,vsomeip_app.json,vsomeip_plc.json,vsomeip_log.json" +#define VSOMEIP_MANDATORY_CONFIGURATION_FILES "vsomeip_std.json,vsomeip_app.json,vsomeip_plc.json" #define VSOMEIP_DEFAULT_CONFIGURATION_FOLDER "/etc/vsomeip" #define VSOMEIP_LOCAL_CONFIGURATION_FOLDER "./vsomeip" @@ -39,7 +39,7 @@ #define VSOMEIP_ROUTING "@VSOMEIP_ROUTING@" #define VSOMEIP_ROUTING_CLIENT 0 -#define VSOMEIP_ROUTING_INFO_SIZE_INIT 256 +#define VSOMEIP_ROUTING_INFO_SIZE_INIT 256 #ifdef _WIN32 #define VSOMEIP_INTERNAL_BASE_PORT 51234 @@ -98,6 +98,8 @@ #define VSOMEIP_UNREGISTER_EVENT 0x1C #define VSOMEIP_ID_RESPONSE 0x1D #define VSOMEIP_ID_REQUEST 0x1E +#define VSOMEIP_OFFERED_SERVICES_REQUEST 0x1F +#define VSOMEIP_OFFERED_SERVICES_RESPONSE 0x20 #define VSOMEIP_OFFER_SERVICE_COMMAND_SIZE 16 #define VSOMEIP_REQUEST_SERVICE_COMMAND_SIZE 17 @@ -111,6 +113,7 @@ #define VSOMEIP_UNREGISTER_EVENT_COMMAND_SIZE 14 #define VSOMEIP_ID_RESPONSE_COMMAND_SIZE 12 #define VSOMEIP_ID_REQUEST_COMMAND_SIZE 13 +#define VSOMEIP_OFFERED_SERVICES_COMMAND_SIZE 8 #ifndef _WIN32 #include <pthread.h> diff --git a/implementation/configuration/src/configuration_impl.cpp b/implementation/configuration/src/configuration_impl.cpp index 78c4535..706f389 100644 --- a/implementation/configuration/src/configuration_impl.cpp +++ b/implementation/configuration/src/configuration_impl.cpp @@ -2065,6 +2065,24 @@ std::shared_ptr<client> configuration_impl::find_client(service_t _service, return its_client; } +bool configuration_impl::is_event_reliable(service_t _service, + instance_t _instance, event_t _event) const { + bool is_reliable(false); + auto its_service = find_service(_service, _instance); + if (its_service) { + auto its_event = its_service->events_.find(_event); + if (its_event != its_service->events_.end()) { + return its_event->second->is_reliable_; + } else { + if (its_service->reliable_ != ILLEGAL_PORT && + its_service->unreliable_ == ILLEGAL_PORT) { + is_reliable = true; + } + } + } + return is_reliable; +} + std::shared_ptr<service> configuration_impl::find_service(service_t _service, instance_t _instance) const { std::shared_ptr<service> its_service; diff --git a/implementation/endpoints/include/udp_server_endpoint_impl.hpp b/implementation/endpoints/include/udp_server_endpoint_impl.hpp index 50b5dda..787a824 100644 --- a/implementation/endpoints/include/udp_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/udp_server_endpoint_impl.hpp @@ -12,6 +12,7 @@ #include <vsomeip/defines.hpp>
#include "server_endpoint_impl.hpp"
+#include <atomic>
namespace vsomeip {
@@ -57,6 +58,7 @@ public: private:
void set_broadcast();
bool is_joined(const std::string &_address) const;
+ bool is_joined(const std::string &_address, bool* _received) const;
private:
socket_type socket_;
@@ -65,7 +67,8 @@ private: mutable std::mutex default_targets_mutex_;
std::map<service_t, endpoint_type> default_targets_;
mutable std::mutex joined_mutex_;
- std::set<std::string> joined_;
+ std::map<std::string, bool> joined_;
+ std::atomic<bool> joined_group_;
message_buffer_t recv_buffer_;
std::mutex socket_mutex_;
diff --git a/implementation/endpoints/src/udp_client_endpoint_impl.cpp b/implementation/endpoints/src/udp_client_endpoint_impl.cpp index 1d28b98..ec4106d 100644 --- a/implementation/endpoints/src/udp_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/udp_client_endpoint_impl.cpp @@ -46,7 +46,7 @@ void udp_client_endpoint_impl::connect() { boost::system::error_code its_bind_error;
socket_->bind(local_, its_bind_error);
if(its_bind_error) {
- VSOMEIP_WARNING << "tcp_client_endpoint::connect: "
+ VSOMEIP_WARNING << "udp_client_endpoint::connect: "
"Error binding socket: " << its_bind_error.message();
}
}
diff --git a/implementation/endpoints/src/udp_server_endpoint_impl.cpp b/implementation/endpoints/src/udp_server_endpoint_impl.cpp index e21f107..ce1a276 100644 --- a/implementation/endpoints/src/udp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/udp_server_endpoint_impl.cpp @@ -28,6 +28,7 @@ udp_server_endpoint_impl::udp_server_endpoint_impl( : server_endpoint_impl<ip::udp_ext>( _host, _local, _io, VSOMEIP_MAX_UDP_MESSAGE_SIZE), socket_(_io, _local.protocol()), + joined_group_(false), recv_buffer_(VSOMEIP_MAX_UDP_MESSAGE_SIZE, 0), local_port_(_local.port()) { boost::system::error_code ec; @@ -151,10 +152,23 @@ bool udp_server_endpoint_impl::is_joined(const std::string &_address) const { return (joined_.find(_address) != joined_.end()); } +bool udp_server_endpoint_impl::is_joined( + const std::string &_address, bool* _received) const { + *_received = false; + std::lock_guard<std::mutex> its_lock(joined_mutex_); + const auto found_address = joined_.find(_address); + if (found_address != joined_.end()) { + *_received = found_address->second; + } + return (found_address != joined_.end()); +} + void udp_server_endpoint_impl::join(const std::string &_address) { + bool has_received(false); - try { - if (!is_joined(_address)) { + std::function<void(const std::string &)> join_func = + [this](const std::string &_address) { + try { bool is_v4(false); bool is_v6(false); { @@ -191,15 +205,20 @@ void udp_server_endpoint_impl::join(const std::string &_address) { } { std::lock_guard<std::mutex> its_lock(joined_mutex_); - joined_.insert(_address); + joined_[_address] = false; } - } else { - VSOMEIP_INFO << "udp_server_endpoint_impl::join: " - "Trying to join already joined address: " << _address; + joined_group_ = true; + } catch (const std::exception &e) { + VSOMEIP_ERROR << "udp_server_endpoint_impl::join" << ":" << e.what(); } - } - catch (const std::exception &e) { - VSOMEIP_ERROR << __func__ << ":" << e.what(); + }; + + if (!is_joined(_address, &has_received)) { + join_func(_address); + } else if (!has_received) { + // joined the multicast group but didn't receive a event yet -> rejoin + leave(_address); + join_func(_address); } } @@ -225,6 +244,9 @@ void udp_server_endpoint_impl::leave(const std::string &_address) { { std::lock_guard<std::mutex> its_lock(joined_mutex_); joined_.erase(_address); + if (!joined_.size()) { + joined_group_ = false; + } } } } @@ -297,6 +319,8 @@ void udp_server_endpoint_impl::receive_cbk( return; } remaining_bytes -= current_message_size; + service_t its_service = VSOMEIP_BYTES_TO_WORD(recv_buffer_[i + VSOMEIP_SERVICE_POS_MIN], + recv_buffer_[i + VSOMEIP_SERVICE_POS_MAX]); if (utility::is_request( recv_buffer_[i + VSOMEIP_MESSAGE_TYPE_POS])) { client_t its_client; @@ -311,9 +335,16 @@ void udp_server_endpoint_impl::receive_cbk( clients_[its_client][its_session] = remote_; clients_to_endpoint_[its_client] = remote_; clients_mutex_.unlock(); + } else if (its_service != VSOMEIP_SD_SERVICE + && utility::is_notification(recv_buffer_[i + VSOMEIP_MESSAGE_TYPE_POS]) + && joined_group_) { + std::lock_guard<std::mutex> its_lock(joined_mutex_); + boost::system::error_code ec; + const auto found_address = joined_.find(_destination.to_string(ec)); + if (found_address != joined_.end()) { + found_address->second = true; + } } - service_t its_service = VSOMEIP_BYTES_TO_WORD(recv_buffer_[i + VSOMEIP_SERVICE_POS_MIN], - recv_buffer_[i + VSOMEIP_SERVICE_POS_MAX]); if (its_service != VSOMEIP_SD_SERVICE || (current_message_size > VSOMEIP_SOMEIP_HEADER_SIZE && current_message_size >= remaining_bytes)) { diff --git a/implementation/routing/include/event.hpp b/implementation/routing/include/event.hpp index e493eff..a403ae8 100644 --- a/implementation/routing/include/event.hpp +++ b/implementation/routing/include/event.hpp @@ -107,6 +107,9 @@ public: bool is_subscribed(client_t _client); + bool is_reliable() const; + void set_reliable(bool _is_reliable); + private: void update_cbk(boost::system::error_code const &_error); void notify(bool _flush); @@ -146,6 +149,8 @@ private: std::atomic<bool> is_cache_placeholder_; epsilon_change_func_t epsilon_change_func_; + + std::atomic<bool> is_reliable_; }; } // namespace vsomeip diff --git a/implementation/routing/include/eventgroupinfo.hpp b/implementation/routing/include/eventgroupinfo.hpp index 0db929c..6f3e563 100644 --- a/implementation/routing/include/eventgroupinfo.hpp +++ b/implementation/routing/include/eventgroupinfo.hpp @@ -54,6 +54,7 @@ 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 void get_reliability(bool& _has_reliable, bool& _has_unreliable) const; VSOMEIP_EXPORT const std::list<target_t> get_targets() const; VSOMEIP_EXPORT uint32_t get_unreliable_target_count() const; @@ -93,6 +94,9 @@ private: std::atomic<uint8_t> threshold_; std::mutex subscription_mutex_; + + std::atomic<bool> has_reliable_; + std::atomic<bool> has_unreliable_; }; } // namespace vsomeip diff --git a/implementation/routing/include/routing_manager.hpp b/implementation/routing/include/routing_manager.hpp index b14f162..f02c533 100644 --- a/implementation/routing/include/routing_manager.hpp +++ b/implementation/routing/include/routing_manager.hpp @@ -101,7 +101,7 @@ public: virtual void set_routing_state(routing_state_e _routing_state) = 0; - + virtual void send_get_offered_services_info(client_t _client, offer_type_e _offer_type) = 0; }; } // namespace vsomeip diff --git a/implementation/routing/include/routing_manager_base.hpp b/implementation/routing/include/routing_manager_base.hpp index e5d7f11..36b6672 100644 --- a/implementation/routing/include/routing_manager_base.hpp +++ b/implementation/routing/include/routing_manager_base.hpp @@ -123,6 +123,8 @@ public: virtual void register_client_error_handler(client_t _client, const std::shared_ptr<endpoint> &_endpoint) = 0; + virtual void send_get_offered_services_info(client_t _client, offer_type_e _offer_type) = 0; + protected: std::shared_ptr<serviceinfo> find_service(service_t _service, instance_t _instance) const; std::shared_ptr<serviceinfo> create_service_info(service_t _service, @@ -254,6 +256,9 @@ protected: }; std::set<subscription_data_t> pending_subscriptions_; + services_t services_remote_; + std::mutex services_remote_mutex_; + private: services_t services_; mutable std::mutex services_mutex_; diff --git a/implementation/routing/include/routing_manager_host.hpp b/implementation/routing/include/routing_manager_host.hpp index 532b0db..b282d75 100644 --- a/implementation/routing/include/routing_manager_host.hpp +++ b/implementation/routing/include/routing_manager_host.hpp @@ -39,6 +39,7 @@ public: virtual void on_subscription_status(service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event, uint16_t _error) = 0; virtual void send(std::shared_ptr<message> _message, bool _flush) = 0; + virtual void on_offered_services_info(std::vector<std::pair<service_t, instance_t>> &_services) = 0; }; } // namespace vsomeip diff --git a/implementation/routing/include/routing_manager_impl.hpp b/implementation/routing/include/routing_manager_impl.hpp index 4b8d78a..c153e5e 100644 --- a/implementation/routing/include/routing_manager_impl.hpp +++ b/implementation/routing/include/routing_manager_impl.hpp @@ -170,6 +170,11 @@ public: std::shared_ptr<eventgroupinfo> find_eventgroup(service_t _service, instance_t _instance, eventgroup_t _eventgroup) const; services_t get_offered_services() const; + std::shared_ptr<serviceinfo> get_offered_service( + service_t _service, instance_t _instance) const; + std::map<instance_t, std::shared_ptr<serviceinfo>> get_offered_service_instances( + service_t _service) const; + std::shared_ptr<endpoint> create_service_discovery_endpoint(const std::string &_address, uint16_t _port, bool _reliable); void init_routing_info(); @@ -212,6 +217,11 @@ public: void set_routing_state(routing_state_e _routing_state); + void send_get_offered_services_info(client_t _client, offer_type_e _offer_type) { + (void) _client; + (void) _offer_type; + } + private: bool deliver_message(const byte_t *_data, length_t _length, instance_t _instance, bool _reliable, bool _is_valid_crc = true); @@ -320,7 +330,7 @@ private: void requested_service_remove(client_t _client, service_t _service, instance_t _instance); - void call_sd_reliable_endpoint_connected(const boost::system::error_code& _error, + void call_sd_endpoint_connected(const boost::system::error_code& _error, service_t _service, instance_t _instance, std::shared_ptr<endpoint> _endpoint, std::shared_ptr<boost::asio::steady_timer> _timer); diff --git a/implementation/routing/include/routing_manager_proxy.hpp b/implementation/routing/include/routing_manager_proxy.hpp index 6d92c39..eed0d6f 100644 --- a/implementation/routing/include/routing_manager_proxy.hpp +++ b/implementation/routing/include/routing_manager_proxy.hpp @@ -99,6 +99,10 @@ public: const std::shared_ptr<endpoint> &_endpoint); void handle_client_error(client_t _client); + void on_offered_services_info(const byte_t *_data, uint32_t _size); + + void send_get_offered_services_info(client_t _client, offer_type_e _offer_type); + private: void register_application(); void deregister_application(); diff --git a/implementation/routing/include/routing_manager_stub.hpp b/implementation/routing/include/routing_manager_stub.hpp index 385c9cf..1737d6f 100644 --- a/implementation/routing/include/routing_manager_stub.hpp +++ b/implementation/routing/include/routing_manager_stub.hpp @@ -128,6 +128,15 @@ private: minor_version_t _minor = ANY_MINOR); void send_client_routing_info(const client_t _target); + void create_offered_services_info(const client_t _target); + void insert_offered_services_info(client_t _target, + routing_info_entry_e _entry, + service_t _service, + instance_t _instance, + major_version_t _major, + minor_version_t _minor); + void send_offered_services_info(const client_t _target); + void on_client_id_timer_expired(boost::system::error_code const &_error); private: @@ -170,6 +179,7 @@ private: std::map<client_t, std::set<client_t>> connection_matrix_; std::map<client_t, std::vector<byte_t>> client_routing_info_; + std::map<client_t, std::vector<byte_t>> offered_services_info_; }; } // namespace vsomeip diff --git a/implementation/routing/src/event.cpp b/implementation/routing/src/event.cpp index 5dd6309..287c50c 100644 --- a/implementation/routing/src/event.cpp +++ b/implementation/routing/src/event.cpp @@ -451,4 +451,12 @@ bool event::is_subscribed(client_t _client) { return false; } +bool event::is_reliable() const { + return is_reliable_; +} + +void event::set_reliable(bool _is_reliable) { + is_reliable_ = _is_reliable; +} + } // namespace vsomeip diff --git a/implementation/routing/src/eventgroupinfo.cpp b/implementation/routing/src/eventgroupinfo.cpp index 2f02a5c..c6635dc 100644 --- a/implementation/routing/src/eventgroupinfo.cpp +++ b/implementation/routing/src/eventgroupinfo.cpp @@ -9,16 +9,19 @@ #include "../include/eventgroupinfo.hpp" +#include "../include/event.hpp" #include "../../endpoints/include/endpoint_definition.hpp" namespace vsomeip { eventgroupinfo::eventgroupinfo() - : major_(DEFAULT_MAJOR), ttl_(DEFAULT_TTL), port_(ILLEGAL_PORT), threshold_(0) { + : major_(DEFAULT_MAJOR), ttl_(DEFAULT_TTL), port_(ILLEGAL_PORT), threshold_(0), + has_reliable_(false), has_unreliable_(false) { } eventgroupinfo::eventgroupinfo(major_version_t _major, ttl_t _ttl) - : major_(_major), ttl_(_ttl), port_(ILLEGAL_PORT), threshold_(0) { + : major_(_major), ttl_(_ttl), port_(ILLEGAL_PORT), threshold_(0), + has_reliable_(false), has_unreliable_(false) { } eventgroupinfo::~eventgroupinfo() { @@ -77,6 +80,7 @@ const std::set<std::shared_ptr<event> > eventgroupinfo::get_events() const { void eventgroupinfo::add_event(std::shared_ptr<event> _event) { std::lock_guard<std::mutex> its_lock(events_mutex_); events_.insert(_event); + _event->is_reliable() ? has_reliable_ = true : has_unreliable_ = true; } void eventgroupinfo::remove_event(std::shared_ptr<event> _event) { @@ -84,6 +88,11 @@ void eventgroupinfo::remove_event(std::shared_ptr<event> _event) { events_.erase(_event); } +void eventgroupinfo::get_reliability(bool& _has_reliable, bool& _has_unreliable) const { + _has_reliable = has_reliable_; + _has_unreliable = has_unreliable_; +} + const std::list<eventgroupinfo::target_t> eventgroupinfo::get_targets() const { std::lock_guard<std::mutex> its_lock(targets_mutex_); return targets_; diff --git a/implementation/routing/src/routing_manager_base.cpp b/implementation/routing/src/routing_manager_base.cpp index 19d1b86..3aa33f5 100644 --- a/implementation/routing/src/routing_manager_base.cpp +++ b/implementation/routing/src/routing_manager_base.cpp @@ -202,6 +202,7 @@ void routing_manager_base::register_event(client_t _client, service_t _service, } } else { its_event = std::make_shared<event>(this, _is_shadow); + its_event->set_reliable(configuration_->is_event_reliable(_service, _instance, _event)); its_event->set_service(_service); its_event->set_instance(_instance); its_event->set_event(_event); @@ -529,10 +530,16 @@ bool routing_manager_base::send(client_t its_client, std::shared_ptr<serviceinfo> routing_manager_base::create_service_info( service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor, ttl_t _ttl, bool _is_local_service) { - std::lock_guard<std::mutex> its_lock(services_mutex_); std::shared_ptr<serviceinfo> its_info = std::make_shared<serviceinfo>(_major, _minor, _ttl, _is_local_service); - services_[_service][_instance] = its_info; + { + std::lock_guard<std::mutex> its_lock(services_mutex_); + services_[_service][_instance] = its_info; + } + if (!_is_local_service) { + std::lock_guard<std::mutex> its_lock(services_remote_mutex_); + services_remote_[_service][_instance] = its_info; + } return its_info; } @@ -557,30 +564,39 @@ void routing_manager_base::clear_service_info(service_t _service, instance_t _in return; } - std::lock_guard<std::mutex> its_lock(services_mutex_); - - // 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); + bool deleted_instance(false); + bool deleted_service(false); + { + std::lock_guard<std::mutex> its_lock(services_mutex_); + + // 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); + deleted_service = true; + } else { + services_[_service].erase(_instance); + deleted_instance = true; + } } else { - services_[_service].erase(_instance); + its_info->set_endpoint(its_empty_endpoint, _reliable); + } + } + + if ((deleted_instance || deleted_service) && !its_info->is_local()) { + std::lock_guard<std::mutex> its_lock(services_remote_mutex_); + if (deleted_service) { + services_remote_.erase(_service); + } else if (deleted_instance) { + services_remote_[_service].erase(_instance); } - } else { - its_info->set_endpoint(its_empty_endpoint, _reliable); } } services_t routing_manager_base::get_services() const { - services_t its_offers; std::lock_guard<std::mutex> its_lock(services_mutex_); - for (auto s : services_) { - for (auto i : s.second) { - its_offers[s.first][i.first] = i.second; - } - } - return (its_offers); + return services_; } bool routing_manager_base::is_available(service_t _service, instance_t _instance, @@ -672,7 +688,7 @@ std::shared_ptr<endpoint> routing_manager_base::find_local(client_t _client) { } std::shared_ptr<endpoint> routing_manager_base::find_or_create_local(client_t _client) { - std::lock_guard<std::mutex> its_lock(local_endpoint_mutex_); + std::lock_guard<std::mutex> its_lock(local_endpoint_mutex_); std::shared_ptr<endpoint> its_endpoint(find_local_unlocked(_client)); if (!its_endpoint) { its_endpoint = create_local_unlocked(_client); diff --git a/implementation/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp index 1c48ca3..8d03d75 100644 --- a/implementation/routing/src/routing_manager_impl.cpp +++ b/implementation/routing/src/routing_manager_impl.cpp @@ -434,19 +434,8 @@ void routing_manager_impl::subscribe(client_t _client, service_t _service, eventgroup_lock.unlock(); } static const ttl_t configured_ttl(configuration_->get_sd_ttl()); - std::uint8_t number_notify_initially(1); - if (_subscription_type == subscription_type_e::SU_RELIABLE_AND_UNRELIABLE && - remote_service_offered_via_tcp_and_udp(_service, _instance)) { - // to be consistent with remote initial events clients - // which want to subscribe via TCP and UDP need to get - // two initial events if the service is offered via TCP - // and UDP - number_notify_initially = 2; - } - for (std::uint8_t i = 0; i < number_notify_initially; i++) { - notify_one_current_value(_client, _service, _instance, - _eventgroup, _event, its_already_subscribed_events); - } + notify_one_current_value(_client, _service, _instance, + _eventgroup, _event, its_already_subscribed_events); discovery_->subscribe(_service, _instance, _eventgroup, _major, configured_ttl, subscriber, _subscription_type); } else { @@ -661,6 +650,10 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, // we need both endpoints as clients can subscribe to events via TCP and UDP std::shared_ptr<endpoint> its_udp_server_endpoint = its_info->get_endpoint(false); std::shared_ptr<endpoint> its_tcp_server_endpoint = its_info->get_endpoint(true); + bool is_offered_both(false); + if (its_udp_server_endpoint && its_tcp_server_endpoint) { + is_offered_both = true; + } if (its_udp_server_endpoint || its_tcp_server_endpoint) { for (auto its_group : its_event->get_eventgroups()) { auto its_eventgroup = find_eventgroup(its_service, _instance, its_group); @@ -668,15 +661,21 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, // Unicast targets for (const auto &its_remote : its_eventgroup->get_targets()) { if(its_remote.endpoint_->is_reliable() && its_tcp_server_endpoint) { - its_targets.insert(its_remote.endpoint_); + if (!is_offered_both || (is_offered_both && its_event->is_reliable())) { + its_targets.insert(its_remote.endpoint_); + } } else if (its_udp_server_endpoint && !its_eventgroup->is_sending_multicast()) { - its_targets.insert(its_remote.endpoint_); + if (!is_offered_both || (is_offered_both && !its_event->is_reliable())) { + its_targets.insert(its_remote.endpoint_); + } } } // Send to multicast targets if subscribers are still interested if (its_eventgroup->is_sending_multicast()) { for (auto its_multicast_target : its_eventgroup->get_multicast_targets()) { - its_targets.insert(its_multicast_target.endpoint_); + if (!is_offered_both || (is_offered_both && !its_event->is_reliable())) { + its_targets.insert(its_multicast_target.endpoint_); + } } } } @@ -883,21 +882,25 @@ void routing_manager_impl::notify_one(service_t _service, instance_t _instance, } } if (found_eventgroup) { + std::set<std::shared_ptr<endpoint_definition>> its_targets; // Now set event's payload! // Either with endpoint_definition (remote) or with client (local). - std::lock_guard<std::mutex> its_lock(remote_subscribers_mutex_); - auto its_service = remote_subscribers_.find(_service); - if (its_service != remote_subscribers_.end()) { - auto its_instance = its_service->second.find(_instance); - if (its_instance != its_service->second.end()) { - auto its_subscriber = its_instance->second.find(_client); - if (its_subscriber != its_instance->second.end()) { - for (auto its_target : its_subscriber->second) { - its_event->set_payload(_payload, its_target, _force, _flush); + { + std::lock_guard<std::mutex> its_lock(remote_subscribers_mutex_); + auto its_service = remote_subscribers_.find(_service); + if (its_service != remote_subscribers_.end()) { + auto its_instance = its_service->second.find(_instance); + if (its_instance != its_service->second.end()) { + auto its_subscriber = its_instance->second.find(_client); + if (its_subscriber != its_instance->second.end()) { + its_targets = its_subscriber->second; } } } } + for (const auto &its_target : its_targets) { + its_event->set_payload(_payload, its_target, _force, _flush); + } } } else { VSOMEIP_WARNING << "Attempt to update the undefined event/field [" @@ -1129,10 +1132,30 @@ void routing_manager_impl::on_notification(client_t _client, } } + bool is_offered_both(false); + if (configuration_->get_reliable_port(_service, _instance) != ILLEGAL_PORT && + configuration_->get_unreliable_port(_service, _instance) != ILLEGAL_PORT) { + is_offered_both = true; + } for (const auto &its_eventgroup : its_eventgroupinfos) { //Unicast targets for (auto its_remote : its_eventgroup->get_targets()) { - its_event->set_payload(its_payload, its_remote.endpoint_, true, true); + if (!is_offered_both) { + its_event->set_payload(its_payload, its_remote.endpoint_, true, true); + } else { + bool was_set(false); + if (its_event->is_reliable() && its_remote.endpoint_->is_reliable()) { + its_event->set_payload(its_payload, its_remote.endpoint_, true, true); + was_set = true; + } + if (!its_event->is_reliable() && !its_remote.endpoint_->is_reliable()) { + its_event->set_payload(its_payload, its_remote.endpoint_, true, true); + was_set = true; + } + if (!was_set) { + its_event->set_payload_dont_notify(its_payload); + } + } } } } @@ -1201,21 +1224,21 @@ void routing_manager_impl::on_connect(std::shared_ptr<endpoint> _endpoint) { if (s.reliable_) { stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, s.service_id_, s.instance_id_, s.major_, s.minor_); - std::shared_ptr<boost::asio::steady_timer> its_timer = - std::make_shared<boost::asio::steady_timer>(io_); - boost::system::error_code ec; - its_timer->expires_from_now(std::chrono::milliseconds(3), ec); - if (!ec) { - its_timer->async_wait( - std::bind( - &routing_manager_impl::call_sd_reliable_endpoint_connected, - std::static_pointer_cast<routing_manager_impl>( - shared_from_this()), - std::placeholders::_1, s.service_id_, - s.instance_id_, s.endpoint_, its_timer)); - } else { - VSOMEIP_ERROR<< "routing_manager_impl::on_connect: " << ec.message(); - } + } + std::shared_ptr<boost::asio::steady_timer> its_timer = + std::make_shared<boost::asio::steady_timer>(io_); + boost::system::error_code ec; + its_timer->expires_from_now(std::chrono::milliseconds(3), ec); + if (!ec) { + its_timer->async_wait( + std::bind( + &routing_manager_impl::call_sd_endpoint_connected, + std::static_pointer_cast<routing_manager_impl>( + shared_from_this()), + std::placeholders::_1, s.service_id_, + s.instance_id_, s.endpoint_, its_timer)); + } else { + VSOMEIP_ERROR<< "routing_manager_impl::on_connect: " << ec.message(); } } } @@ -1506,6 +1529,31 @@ services_t routing_manager_impl::get_offered_services() const { return its_services; } +std::shared_ptr<serviceinfo> routing_manager_impl::get_offered_service( + service_t _service, instance_t _instance) const { + std::shared_ptr<serviceinfo> its_info; + its_info = find_service(_service, _instance); + if (its_info && !its_info->is_local()) { + its_info.reset(); + } + return its_info; +} + +std::map<instance_t, std::shared_ptr<serviceinfo>> +routing_manager_impl::get_offered_service_instances(service_t _service) const { + std::map<instance_t, std::shared_ptr<serviceinfo>> its_instances; + const services_t its_services(get_services()); + const auto found_service = its_services.find(_service); + if (found_service != its_services.end()) { + for (const auto i : found_service->second) { + if (i.second->is_local()) { + its_instances[i.first] = i.second; + } + } + } + return its_instances; +} + std::shared_ptr<endpoint> routing_manager_impl::find_or_create_remote_client( service_t _service, instance_t _instance, bool _reliable, client_t _client) { std::shared_ptr<endpoint> its_endpoint; @@ -1981,13 +2029,24 @@ void routing_manager_impl::add_routing_info( } } + bool udp_inserted(false); + // Add endpoint(s) if necessary if (_reliable_port != ILLEGAL_PORT && !is_reliable_known) { - std::shared_ptr<endpoint_definition> endpoint_def + std::shared_ptr<endpoint_definition> endpoint_def_tcp = endpoint_definition::get(_reliable_address, _reliable_port, true); - { + if (_unreliable_port != ILLEGAL_PORT && !is_unreliable_known) { + std::shared_ptr<endpoint_definition> endpoint_def_udp + = endpoint_definition::get(_unreliable_address, _unreliable_port, false); + { + std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_); + remote_service_info_[_service][_instance][false] = endpoint_def_udp; + remote_service_info_[_service][_instance][true] = endpoint_def_tcp; + } + udp_inserted = true; + } else { std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_); - remote_service_info_[_service][_instance][true] = endpoint_def; + remote_service_info_[_service][_instance][true] = endpoint_def_tcp; } // check if service was requested and establish TCP connection if necessary @@ -2050,7 +2109,7 @@ void routing_manager_impl::add_routing_info( its_info->get_major(), its_info->get_minor()); if (discovery_) { - discovery_->on_reliable_endpoint_connected( + discovery_->on_endpoint_connected( _service, _instance, its_info->get_endpoint(true)); } @@ -2064,16 +2123,23 @@ void routing_manager_impl::add_routing_info( } if (_unreliable_port != ILLEGAL_PORT && !is_unreliable_known) { - std::shared_ptr<endpoint_definition> endpoint_def - = endpoint_definition::get(_unreliable_address, _unreliable_port, false); - { - std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_); - remote_service_info_[_service][_instance][false] = endpoint_def; + if (!udp_inserted) { + std::shared_ptr<endpoint_definition> endpoint_def + = endpoint_definition::get(_unreliable_address, _unreliable_port, false); + { + std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_); + remote_service_info_[_service][_instance][false] = endpoint_def; + } } if (!is_reliable_known) { on_availability(_service, _instance, true, _major, _minor); stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance, _major, _minor); } + if (discovery_) { + discovery_->on_endpoint_connected( + _service, _instance, + its_info->get_endpoint(false)); + } } } @@ -2140,44 +2206,45 @@ void routing_manager_impl::del_routing_info(service_t _service, instance_t _inst } std::chrono::milliseconds routing_manager_impl::update_routing_info(std::chrono::milliseconds _elapsed) { - std::chrono::seconds default_ttl(DEFAULT_TTL); + const std::chrono::seconds default_ttl(DEFAULT_TTL); std::chrono::milliseconds its_smallest_ttl = std::chrono::duration_cast<std::chrono::milliseconds>(default_ttl); std::map<service_t, std::map<instance_t, std::pair<bool, bool> > > its_expired_offers; - for (auto &s : get_services()) { - for (auto &i : s.second) { - if (i.second->is_local()) { - continue; //don't expire local services - } - ttl_t its_ttl = i.second->get_ttl(); - std::chrono::milliseconds precise_ttl = i.second->get_precise_ttl(); - if (its_ttl < DEFAULT_TTL) { // do not touch "forever" - if (precise_ttl.count() < _elapsed.count() || precise_ttl.count() == 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 { - std::chrono::milliseconds its_new_ttl(precise_ttl - _elapsed); - i.second->set_precise_ttl(its_new_ttl); - if (its_smallest_ttl > its_new_ttl) - its_smallest_ttl = its_new_ttl; + { + std::lock_guard<std::mutex> its_lock(services_remote_mutex_); + for (const auto &s : services_remote_) { + for (const auto &i : s.second) { + ttl_t its_ttl = i.second->get_ttl(); + if (its_ttl < DEFAULT_TTL) { // do not touch "forever" + std::chrono::milliseconds precise_ttl = i.second->get_precise_ttl(); + if (precise_ttl.count() < _elapsed.count() || precise_ttl.count() == 0) { + i.second->set_ttl(0); + its_expired_offers[s.first][i.first] = { + i.second->get_endpoint(true) != nullptr, + i.second->get_endpoint(false) != nullptr + }; + } else { + std::chrono::milliseconds its_new_ttl(precise_ttl - _elapsed); + i.second->set_precise_ttl(its_new_ttl); + if (its_smallest_ttl > its_new_ttl) + its_smallest_ttl = its_new_ttl; + } } } } } - for (auto &s : its_expired_offers) { - for (auto &i : s.second) { + for (const auto &s : its_expired_offers) { + for (const auto &i : s.second) { + if (discovery_) { + discovery_->unsubscribe_all(s.first, i.first); + } + del_routing_info(s.first, i.first, i.second.first, i.second.second); VSOMEIP_INFO << "update_routing_info: elapsed=" << _elapsed.count() << " : delete service/instance " << std::hex << s.first << "/" << i.first; - del_routing_info(s.first, i.first, i.second.first, i.second.second); } } @@ -2407,8 +2474,22 @@ void routing_manager_impl::on_subscribe( } // send initial events if we already have a cached field (is_set) for (auto its_event : its_eventgroup->get_events()) { + bool is_offered_both(false); + if (configuration_->get_reliable_port(_service, _instance) != ILLEGAL_PORT && + configuration_->get_unreliable_port(_service, _instance) != ILLEGAL_PORT) { + is_offered_both = true; + } if (its_event->is_field() && its_event->is_set()) { - its_event->notify_one(_subscriber, true); // TODO: use _flush parameter to send all event at once + if (!is_offered_both) { + its_event->notify_one(_subscriber, true); + } else { + if (its_event->is_reliable() && _subscriber->is_reliable()) { + its_event->notify_one(_subscriber, true); + } + if (!its_event->is_reliable() && !_subscriber->is_reliable()) { + its_event->notify_one(_subscriber, true); + } + } } } stub_->send_subscribe(find_local(_service, _instance), @@ -2425,15 +2506,6 @@ void routing_manager_impl::on_unsubscribe(service_t _service, if (its_eventgroup) { client_t its_client = find_client(_service, _instance, its_eventgroup, _target); - VSOMEIP_INFO << "REMOTE UNSUBSCRIBE(" - << std::hex << std::setw(4) << std::setfill('0') << its_client <<"): [" - << std::hex << std::setw(4) << std::setfill('0') << _service << "." - << std::hex << std::setw(4) << std::setfill('0') << _instance << "." - << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "]" - << " from " << _target->get_address().to_string() - << ":" << std::dec <<_target->get_port() - << (_target->is_reliable() ? " reliable" : " unreliable"); - its_eventgroup->remove_target(_target); clear_remote_subscriber(_service, _instance, its_client, _target); @@ -2451,6 +2523,14 @@ void routing_manager_impl::on_unsubscribe(service_t _service, } } } + VSOMEIP_INFO << "REMOTE UNSUBSCRIBE(" + << std::hex << std::setw(4) << std::setfill('0') << its_client <<"): [" + << std::hex << std::setw(4) << std::setfill('0') << _service << "." + << std::hex << std::setw(4) << std::setfill('0') << _instance << "." + << std::hex << std::setw(4) << std::setfill('0') << _eventgroup << "]" + << " from " << _target->get_address().to_string() + << ":" << std::dec <<_target->get_port() + << (_target->is_reliable() ? " reliable" : " unreliable"); } else { VSOMEIP_ERROR << "REMOTE UNSUBSCRIBE: attempt to subscribe to unknown eventgroup [" @@ -2467,34 +2547,37 @@ void routing_manager_impl::on_subscribe_ack(service_t _service, instance_t _instance, const boost::asio::ip::address &_address, uint16_t _port) { + bool multicast_known(false); { std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_); - 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]; + const auto found_service = multicast_info.find(_service); + if (found_service != multicast_info.end()) { + const auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + const auto& endpoint_def = found_instance->second; 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; + multicast_known = true; } } } - - // 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; + if (!multicast_known) { + // 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); + const 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) { - { + if (!multicast_known) { std::lock_guard<std::recursive_mutex> its_lock(endpoint_mutex_); service_instances_[_service][its_endpoint.get()] = _instance; } @@ -2542,11 +2625,16 @@ void routing_manager_impl::on_subscribe_ack(client_t _client, } for (auto its_subscriber : subscribed_clients) { if (its_subscriber == get_client()) { - host_->on_subscription_error(_service, _instance, _eventgroup, 0x0 /*OK*/); - host_->on_subscription_status(_service, _instance, _eventgroup, _event, 0x0 /*OK*/); + host_->on_subscription_error(_service, _instance, + _eventgroup, 0x0 /*OK*/); + for (auto its_event : its_eventgroup->get_events()) { + host_->on_subscription_status(_service, _instance, + _eventgroup, its_event->get_event(), + 0x0 /*OK*/); + } } else { - stub_->send_subscribe_ack(its_subscriber, _service, _instance, - _eventgroup, _event); + stub_->send_subscribe_ack(its_subscriber, _service, + _instance, _eventgroup, _event); } } } @@ -2590,11 +2678,16 @@ void routing_manager_impl::on_subscribe_nack(client_t _client, } for (auto its_subscriber : subscribed_clients) { if (its_subscriber == get_client()) { - host_->on_subscription_error(_service, _instance, _eventgroup, 0x7 /*Rejected*/); - host_->on_subscription_status(_service, _instance, _eventgroup, _event, 0x7 /*Rejected*/); + host_->on_subscription_error(_service, _instance, + _eventgroup, 0x7 /*Rejected*/); + for (auto its_event : its_eventgroup->get_events()) { + host_->on_subscription_status(_service, _instance, + _eventgroup, its_event->get_event(), + 0x7 /*Rejected*/); + } } else { - stub_->send_subscribe_nack(its_subscriber, _service, _instance, - _eventgroup, _event); + stub_->send_subscribe_nack(its_subscriber, _service, + _instance, _eventgroup, _event); } } } @@ -2924,7 +3017,6 @@ void routing_manager_impl::on_identify_response(client_t _client, service_t _ser void routing_manager_impl::identify_for_subscribe(client_t _client, service_t _service, instance_t _instance, major_version_t _major, subscription_type_e _subscription_type) { - if (_subscription_type == subscription_type_e::SU_RELIABLE_AND_UNRELIABLE || _subscription_type == subscription_type_e::SU_PREFER_UNRELIABLE || _subscription_type == subscription_type_e::SU_UNRELIABLE) { @@ -2962,6 +3054,11 @@ bool routing_manager_impl::send_identify_message(client_t _client, auto its_endpoint = find_or_create_remote_client(_service, _instance, _reliable, _client); if (!its_endpoint) { + VSOMEIP_WARNING << "routing_manager_impl::send_identify_message: " + << "No " << (_reliable ? "reliable" : "unreliable") + << " route for identify message to service/instance " + << std::hex << _service << "/" << _instance << " for client " + << _client; return false; } { @@ -3741,7 +3838,7 @@ routing_manager_impl::get_subscribed_eventgroups( return its_eventgroups; } -void routing_manager_impl::call_sd_reliable_endpoint_connected( +void routing_manager_impl::call_sd_endpoint_connected( const boost::system::error_code& _error, service_t _service, instance_t _instance, std::shared_ptr<endpoint> _endpoint, @@ -3751,7 +3848,7 @@ void routing_manager_impl::call_sd_reliable_endpoint_connected( return; } if (discovery_) { - discovery_->on_reliable_endpoint_connected(_service, _instance, + discovery_->on_endpoint_connected(_service, _instance, _endpoint); } } diff --git a/implementation/routing/src/routing_manager_proxy.cpp b/implementation/routing/src/routing_manager_proxy.cpp index 309d220..d94ae69 100644 --- a/implementation/routing/src/routing_manager_proxy.cpp +++ b/implementation/routing/src/routing_manager_proxy.cpp @@ -1079,6 +1079,16 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size, break; + case VSOMEIP_OFFERED_SERVICES_RESPONSE: + if (!configuration_->is_security_enabled() ||_bound_client == routing_host_id) { + on_offered_services_info(&_data[VSOMEIP_COMMAND_PAYLOAD_POS], its_length); + } else { + VSOMEIP_WARNING << std::hex << "Security: Client 0x" << get_client() + << " received an offered services info from a client which isn't the routing manager" + << " : Skip message!"; + } + break; + default: break; } @@ -1287,6 +1297,57 @@ void routing_manager_proxy::on_routing_info(const byte_t *_data, } } +void routing_manager_proxy::on_offered_services_info(const byte_t *_data, + uint32_t _size) { +#if 0 + std::stringstream msg; + msg << "rmp::on_offered_services_info(" << std::hex << client_ << "): "; + for (uint32_t i = 0; i < _size; ++i) + msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; + VSOMEIP_INFO << msg.str(); +#endif + + std::vector<std::pair<service_t, instance_t>> its_offered_services_info; + + uint32_t i = 0; + while (i + sizeof(uint32_t) + sizeof(routing_info_entry_e) <= _size) { + routing_info_entry_e routing_info_entry; + std::memcpy(&routing_info_entry, &_data[i], sizeof(routing_info_entry_e)); + i += uint32_t(sizeof(routing_info_entry_e)); + + uint32_t its_service_entry_size; + std::memcpy(&its_service_entry_size, &_data[i], sizeof(uint32_t)); + i += uint32_t(sizeof(uint32_t)); + + if (its_service_entry_size + i > _size) { + VSOMEIP_WARNING << "Client 0x" << std::hex << get_client() << " : " + << "Processing of offered services info failed due to bad length fields!"; + return; + } + + if (its_service_entry_size >= sizeof(service_t) + sizeof(instance_t) + sizeof(major_version_t) + sizeof(minor_version_t)) { + service_t its_service; + std::memcpy(&its_service, &_data[i], sizeof(service_t)); + i += uint32_t(sizeof(service_t)); + + instance_t its_instance; + std::memcpy(&its_instance, &_data[i], sizeof(instance_t)); + i += uint32_t(sizeof(instance_t)); + + major_version_t its_major; + std::memcpy(&its_major, &_data[i], sizeof(major_version_t)); + i += uint32_t(sizeof(major_version_t)); + + minor_version_t its_minor; + std::memcpy(&its_minor, &_data[i], sizeof(minor_version_t)); + i += uint32_t(sizeof(minor_version_t)); + + its_offered_services_info.push_back(std::make_pair(its_service, its_instance)); + } + } + host_->on_offered_services_info(its_offered_services_info); +} + void routing_manager_proxy::reconnect(const std::unordered_set<client_t> &_clients) { // inform host about its own registration state changes host_->on_state(static_cast<state_type_e>(inner_state_type_e::ST_DEREGISTERED)); @@ -1838,4 +1899,26 @@ void routing_manager_proxy::handle_client_error(client_t _client) { } } +void routing_manager_proxy::send_get_offered_services_info(client_t _client, offer_type_e _offer_type) { + (void)_client; + + byte_t its_command[VSOMEIP_OFFERED_SERVICES_COMMAND_SIZE]; + uint32_t its_size = VSOMEIP_OFFERED_SERVICES_COMMAND_SIZE + - VSOMEIP_COMMAND_HEADER_SIZE; + + its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_OFFERED_SERVICES_REQUEST; + 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], &_offer_type, + sizeof(_offer_type)); + + std::lock_guard<std::mutex> its_lock(sender_mutex_); + if (sender_) { + sender_->send(its_command, sizeof(its_command)); + } +} + + } // namespace vsomeip diff --git a/implementation/routing/src/routing_manager_stub.cpp b/implementation/routing/src/routing_manager_stub.cpp index 2ce4d63..0f3d0b5 100644 --- a/implementation/routing/src/routing_manager_stub.cpp +++ b/implementation/routing/src/routing_manager_stub.cpp @@ -228,7 +228,7 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, client_t its_target_client; client_t its_subscriber; bool its_is_valid_crc(true); - + offer_type_e its_offer_type; its_command = _data[VSOMEIP_COMMAND_TYPE_POS]; std::memcpy(&its_client, &_data[VSOMEIP_COMMAND_CLIENT_POS], @@ -623,6 +623,57 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, VSOMEIP_INFO << "REGISTERED_ACK(" << std::hex << std::setw(4) << std::setfill('0') << its_client << ")"; break; + case VSOMEIP_OFFERED_SERVICES_REQUEST: + if (_size != VSOMEIP_OFFERED_SERVICES_COMMAND_SIZE) { + VSOMEIP_WARNING << "Received a VSOMEIP_OFFERED_SERVICES_REQUEST command with wrong size ~> skip!"; + break; + } + + std::memcpy(&its_offer_type, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], + sizeof(its_offer_type)); + + std::lock_guard<std::mutex> its_guard(routing_info_mutex_); + create_offered_services_info(its_client); + + for (auto found_client : routing_info_) { + // skip services which are offered on remote hosts + if (found_client.first != VSOMEIP_ROUTING_CLIENT) { + for (const auto &its_service : found_client.second.second) { + for (const auto &its_instance : its_service.second) { + uint16_t its_reliable_port = configuration_->get_reliable_port(its_service.first, + its_instance.first); + uint16_t its_unreliable_port = configuration_->get_unreliable_port( + its_service.first, its_instance.first); + + if (its_offer_type == offer_type_e::OT_LOCAL) { + if (its_reliable_port == ILLEGAL_PORT + && its_unreliable_port == ILLEGAL_PORT) { + insert_offered_services_info(its_client, + routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, + its_service.first, its_instance.first, + its_instance.second.first, its_instance.second.second); + } + } + else if (its_offer_type == offer_type_e::OT_REMOTE) { + if (its_reliable_port != ILLEGAL_PORT + || its_unreliable_port != ILLEGAL_PORT) { + insert_offered_services_info(its_client, + routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, + its_service.first, its_instance.first, + its_instance.second.first, its_instance.second.second); + } + } else if (its_offer_type == offer_type_e::OT_ALL) { + insert_offered_services_info(its_client, + routing_info_entry_e::RIE_ADD_SERVICE_INSTANCE, + its_service.first, its_instance.first, + its_instance.second.first, its_instance.second.second); + } + } + } + } + } + send_offered_services_info(its_client); + break; } } } @@ -879,6 +930,27 @@ void routing_manager_stub::create_client_routing_info(const client_t _target) { client_routing_info_[_target] = its_command; } +void routing_manager_stub::create_offered_services_info(const client_t _target) { + std::vector<byte_t> its_command; + its_command.push_back(VSOMEIP_OFFERED_SERVICES_RESPONSE); + + // Sender client + client_t client = get_client(); + for (uint32_t i = 0; i < sizeof(client_t); ++i) { + its_command.push_back( + reinterpret_cast<const byte_t*>(&client)[i]); + } + + // Overall size placeholder + byte_t size_placeholder = 0x0; + for (uint32_t i = 0; i < sizeof(uint32_t); ++i) { + its_command.push_back(size_placeholder); + } + + offered_services_info_[_target] = its_command; +} + + void routing_manager_stub::send_client_routing_info(const client_t _target) { if (client_routing_info_.find(_target) == client_routing_info_.end()) { return; @@ -915,6 +987,43 @@ void routing_manager_stub::send_client_routing_info(const client_t _target) { } } + +void routing_manager_stub::send_offered_services_info(const client_t _target) { + if (offered_services_info_.find(_target) == offered_services_info_.end()) { + return; + } + std::shared_ptr<endpoint> its_endpoint = host_->find_local(_target); + if (its_endpoint) { + auto its_command = offered_services_info_[_target]; + + // File overall size + std::size_t its_size = its_command.size() - VSOMEIP_COMMAND_PAYLOAD_POS; + std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, sizeof(uint32_t)); + its_size += VSOMEIP_COMMAND_PAYLOAD_POS; + +#if 0 + std::stringstream msg; + msg << "rms::send_offered_services_info to (" << std::hex << _target << "): "; + for (uint32_t i = 0; i < its_size; ++i) + msg << std::hex << std::setw(2) << std::setfill('0') << (int)its_command[i] << " "; + VSOMEIP_INFO << msg.str(); +#endif + + // Send routing info or error! + if(its_command.size() <= max_local_message_size_ + || VSOMEIP_MAX_LOCAL_MESSAGE_SIZE == 0) { + its_endpoint->send(&its_command[0], uint32_t(its_size), true); + } else { + VSOMEIP_ERROR << "Offered services info exceeds maximum message size: Can't send!"; + } + + offered_services_info_.erase(_target); + } else { + VSOMEIP_ERROR << "Send offered services info to client 0x" << std::hex << _target + << " failed: No valid endpoint!"; + } +} + void routing_manager_stub::insert_client_routing_info(client_t _target, routing_info_entry_e _entry, client_t _client, service_t _service, @@ -987,6 +1096,56 @@ void routing_manager_stub::insert_client_routing_info(client_t _target, client_routing_info_[_target] = its_command; } +void routing_manager_stub::insert_offered_services_info(client_t _target, + routing_info_entry_e _entry, + service_t _service, + instance_t _instance, + major_version_t _major, + minor_version_t _minor) { + + if (offered_services_info_.find(_target) == offered_services_info_.end()) { + return; + } + + auto its_command = offered_services_info_[_target]; + + // Routing Info State Change + for (uint32_t i = 0; i < sizeof(routing_info_entry_e); ++i) { + its_command.push_back( + reinterpret_cast<const byte_t*>(&_entry)[i]); + } + + // entry size + uint32_t its_service_entry_size = uint32_t(sizeof(service_t) + + sizeof(instance_t) + sizeof(major_version_t) + sizeof(minor_version_t)); + for (uint32_t i = 0; i < sizeof(its_service_entry_size); ++i) { + its_command.push_back( + reinterpret_cast<const byte_t*>(&its_service_entry_size)[i]); + } + //Service + for (uint32_t i = 0; i < sizeof(service_t); ++i) { + its_command.push_back( + reinterpret_cast<const byte_t*>(&_service)[i]); + } + // Instance + for (uint32_t i = 0; i < sizeof(instance_t); ++i) { + its_command.push_back( + reinterpret_cast<const byte_t*>(&_instance)[i]); + } + // Major version + for (uint32_t i = 0; i < sizeof(major_version_t); ++i) { + its_command.push_back( + reinterpret_cast<const byte_t*>(&_major)[i]); + } + // Minor version + for (uint32_t i = 0; i < sizeof(minor_version_t); ++i) { + its_command.push_back( + reinterpret_cast<const byte_t*>(&_minor)[i]); + } + + offered_services_info_[_target] = its_command; +} + void routing_manager_stub::inform_requesters(client_t _hoster, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor, routing_info_entry_e _entry, bool _inform_service) { diff --git a/implementation/runtime/include/application_impl.hpp b/implementation/runtime/include/application_impl.hpp index b03c497..163e676 100644 --- a/implementation/runtime/include/application_impl.hpp +++ b/implementation/runtime/include/application_impl.hpp @@ -174,6 +174,13 @@ public: VSOMEIP_EXPORT void register_subscription_status_handler(service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event, subscription_status_handler_t _handler, bool _is_selective); + + VSOMEIP_EXPORT void get_offered_services_async(offer_type_e _offer_type, offered_services_handler_t _handler); + + VSOMEIP_EXPORT void on_offered_services_info(std::vector<std::pair<service_t, instance_t>> &_services); + + VSOMEIP_EXPORT void set_watchdog_handler(watchdog_handler_t _handler, std::chrono::seconds _interval); + private: // // Types @@ -184,6 +191,8 @@ private: AVAILABILITY, STATE, SUBSCRIPTION, + OFFERED_SERVICES_INFO, + WATCHDOG, UNKNOWN }; @@ -268,6 +277,9 @@ private: eventgroup_t _eventgroup, event_t _event); void print_blocking_call(std::shared_ptr<sync_handler> _handler); + + void watchdog_cbk(boost::system::error_code const &_error); + // // Attributes // @@ -296,6 +308,10 @@ private: std::mutex state_handler_mutex_; state_handler_t handler_; + // vsomeip offered services handler + std::mutex offered_services_handler_mutex_; + offered_services_handler_t offered_services_handler_; + // Method/Event (=Member) handlers std::map<service_t, std::map<instance_t, std::map<method_t, message_handler_t> > > members_; @@ -379,6 +395,10 @@ private: std::map<std::tuple<service_t, instance_t, eventgroup_t, event_t>, subscription_state_e> subscription_state_; + std::mutex watchdog_timer_mutex_; + boost::asio::steady_timer watchdog_timer_; + watchdog_handler_t watchdog_handler_; + std::chrono::seconds watchdog_interval_; }; } // namespace vsomeip diff --git a/implementation/runtime/src/application_impl.cpp b/implementation/runtime/src/application_impl.cpp index d44aa9a..7b8fd22 100644 --- a/implementation/runtime/src/application_impl.cpp +++ b/implementation/runtime/src/application_impl.cpp @@ -27,6 +27,7 @@ #include "../../tracing/include/trace_connector.hpp" #include "../../tracing/include/enumeration_types.hpp" #include "../../plugin/include/plugin_manager.hpp" +#include "../../endpoints/include/endpoint.hpp" namespace vsomeip { @@ -52,7 +53,8 @@ application_impl::application_impl(const std::string &_name) stopped_(false), block_stopping_(false), is_routing_manager_host_(false), - stopped_called_(false) { + stopped_called_(false), + watchdog_timer_(io_) { } application_impl::~application_impl() { @@ -1358,6 +1360,10 @@ void application_impl::on_message(const std::shared_ptr<message> &&_message) { if (_message->get_message_type() == message_type_e::MT_NOTIFICATION) { if (!check_for_active_subscription(its_service, its_instance, static_cast<event_t>(its_method))) { + VSOMEIP_ERROR << "application_impl::on_message [" + << std::hex << std::setw(4) << std::setfill('0') << its_service << "." + << std::hex << std::setw(4) << std::setfill('0') << its_instance << "." + << std::hex << std::setw(4) << std::setfill('0') << its_method << "]"; return; } } @@ -1589,6 +1595,10 @@ void application_impl::remove_elapsed_dispatchers() { void application_impl::clear_all_handler() { unregister_state_handler(); + { + std::lock_guard<std::mutex> its_lock(offered_services_handler_mutex_); + offered_services_handler_ = nullptr; + } { std::lock_guard<std::mutex> availability_lock(availability_mutex_); @@ -1909,6 +1919,14 @@ void application_impl::print_blocking_call(std::shared_ptr<sync_handler> _handle << std::hex << std::setw(4) << std::setfill('0') << _handler->eventgroup_id_ << ":" << std::hex << std::setw(4) << std::setfill('0') << _handler->method_id_ << "]"; break; + case handler_type_e::OFFERED_SERVICES_INFO: + VSOMEIP_INFO << "BLOCKING CALL OFFERED_SERVICES_INFO(" + << std::hex << std::setw(4) << std::setfill('0') << get_client() <<")"; + break; + case handler_type_e::WATCHDOG: + VSOMEIP_INFO << "BLOCKING CALL WATCHDOG(" + << std::hex << std::setw(4) << std::setfill('0') << get_client() <<")"; + break; case handler_type_e::UNKNOWN: VSOMEIP_INFO << "BLOCKING CALL UNKNOWN(" << std::hex << std::setw(4) << std::setfill('0') << get_client() << ")"; @@ -1916,4 +1934,111 @@ void application_impl::print_blocking_call(std::shared_ptr<sync_handler> _handle } } + +void application_impl::get_offered_services_async(offer_type_e _offer_type, offered_services_handler_t _handler) { + { + std::lock_guard<std::mutex> its_lock(offered_services_handler_mutex_); + offered_services_handler_ = _handler; + } + + if (!is_routing_manager_host_) { + routing_->send_get_offered_services_info(get_client(), _offer_type); + } else { + std::vector<std::pair<service_t, instance_t>> its_services; + auto its_routing_manager_host = std::dynamic_pointer_cast<routing_manager_impl>(routing_); + + for (auto s : its_routing_manager_host->get_offered_services()) { + for (auto i : s.second) { + auto its_unreliable_endpoint = i.second->get_endpoint(false); + auto its_reliable_endpoint = i.second->get_endpoint(true); + + if (_offer_type == offer_type_e::OT_LOCAL) { + if ( ((its_unreliable_endpoint && (its_unreliable_endpoint->get_local_port() == ILLEGAL_PORT)) + && (its_reliable_endpoint && (its_reliable_endpoint->get_local_port() == ILLEGAL_PORT))) + || (!its_reliable_endpoint && !its_unreliable_endpoint)) { + its_services.push_back(std::make_pair(s.first, i.first)); + } + } else if (_offer_type == offer_type_e::OT_REMOTE) { + if ((its_unreliable_endpoint && its_unreliable_endpoint->get_local_port() != ILLEGAL_PORT) + || (its_reliable_endpoint && its_reliable_endpoint->get_local_port() != ILLEGAL_PORT)) { + its_services.push_back(std::make_pair(s.first, i.first)); + } + } else if (_offer_type == offer_type_e::OT_ALL) { + its_services.push_back(std::make_pair(s.first, i.first)); + } + } + } + on_offered_services_info(its_services); + } + return; +} + + +void application_impl::on_offered_services_info(std::vector<std::pair<service_t, instance_t>> &_services) { + bool has_offered_services_handler(false); + offered_services_handler_t handler = nullptr; + { + std::lock_guard<std::mutex> its_lock(offered_services_handler_mutex_); + if (offered_services_handler_) { + has_offered_services_handler = true; + handler = offered_services_handler_; + } + } + if (has_offered_services_handler) { + { + std::lock_guard<std::mutex> its_lock(handlers_mutex_); + std::shared_ptr<sync_handler> its_sync_handler + = std::make_shared<sync_handler>([handler, _services]() { + handler(_services); + }); + its_sync_handler->handler_type_ = handler_type_e::OFFERED_SERVICES_INFO; + handlers_.push_back(its_sync_handler); + } + dispatcher_condition_.notify_one(); + } +} + +void application_impl::watchdog_cbk(boost::system::error_code const &_error) { + if (!_error) { + + watchdog_handler_t handler = nullptr; + { + std::lock_guard<std::mutex> its_lock(watchdog_timer_mutex_); + handler = watchdog_handler_; + if (handler && std::chrono::seconds::zero() != watchdog_interval_) { + watchdog_timer_.expires_from_now(watchdog_interval_); + watchdog_timer_.async_wait(std::bind(&application_impl::watchdog_cbk, + this, std::placeholders::_1)); + } + } + + if (handler) { + std::lock_guard<std::mutex> its_lock(handlers_mutex_); + std::shared_ptr<sync_handler> its_sync_handler + = std::make_shared<sync_handler>([handler]() { handler(); }); + its_sync_handler->handler_type_ = handler_type_e::WATCHDOG; + handlers_.push_back(its_sync_handler); + } + dispatcher_condition_.notify_one(); + + } +} + +void application_impl::set_watchdog_handler(watchdog_handler_t _handler, + std::chrono::seconds _interval) { + if (_handler && std::chrono::seconds::zero() != _interval) { + std::lock_guard<std::mutex> its_lock(watchdog_timer_mutex_); + watchdog_handler_ = _handler; + watchdog_interval_ = _interval; + watchdog_timer_.expires_from_now(_interval); + watchdog_timer_.async_wait(std::bind(&application_impl::watchdog_cbk, + this, std::placeholders::_1)); + } else { + std::lock_guard<std::mutex> its_lock(watchdog_timer_mutex_); + watchdog_timer_.cancel(); + watchdog_handler_ = nullptr; + watchdog_interval_ = std::chrono::seconds::zero(); + } +} + } // namespace vsomeip diff --git a/implementation/service_discovery/include/service_discovery.hpp b/implementation/service_discovery/include/service_discovery.hpp index 703bf22..075129b 100644 --- a/implementation/service_discovery/include/service_discovery.hpp +++ b/implementation/service_discovery/include/service_discovery.hpp @@ -55,7 +55,7 @@ public: virtual void send_subscriptions(service_t _service, instance_t _instance, client_t _client, bool _reliable) = 0; - virtual void on_reliable_endpoint_connected( + virtual void on_endpoint_connected( service_t _service, instance_t _instance, const std::shared_ptr<const vsomeip::endpoint> &_endpoint) = 0; diff --git a/implementation/service_discovery/include/service_discovery_host.hpp b/implementation/service_discovery/include/service_discovery_host.hpp index e1e0ccd..492c920 100644 --- a/implementation/service_discovery/include/service_discovery_host.hpp +++ b/implementation/service_discovery/include/service_discovery_host.hpp @@ -93,6 +93,11 @@ public: instance_t _instance, bool _reliable) = 0; virtual std::chrono::steady_clock::time_point expire_subscriptions() = 0; + + virtual std::shared_ptr<serviceinfo> get_offered_service( + service_t _service, instance_t _instance) const = 0; + virtual std::map<instance_t, std::shared_ptr<serviceinfo>> get_offered_service_instances( + service_t _service) const = 0; }; } // namespace sd diff --git a/implementation/service_discovery/include/service_discovery_impl.hpp b/implementation/service_discovery/include/service_discovery_impl.hpp index bc3a842..5f28135 100644 --- a/implementation/service_discovery/include/service_discovery_impl.hpp +++ b/implementation/service_discovery/include/service_discovery_impl.hpp @@ -82,7 +82,7 @@ public: const boost::asio::ip::address &_sender, const boost::asio::ip::address &_destination); - void on_reliable_endpoint_connected( + void on_endpoint_connected( service_t _service, instance_t _instance, const std::shared_ptr<const vsomeip::endpoint> &_endpoint); diff --git a/implementation/service_discovery/include/subscription.hpp b/implementation/service_discovery/include/subscription.hpp index dc8222c..3c3bfe8 100644 --- a/implementation/service_discovery/include/subscription.hpp +++ b/implementation/service_discovery/include/subscription.hpp @@ -38,6 +38,9 @@ public: bool is_tcp_connection_established() const; void set_tcp_connection_established(bool _is_established); + bool is_udp_connection_established() const; + void set_udp_connection_established(bool _is_established); + subscription_type_e get_subscription_type() const; uint8_t get_counter() const; @@ -51,6 +54,7 @@ private: bool is_acknowledged_; bool tcp_connection_established_; + bool udp_connection_established_; subscription_type_e subscription_type_; diff --git a/implementation/service_discovery/src/service_discovery_impl.cpp b/implementation/service_discovery/src/service_discovery_impl.cpp index b6a45b6..9577526 100644 --- a/implementation/service_discovery/src/service_discovery_impl.cpp +++ b/implementation/service_discovery/src/service_discovery_impl.cpp @@ -262,21 +262,44 @@ void service_discovery_impl::subscribe(service_t _service, instance_t _instance, } } - if (its_subscription->get_endpoint(true) - && its_subscription->get_endpoint(true)->is_connected()) { - insert_subscription(its_message, - _service, _instance, - _eventgroup, - its_subscription, true, true); - } else { - // don't insert reliable endpoint option if the - // TCP client endpoint is not yet connected - insert_subscription(its_message, - _service, _instance, - _eventgroup, - its_subscription, false, true); - its_subscription->set_tcp_connection_established(false); + if (its_subscription->get_endpoint(true) && + its_subscription->get_endpoint(false)) { + if (its_subscription->get_endpoint(true)->is_connected() && + its_subscription->get_endpoint(false)->is_connected()) { + insert_subscription(its_message, + _service, _instance, + _eventgroup, + its_subscription, true, true); + } else { + if (!its_subscription->get_endpoint(true)->is_connected()) { + its_subscription->set_tcp_connection_established(false); + } + if (!its_subscription->get_endpoint(false)->is_connected()) { + its_subscription->set_udp_connection_established(false); + } + } + } else if (its_subscription->get_endpoint(true) && + !its_subscription->get_endpoint(false)) { + if (its_subscription->get_endpoint(true)->is_connected()) { + insert_subscription(its_message, + _service, _instance, + _eventgroup, + its_subscription, true, false); + } else { + its_subscription->set_tcp_connection_established(false); + } + } else if (!its_subscription->get_endpoint(true) && + its_subscription->get_endpoint(false)) { + if (its_subscription->get_endpoint(false)->is_connected()) { + insert_subscription(its_message, + _service, _instance, + _eventgroup, + its_subscription, false, true); + } else { + its_subscription->set_udp_connection_established(false); + } } + if(0 < its_message->get_entries().size()) { its_subscription->set_acknowledged(false); } @@ -886,7 +909,7 @@ void service_discovery_impl::insert_subscription( } if (_insert_unreliable) { its_endpoint = _subscription->get_endpoint(false); - if (its_endpoint && its_endpoint->get_local_port()) { + if (its_endpoint) { const std::uint16_t its_port = its_endpoint->get_local_port(); if (its_port) { insert_option(_message, its_entry, unicast_, its_port, false); @@ -1357,22 +1380,21 @@ void service_discovery_impl::process_offerservice_serviceentry( void service_discovery_impl::process_findservice_serviceentry( service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor, bool _unicast_flag) { - 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_uni_or_multicast_offerservice(_service, _instance, _major, _minor, its_info, - _unicast_flag); - } - } else { - // send back all available instances - for (const auto &found_instance : found_service->second) { - send_uni_or_multicast_offerservice(_service, _instance, _major, _minor, - found_instance.second, _unicast_flag); - } + + if (_instance != ANY_INSTANCE) { + std::shared_ptr<serviceinfo> its_info = host_->get_offered_service( + _service, _instance); + if (its_info) { + send_uni_or_multicast_offerservice(_service, _instance, _major, + _minor, its_info, _unicast_flag); + } + } else { + std::map<instance_t, std::shared_ptr<serviceinfo>> offered_instances = + host_->get_offered_service_instances(_service); + // send back all available instances + for (const auto &found_instance : offered_instances) { + send_uni_or_multicast_offerservice(_service, _instance, _major, + _minor, found_instance.second, _unicast_flag); } } } @@ -1436,7 +1458,7 @@ void service_discovery_impl::send_multicast_offer_service( } } -void service_discovery_impl::on_reliable_endpoint_connected( +void service_discovery_impl::on_endpoint_connected( service_t _service, instance_t _instance, const std::shared_ptr<const vsomeip::endpoint> &_endpoint) { std::shared_ptr<runtime> its_runtime = runtime_.lock(); @@ -1467,16 +1489,39 @@ void service_discovery_impl::on_reliable_endpoint_connected( _instance, true)) { continue; } + if (its_client.second->get_endpoint(false) && + !host_->has_identified(its_client.first, _service, + _instance, false)) { + continue; + } } std::shared_ptr<subscription> its_subscription(its_client.second); - if(its_subscription && !its_subscription->is_tcp_connection_established()) { - const std::shared_ptr<const endpoint> its_endpoint( - its_subscription->get_endpoint(true)); - if(its_endpoint && its_endpoint->is_connected()) { - if(its_endpoint.get() == _endpoint.get()) { - // mark as established - its_subscription->set_tcp_connection_established(true); - + if (its_subscription) { + if (!its_subscription->is_tcp_connection_established() || + !its_subscription->is_udp_connection_established()) { + const std::shared_ptr<const endpoint> its_reliable_endpoint( + its_subscription->get_endpoint(true)); + const std::shared_ptr<const endpoint> its_unreliable_endpoint( + its_subscription->get_endpoint(false)); + if(its_reliable_endpoint && its_reliable_endpoint->is_connected()) { + if(its_reliable_endpoint.get() == _endpoint.get()) { + // mark tcp as established + its_subscription->set_tcp_connection_established(true); + } + } + if(its_unreliable_endpoint && its_unreliable_endpoint->is_connected()) { + if(its_reliable_endpoint.get() == _endpoint.get()) { + // mark udp as established + its_subscription->set_udp_connection_established(true); + } + } + if ((its_reliable_endpoint && its_unreliable_endpoint && + its_subscription->is_tcp_connection_established() && + its_subscription->is_udp_connection_established()) || + (its_reliable_endpoint && !its_unreliable_endpoint && + its_subscription->is_tcp_connection_established()) || + (its_unreliable_endpoint && !its_reliable_endpoint && + its_subscription->is_udp_connection_established())) { std::shared_ptr<endpoint> its_unreliable; std::shared_ptr<endpoint> its_reliable; get_subscription_endpoints( @@ -1486,11 +1531,9 @@ void service_discovery_impl::on_reliable_endpoint_connected( its_client.first); its_subscription->set_endpoint(its_reliable, true); its_subscription->set_endpoint(its_unreliable, false); - // only insert reliable subscriptions as unreliable - // ones are immediately sent out insert_subscription(its_message, _service, _instance, its_eventgroup.first, - its_subscription, true, false); + its_subscription, true, true); its_subscription->set_acknowledged(false); } } @@ -1881,6 +1924,41 @@ void service_discovery_impl::handle_eventgroup_subscription(service_t _service, std::vector <accepted_subscriber_t> &accepted_subscribers) { if (its_message) { + bool has_reliable_events(false); + bool has_unreliable_events(false); + auto its_eventgroup = host_->find_eventgroup(_service, _instance, _eventgroup); + if (its_eventgroup) { + its_eventgroup->get_reliability(has_reliable_events, has_unreliable_events); + } + + bool reliablility_nack(false); + if (has_reliable_events && !has_unreliable_events) { + if (!(_first_port != ILLEGAL_PORT && _is_first_reliable) && + !(_second_port != ILLEGAL_PORT && _is_second_reliable)) { + reliablility_nack = true; + } + } else if (!has_reliable_events && has_unreliable_events) { + if (!(_first_port != ILLEGAL_PORT && !_is_first_reliable) && + !(_second_port != ILLEGAL_PORT && !_is_second_reliable)) { + reliablility_nack = true; + } + } else if (has_reliable_events && has_unreliable_events) { + if (_first_port == ILLEGAL_PORT || _second_port == ILLEGAL_PORT) { + reliablility_nack = true; + } + if (_is_first_reliable == _is_second_reliable) { + reliablility_nack = true; + } + } + if (reliablility_nack && _ttl > 0) { + insert_subscription_nack(its_message, _service, _instance, + _eventgroup, _counter, _major, _reserved); + VSOMEIP_WARNING << "Subscription for service/instance " + << std::hex << _service << "/" << _instance + << " not valid: Event configuration does not match the provided endpoint options"; + return; + } + std::shared_ptr < eventgroupinfo > its_info = host_->find_eventgroup( _service, _instance, _eventgroup); @@ -2104,25 +2182,15 @@ bool service_discovery_impl::is_tcp_connected(service_t _service, instance_t _instance, std::shared_ptr<vsomeip::endpoint_definition> its_endpoint) { bool is_connected = false; - 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; - if(its_info) { - //get reliable server endpoint - auto its_reliable_server_endpoint = - std::dynamic_pointer_cast<tcp_server_endpoint_impl>( - its_info->get_endpoint(true)); - if (its_reliable_server_endpoint - && its_reliable_server_endpoint->is_established( - its_endpoint)) { - is_connected = true; - } - } - } + std::shared_ptr<serviceinfo> its_info = host_->get_offered_service(_service, + _instance); + if (its_info) { + //get reliable server endpoint + auto its_reliable_server_endpoint = std::dynamic_pointer_cast< + tcp_server_endpoint_impl>(its_info->get_endpoint(true)); + if (its_reliable_server_endpoint + && its_reliable_server_endpoint->is_established(its_endpoint)) { + is_connected = true; } } return is_connected; @@ -2231,9 +2299,17 @@ void service_discovery_impl::send_subscriptions(service_t _service, instance_t _ if (_reliable) { endpoint = its_reliable; found_client->second->set_endpoint(its_reliable, true); + if (its_unreliable && + !host_->has_identified(found_client->first, _service, _instance, false)) { + return; + } } else { endpoint = its_unreliable; found_client->second->set_endpoint(its_unreliable, false); + if (its_reliable && + !host_->has_identified(found_client->first, _service, _instance, true)) { + return; + } } if (endpoint) { if (!has_address) { @@ -2247,21 +2323,41 @@ void service_discovery_impl::send_subscriptions(service_t _service, instance_t _ std::shared_ptr<message_impl> its_message = its_runtime->create_message(); - if(_reliable) { - if(endpoint->is_connected()) { + if (its_reliable && its_unreliable) { + if (its_reliable->is_connected() && its_unreliable->is_connected()) { insert_subscription(its_message, _service, _instance, found_eventgroup.first, - found_client->second, _reliable, !_reliable); + found_client->second, true, true); found_client->second->set_tcp_connection_established(true); + found_client->second->set_udp_connection_established(true); } else { - // don't insert reliable endpoint option if the - // TCP client endpoint is not yet connected found_client->second->set_tcp_connection_established(false); + found_client->second->set_udp_connection_established(false); } } else { - insert_subscription(its_message, _service, - _instance, found_eventgroup.first, - found_client->second, _reliable, !_reliable); + if(_reliable) { + if(endpoint->is_connected()) { + insert_subscription(its_message, _service, + _instance, found_eventgroup.first, + found_client->second, _reliable, !_reliable); + found_client->second->set_tcp_connection_established(true); + } else { + // don't insert reliable endpoint option if the + // TCP client endpoint is not yet connected + found_client->second->set_tcp_connection_established(false); + } + } else { + if (endpoint->is_connected()) { + insert_subscription(its_message, _service, + _instance, found_eventgroup.first, + found_client->second, _reliable, !_reliable); + found_client->second->set_udp_connection_established(true); + } else { + // don't insert reliable endpoint option if the + // UDP client endpoint is not yet connected + found_client->second->set_udp_connection_established(false); + } + } } if (its_message->get_entries().size() && its_message->get_options().size()) { diff --git a/implementation/service_discovery/src/subscription.cpp b/implementation/service_discovery/src/subscription.cpp index c56b0d2..aca8967 100644 --- a/implementation/service_discovery/src/subscription.cpp +++ b/implementation/service_discovery/src/subscription.cpp @@ -17,6 +17,7 @@ subscription::subscription(major_version_t _major, ttl_t _ttl, reliable_(_reliable), unreliable_(_unreliable), is_acknowledged_(true), tcp_connection_established_(false), + udp_connection_established_(false), subscription_type_(_subscription_type), counter_(_counter) { } @@ -63,6 +64,13 @@ void subscription::set_tcp_connection_established(bool _is_established) { tcp_connection_established_ = _is_established; } +bool subscription::is_udp_connection_established() const { + return udp_connection_established_; +} +void subscription::set_udp_connection_established(bool _is_established) { + udp_connection_established_ = _is_established; +} + subscription_type_e subscription::get_subscription_type() const { return subscription_type_; } diff --git a/implementation/tracing/include/enumeration_types.hpp b/implementation/tracing/include/enumeration_types.hpp index 7696c57..82ed3c4 100644 --- a/implementation/tracing/include/enumeration_types.hpp +++ b/implementation/tracing/include/enumeration_types.hpp @@ -16,8 +16,8 @@ enum class filter_criteria_e : uint8_t { }; enum class filter_type_e : uint8_t { - NEGATIVE = 0x00, - POSITIVE = 0x01 + NEGATIVE = 0x00, + POSITIVE = 0x01 }; } // namespace tc diff --git a/implementation/tracing/src/trace_connector.cpp b/implementation/tracing/src/trace_connector.cpp index 93f7d6e..dc52010 100644 --- a/implementation/tracing/src/trace_connector.cpp +++ b/implementation/tracing/src/trace_connector.cpp @@ -295,23 +295,24 @@ bool trace_connector::apply_filter_rules(const byte_t *_data, uint16_t _data_si filter_rule_t its_filter_rule = it_filter_rules->second; // apply filter rule - bool trace_message = true; + bool filter_rule_matches = false; filter_type_e its_filter_type = its_filter_rule.first; for(auto it_filter_rule_map = its_filter_rule.second.begin(); - it_filter_rule_map != its_filter_rule.second.end() && trace_message; + it_filter_rule_map != its_filter_rule.second.end(); ++it_filter_rule_map) { filter_criteria_e its_criteria = it_filter_rule_map->first; auto &its_filter_expressions = it_filter_rule_map->second; - if(its_filter_expressions.size() != 0) { - // check if filter expressions of filter criteria match - const bool filter_rule_matches = filter_expressions_match(its_criteria, its_filter_expressions, _data, _data_size); - trace_message = !(filter_rule_matches && its_filter_type == filter_type_e::NEGATIVE); + // check if filter expressions of filter criteria match + filter_rule_matches = filter_expressions_match(its_criteria, its_filter_expressions, _data, _data_size) == (int)its_filter_type; + if(!filter_rule_matches) { + // filter expressions of filter criteria does not match + break; } } - if(trace_message) { + if(filter_rule_matches) { //filter rule matches -> send message over 'its_channel' to DLT _send_msg_over_channels.push_back(its_channel); } @@ -360,17 +361,20 @@ bool trace_connector::filter_expressions_match( // if extraction is successful, filter if (is_successful) { - bool filter_expressions_matches = false; + bool filter_expressions_matches = true; for (auto it_expressions = _expressions.begin(); - it_expressions != _expressions.end() && !filter_expressions_matches; + it_expressions != _expressions.end(); ++it_expressions) { filter_expression_t its_filter_expression = *it_expressions; uint16_t its_message_value = 0; + its_message_value = (uint16_t)((its_message_value << 8) + first); its_message_value = (uint16_t)((its_message_value << 8) + second); - - filter_expressions_matches = (its_filter_expression == its_message_value); + if(its_filter_expression != its_message_value) { + filter_expressions_matches = false; + break; + } } return filter_expressions_matches; } diff --git a/implementation/tracing/src/trace_header.cpp b/implementation/tracing/src/trace_header.cpp index d78e600..3ae1b10 100644 --- a/implementation/tracing/src/trace_header.cpp +++ b/implementation/tracing/src/trace_header.cpp @@ -20,19 +20,22 @@ bool trace_header::prepare(const std::shared_ptr<endpoint> &_endpoint, bool trace_header::prepare(const endpoint *_endpoint, bool _is_sending, instance_t _instance) { + boost::asio::ip::address its_address; + unsigned short its_port(0); + protocol_e its_protocol(protocol_e::unknown); + if (_endpoint) { const client_endpoint* its_client_endpoint = dynamic_cast<const client_endpoint*>(_endpoint); if (its_client_endpoint) { - boost::asio::ip::address its_address; its_client_endpoint->get_remote_address(its_address); if (its_address.is_v6()) { return false; } - unsigned short its_port = its_client_endpoint->get_remote_port(); - protocol_e its_protocol(protocol_e::unknown); + its_port = its_client_endpoint->get_remote_port(); + if (_endpoint->is_local()) { its_protocol = protocol_e::local; } else { @@ -42,12 +45,9 @@ bool trace_header::prepare(const endpoint *_endpoint, bool _is_sending, its_protocol = protocol_e::udp; } } - prepare(its_address.to_v4(), its_port, its_protocol, _is_sending, - _instance); - return true; } } - std::memset(data_, 0, VSOMEIP_TRACE_HEADER_SIZE); + prepare(its_address.to_v4(), its_port, its_protocol, _is_sending, _instance); return true; } @@ -55,16 +55,16 @@ void trace_header::prepare(const boost::asio::ip::address_v4 &_address, std::uint16_t _port, protocol_e _protocol, bool _is_sending, instance_t _instance) { unsigned long its_address_as_long = _address.to_ulong(); - data_[0] = VSOMEIP_LONG_BYTE0(its_address_as_long); - data_[1] = VSOMEIP_LONG_BYTE1(its_address_as_long); - data_[2] = VSOMEIP_LONG_BYTE2(its_address_as_long); - data_[3] = VSOMEIP_LONG_BYTE3(its_address_as_long); - data_[4] = VSOMEIP_WORD_BYTE0(_port); - data_[5] = VSOMEIP_WORD_BYTE1(_port); + data_[0] = VSOMEIP_LONG_BYTE3(its_address_as_long); + data_[1] = VSOMEIP_LONG_BYTE2(its_address_as_long); + data_[2] = VSOMEIP_LONG_BYTE1(its_address_as_long); + data_[3] = VSOMEIP_LONG_BYTE0(its_address_as_long); + data_[4] = VSOMEIP_WORD_BYTE1(_port); + data_[5] = VSOMEIP_WORD_BYTE0(_port); data_[6] = static_cast<byte_t>(_protocol); data_[7] = static_cast<byte_t>(_is_sending); - data_[8] = VSOMEIP_WORD_BYTE0(_instance); - data_[9] = VSOMEIP_WORD_BYTE1(_instance); + data_[8] = VSOMEIP_WORD_BYTE1(_instance); + data_[9] = VSOMEIP_WORD_BYTE0(_instance); } } // namespace tc diff --git a/implementation/utility/include/utility.hpp b/implementation/utility/include/utility.hpp index 9245f90..40c6973 100644 --- a/implementation/utility/include/utility.hpp +++ b/implementation/utility/include/utility.hpp @@ -107,12 +107,12 @@ public: || _type == message_type_e::MT_UNKNOWN); } - static uint16_t its_configuration_refs__; - private: static bool is_bigger_last_assigned_client_id(client_t _client); static void set_client_id_lowbyte(client_t _client); static void check_client_id_consistency(); + + static uint16_t its_configuration_refs__; }; } // namespace vsomeip diff --git a/interface/vsomeip/application.hpp b/interface/vsomeip/application.hpp index 280957c..fdf007e 100644 --- a/interface/vsomeip/application.hpp +++ b/interface/vsomeip/application.hpp @@ -10,6 +10,7 @@ #include <memory> #include <set> #include <map> +#include <vector> #include <vsomeip/primitive_types.hpp> #include <vsomeip/enumeration_types.hpp> @@ -312,7 +313,7 @@ public: */ virtual void subscribe(service_t _service, instance_t _instance, eventgroup_t _eventgroup, major_version_t _major = DEFAULT_MAJOR, - subscription_type_e _subscription_type = subscription_type_e::SU_PREFER_RELIABLE, + subscription_type_e _subscription_type = subscription_type_e::SU_RELIABLE_AND_UNRELIABLE, event_t _event = ANY_EVENT) = 0; /** @@ -884,6 +885,47 @@ public: virtual void register_subscription_status_handler(service_t _service, instance_t _instance, eventgroup_t _eventgroup, event_t _event, subscription_status_handler_t _handler, bool _is_selective) = 0; + + /** + * + * \brief Returns all registered services / instances on this node in an async callback. + * + * When called with a handler of type offered_services_handler_t, + * all at the routing manager registered services on this node get returned in a vector of + * service / instance pairs depending on the given _offer_type. + * + * \param _offer_type type of offered services to be returned (OT_LOCAL = 0x00, OT_REMOTE = 0x01, OT_ALL = 0x02) + * \param offered_services_handler_t handler which gets called with a vector of service instance pairs that are currently offered + */ + virtual void get_offered_services_async(offer_type_e _offer_type, offered_services_handler_t _handler) = 0; + + /** + * + * \brief Sets a handler to be called cyclically for watchdog monitoring. + * + * The handler shall be called in the given interval, but not before start() + * has been called, and not after call to stop() returned. + * + * In case the application is running, i.e. start() succeeded, but the + * handler will not be invoke within the (approximate) interval it may + * be assumed that I/O or internal dispatcher threads are non-functional. + * + * \remark Accuracy of call interval is limited by clock/timer granularity + * or scheduling effects, thus it may underrun or overrun by small + * amount. + * + * \note Only one handler can be active at the time, thus last handler set + * by calling this function will be invoked. + * + * \note To disable calling an active handler, invoke this method again, + * passing nullptr as _handler and/or std::chrono::seconds::zero() + * as _interval. + * + * \param _handler A watchdog handler, pass nullptr to deactivate. + * \param _interval Call interval in seconds, pass std::chrono::seconds::zero() to deactivate. + */ + virtual void set_watchdog_handler(watchdog_handler_t _handler, std::chrono::seconds _interval) = 0; + }; /** @} */ diff --git a/interface/vsomeip/enumeration_types.hpp b/interface/vsomeip/enumeration_types.hpp index 74358c6..1f83b81 100644 --- a/interface/vsomeip/enumeration_types.hpp +++ b/interface/vsomeip/enumeration_types.hpp @@ -63,6 +63,12 @@ enum class routing_state_e : uint8_t { RS_UNKNOWN = 0xFF }; +enum class offer_type_e : uint8_t { + OT_LOCAL = 0x00, + OT_REMOTE = 0x01, + OT_ALL = 0x02, +}; + } // namespace vsomeip #endif // VSOMEIP_ENUMERATION_TYPES_HPP diff --git a/interface/vsomeip/handler.hpp b/interface/vsomeip/handler.hpp index 507ac3c..ab4f118 100644 --- a/interface/vsomeip/handler.hpp +++ b/interface/vsomeip/handler.hpp @@ -23,6 +23,10 @@ typedef std::function< void (const uint16_t) > error_handler_t; typedef std::function< void (const service_t, const instance_t, const eventgroup_t, const event_t, const uint16_t) > subscription_status_handler_t; +typedef std::function< void (const std::vector<std::pair<service_t, instance_t>> &_services) > offered_services_handler_t; +typedef std::function< void () > watchdog_handler_t; + + } // namespace vsomeip #endif // VSOMEIP_HANDLER_HPP diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 8e88a05..d1337e7 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1145,6 +1145,30 @@ if(NOT ${TESTS_BAT}) ${TEST_SUBSCRIBE_NOTIFY_SERVICE} ) + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_master_tcp.json) + configure_file( + ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}.in + ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_slave_tcp.json) + configure_file( + ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE}.in + ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master.json) configure_file( @@ -1169,6 +1193,30 @@ if(NOT ${TESTS_BAT}) ${TEST_SUBSCRIBE_NOTIFY_SERVICE} ) + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_master_tcp.json) + configure_file( + ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}.in + ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} + ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_slave_tcp.json) + configure_file( + ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/conf/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE}.in + ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${PROJECT_SOURCE_DIR}/test/subscribe_notify_tests/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} + ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_SERVICE} + ) + set(TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_master.json) configure_file( @@ -1413,6 +1461,30 @@ if(NOT ${TESTS_BAT}) ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} ) + set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_master_tcp.json) + configure_file( + ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}.in + ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} + ) + + set(TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE + ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_slave_tcp.json) + configure_file( + ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/conf/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE}.in + ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + ${TEST_SUBSCRIBE_NOTIFY_ONE_SERVICE} + ) + # copy starter scripts into builddir set(TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_master_starter.sh) copy_to_builddir(${PROJECT_SOURCE_DIR}/test/subscribe_notify_one_tests/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} @@ -1581,6 +1653,31 @@ if(NOT ${TESTS_BAT}) ${TEST_INITIAL_EVENT_SERVICE} ) + # Copy config files for test into $BUILDDIR/test + set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_master_tcp.json) + configure_file( + ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}.in + ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_slave_tcp.json) + configure_file( + ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE}.in + ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_SLAVE_TCP_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_master.json) configure_file( @@ -1605,6 +1702,30 @@ if(NOT ${TESTS_BAT}) ${TEST_INITIAL_EVENT_SERVICE} ) + set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_master_tcp.json) + configure_file( + ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}.in + ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} + ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + + set(TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE + ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_slave_tcp.json) + configure_file( + ${PROJECT_SOURCE_DIR}/test/initial_event_tests/conf/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE}.in + ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} + @ONLY) + copy_to_builddir( + ${PROJECT_SOURCE_DIR}/test/initial_event_tests/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} + ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_SLAVE_TCP_CONFIG_FILE} + ${TEST_INITIAL_EVENT_SERVICE} + ) + set(TEST_INITIAL_EVENT_DIFF_IDS_PARTIAL_SAME_PORTS_MASTER_CONFIG_FILE ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_partial_same_ports_master.json) configure_file( @@ -1810,6 +1931,45 @@ if(NOT ${TESTS_BAT}) endif() ############################################################################## +# offered services info tests +############################################################################## +if(NOT ${TESTS_BAT}) + set(TEST_OFFERED_SERVICES_INFO_NAME offered_services_info_test) + set(TEST_OFFERED_SERVICES_INFO_SERVICE ${TEST_OFFERED_SERVICES_INFO_NAME}_service) + add_executable(${TEST_OFFERED_SERVICES_INFO_SERVICE} offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_NAME}_service.cpp) + target_link_libraries(${TEST_OFFERED_SERVICES_INFO_SERVICE} + vsomeip + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + set(TEST_OFFERED_SERVICES_INFO_CLIENT ${TEST_OFFERED_SERVICES_INFO_NAME}_client) + add_executable(${TEST_OFFERED_SERVICES_INFO_CLIENT} offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_NAME}_client.cpp) + target_link_libraries(${TEST_OFFERED_SERVICES_INFO_CLIENT} + vsomeip + ${Boost_LIBRARIES} + ${DL_LIBRARY} + ${TEST_LINK_LIBRARIES} + ) + + # copy starter scripts into builddir + set(TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER ${TEST_OFFERED_SERVICES_INFO_NAME}_local_starter.sh) + copy_to_builddir(${PROJECT_SOURCE_DIR}/test/offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER} + ${PROJECT_BINARY_DIR}/test/${TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER} + ${TEST_OFFERED_SERVICES_INFO_SERVICE} + ) + + # Copy config file for local test into $BUILDDIR/test + set(TEST_OFFERED_SERVICES_INFO_LOCAL_CONFIG_FILE ${TEST_OFFERED_SERVICES_INFO_NAME}_local.json) + copy_to_builddir( + ${PROJECT_SOURCE_DIR}/test/offered_services_info_test/${TEST_OFFERED_SERVICES_INFO_LOCAL_CONFIG_FILE} + ${PROJECT_BINARY_DIR}/test/${TEST_OFFERED_SERVICES_INFO_LOCAL_CONFIG_FILE} + ${TEST_OFFERED_SERVICES_INFO_SERVICE} + ) +endif() + +############################################################################## # Add for every test a dependency to gtest ############################################################################## @@ -1846,6 +2006,8 @@ if(NOT ${TESTS_BAT}) add_dependencies(${TEST_OFFER_CLIENT} gtest) add_dependencies(${TEST_OFFER_SERVICE_EXTERNAL} gtest) add_dependencies(${TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER} gtest) + add_dependencies(${TEST_OFFERED_SERVICES_INFO_CLIENT} gtest) + add_dependencies(${TEST_OFFERED_SERVICES_INFO_SERVICE} gtest) else() add_dependencies(${TEST_LOCAL_ROUTING_SERVICE} gtest) add_dependencies(${TEST_LOCAL_ROUTING_CLIENT} gtest) @@ -1890,6 +2052,8 @@ if(NOT ${TESTS_BAT}) add_dependencies(build_tests ${TEST_OFFER_EXTERNAL_SD_MESSAGE_SENDER}) add_dependencies(build_tests ${TEST_RESTART_ROUTING_SERVICE}) add_dependencies(build_tests ${TEST_RESTART_ROUTING_CLIENT}) + add_dependencies(build_tests ${TEST_OFFERED_SERVICES_INFO_CLIENT}) + add_dependencies(build_tests ${TEST_OFFERED_SERVICES_INFO_SERVICE}) else() add_dependencies(build_tests ${TEST_LOCAL_ROUTING_SERVICE}) add_dependencies(build_tests ${TEST_LOCAL_ROUTING_CLIENT}) @@ -2025,7 +2189,7 @@ if(NOT ${TESTS_BAT}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp @@ -2037,7 +2201,7 @@ if(NOT ${TESTS_BAT}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_prefer_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_prefer_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} PREFER_TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} PREFER_TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_diff_ports_prefer_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_udp @@ -2045,11 +2209,11 @@ if(NOT ${TESTS_BAT}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_prefer_udp @@ -2057,7 +2221,7 @@ if(NOT ${TESTS_BAT}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_prefer_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_prefer_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} PREFER_TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_MASTER_STARTER} PREFER_TCP ${TEST_SUBSCRIBE_NOTIFY_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_same_ports_prefer_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp @@ -2086,11 +2250,11 @@ if(NOT ${TESTS_BAT}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} TCP ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} TCP_AND_UDP ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_prefer_udp @@ -2098,7 +2262,7 @@ if(NOT ${TESTS_BAT}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_prefer_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_prefer_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} PREFER_TCP ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_SUBSCRIBE_NOTIFY_ONE_MASTER_STARTER} PREFER_TCP ${TEST_SUBSCRIBE_NOTIFY_ONE_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}) set_tests_properties(${TEST_SUBSCRIBE_NOTIFY_ONE_NAME}_diff_client_ids_diff_ports_prefer_tcp PROPERTIES TIMEOUT 120) # cpu load tests @@ -2113,11 +2277,11 @@ if(NOT ${TESTS_BAT}) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} TCP ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} TCP ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} TCP_AND_UDP ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} TCP_AND_UDP ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_prefer_udp @@ -2125,7 +2289,7 @@ if(NOT ${TESTS_BAT}) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_prefer_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_prefer_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} PREFER_TCP ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} PREFER_TCP ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE}) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_diff_ports_prefer_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_udp @@ -2133,7 +2297,7 @@ if(NOT ${TESTS_BAT}) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} TCP ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} TCP ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_both_tcp_and_udp @@ -2145,7 +2309,7 @@ if(NOT ${TESTS_BAT}) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_prefer_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_prefer_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} PREFER_TCP ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE}) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} PREFER_TCP ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE}) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_diff_client_ids_same_ports_prefer_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_diff_client_ids_partial_same_ports_both_tcp_and_udp @@ -2161,11 +2325,11 @@ if(NOT ${TESTS_BAT}) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} TCP ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} MULTIPLE_EVENTS) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} TCP ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} MULTIPLE_EVENTS) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} TCP_AND_UDP ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} MULTIPLE_EVENTS) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} TCP_AND_UDP ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} MULTIPLE_EVENTS) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_prefer_udp @@ -2173,7 +2337,7 @@ if(NOT ${TESTS_BAT}) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_prefer_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_prefer_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} PREFER_TCP ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} MULTIPLE_EVENTS) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} PREFER_TCP ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} MULTIPLE_EVENTS) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_diff_ports_prefer_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_udp @@ -2181,11 +2345,11 @@ if(NOT ${TESTS_BAT}) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} TCP ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} MULTIPLE_EVENTS) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} TCP ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} MULTIPLE_EVENTS) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} TCP_AND_UDP ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} MULTIPLE_EVENTS) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} TCP_AND_UDP ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} MULTIPLE_EVENTS) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_prefer_udp @@ -2193,7 +2357,7 @@ if(NOT ${TESTS_BAT}) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_prefer_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_prefer_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} PREFER_TCP ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} MULTIPLE_EVENTS) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} PREFER_TCP ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} MULTIPLE_EVENTS) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_same_ports_prefer_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_diff_client_ids_partial_same_ports_both_tcp_and_udp @@ -2209,11 +2373,11 @@ if(NOT ${TESTS_BAT}) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} TCP ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} TCP ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} TCP_AND_UDP ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} TCP_AND_UDP ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_prefer_udp @@ -2221,7 +2385,7 @@ if(NOT ${TESTS_BAT}) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_prefer_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_prefer_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} PREFER_TCP ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_CONFIG_FILE} MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} PREFER_TCP ${TEST_INITIAL_EVENT_DIFF_IDS_DIFF_PORTS_MASTER_TCP_CONFIG_FILE} MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_diff_ports_prefer_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_udp @@ -2229,11 +2393,11 @@ if(NOT ${TESTS_BAT}) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} TCP ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} TCP ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_both_tcp_and_udp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} TCP_AND_UDP ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} TCP_AND_UDP ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_both_tcp_and_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_prefer_udp @@ -2241,7 +2405,7 @@ if(NOT ${TESTS_BAT}) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_prefer_udp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_prefer_tcp - COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} PREFER_TCP ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_CONFIG_FILE} MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_INITIAL_EVENT_MASTER_STARTER} PREFER_TCP ${TEST_INITIAL_EVENT_DIFF_IDS_SAME_PORTS_MASTER_TCP_CONFIG_FILE} MULTIPLE_EVENTS SUBSCRIBE_ON_AVAILABILITY) set_tests_properties(${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_same_ports_prefer_tcp PROPERTIES TIMEOUT 120) add_test(NAME ${TEST_INITIAL_EVENT_NAME}_multiple_events_subscribe_on_availability_diff_client_ids_partial_same_ports_both_tcp_and_udp @@ -2260,6 +2424,11 @@ if(NOT ${TESTS_BAT}) COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_OFFER_EXTERNAL_MASTER_STARTER}) set_tests_properties(${TEST_OFFER_NAME}_local PROPERTIES TIMEOUT 360) + # offered services info tets + add_test(NAME ${TEST_OFFERED_SERVICES_INFO_NAME}_local + COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_OFFERED_SERVICES_INFO_LOCAL_STARTER}) + set_tests_properties(${TEST_OFFERED_SERVICES_INFO_NAME}_local PROPERTIES TIMEOUT 180) + # Restart-Routing tests add_test(NAME ${TEST_RESTART_ROUTING_NAME} COMMAND ${PROJECT_BINARY_DIR}/test/${TEST_RESTART_ROUTING_STARTER} diff --git a/test/application_tests/application_test.cpp b/test/application_tests/application_test.cpp index 304a0cc..b7c3ac0 100644 --- a/test/application_tests/application_test.cpp +++ b/test/application_tests/application_test.cpp @@ -138,6 +138,81 @@ TEST_F(someip_application_test, stop_application_twice) app_->stop(); } +/** + * @test Checks whether watchdog handler is invoked (regularly) also after restarting. + */ +TEST_F(someip_application_test, watchdog_handler) +{ + std::atomic<int> cb_count(0); + auto wd_handler = [&] () { + ++cb_count; + }; + + app_->set_watchdog_handler(std::cref(wd_handler), std::chrono::seconds(1)); + + std::promise<bool> its_promise; + std::thread t([&]() { + its_promise.set_value(true); + app_->start(); + }); + EXPECT_TRUE(its_promise.get_future().get()); + + // wait till watchdog handler has been invoked once + while (0 == cb_count.load()) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + ASSERT_EQ(1, cb_count.load()); + + // clear handler (must not be called again) + app_->set_watchdog_handler(nullptr, std::chrono::seconds::zero()); + + // wait doubled interval (used previously).. + std::this_thread::sleep_for(std::chrono::seconds(2)); + // .. to ensure it was not called again + ASSERT_EQ(1, cb_count.load()); + + // enable handler again + app_->set_watchdog_handler(std::cref(wd_handler), std::chrono::seconds(1)); + + // wait till watchdog handler has been invoked again (2nd time) + while (1 == cb_count.load()) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + + app_->stop(); + t.join(); + + // wait doubled interval (used previously).. + std::this_thread::sleep_for(std::chrono::seconds(2)); + // .. to ensure it was not called after stop() + ASSERT_EQ(2, cb_count.load()); + + // restart application (w/ watchdog handler still set) + std::promise<bool> its_promise2; + std::thread t2([&]() { + its_promise2.set_value(true); + app_->start(); + }); + EXPECT_TRUE(its_promise2.get_future().get()); + + // wait till watchdog handler has been invoked again (3rd time) + while (2 == cb_count.load()) { + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } + ASSERT_EQ(3, cb_count.load()); + + // clear handler again (must not be called again), this time via zero interval + app_->set_watchdog_handler(std::cref(wd_handler), std::chrono::seconds::zero()); + + // wait doubled interval (used previously).. + std::this_thread::sleep_for(std::chrono::seconds(2)); + // .. to ensure it was not called again + ASSERT_EQ(3, cb_count.load()); + + app_->stop(); + t2.join(); +} + class someip_application_shutdown_test: public ::testing::Test { protected: diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_tcp.json.in b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_tcp.json.in new file mode 100644 index 0000000..7cb35fb --- /dev/null +++ b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_master_tcp.json.in @@ -0,0 +1,165 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_one", + "id":"0x1111" + }, + { + "name":"initial_event_test_service_two", + "id":"0x2222" + }, + { + "name":"initial_event_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30001", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x1111", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x1112", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x1113", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x1114", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x1115", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30002", + "reliable": + { + "port":"40002", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x2222", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x2223", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x2224", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x2225", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x2226", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30003", + "reliable": + { + "port":"40003", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x3333", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x3334", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x3335", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x3336", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x3337", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x8888", + "instance":"0x0001", + "unreliable":"8888" + } + ], + "routing":"initial_event_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_tcp.json.in b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_tcp.json.in new file mode 100644 index 0000000..320e2a3 --- /dev/null +++ b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_diff_ports_slave_tcp.json.in @@ -0,0 +1,166 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "diagnosis" : "0x63", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_four", + "id":"0x4444" + }, + { + "name":"initial_event_test_service_five", + "id":"0x5555" + }, + { + "name":"initial_event_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30004", + "reliable": + { + "port":"40004", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x4444", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x4445", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x4446", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x4447", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x4448", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30005", + "reliable": + { + "port":"40005", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x5555", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x5556", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x5557", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x5558", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x5559", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30006", + "reliable": + { + "port":"40006", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x6666", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x6667", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x6668", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x6669", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x666a", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x9999", + "instance":"0x0001", + "unreliable":"9999" + } + ], + "routing":"initial_event_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_tcp.json.in b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_tcp.json.in new file mode 100644 index 0000000..7336aa2 --- /dev/null +++ b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_master_tcp.json.in @@ -0,0 +1,165 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_one", + "id":"0x1111" + }, + { + "name":"initial_event_test_service_two", + "id":"0x2222" + }, + { + "name":"initial_event_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x1111", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x1112", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x1113", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x1114", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x1115", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x2222", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x2223", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x2224", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x2225", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x2226", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x3333", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x3334", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x3335", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x3336", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x3337", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x8888", + "instance":"0x0001", + "unreliable":"8888" + } + ], + "routing":"initial_event_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +}
\ No newline at end of file diff --git a/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_tcp.json.in b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_tcp.json.in new file mode 100644 index 0000000..f22ad4e --- /dev/null +++ b/test/initial_event_tests/conf/initial_event_test_diff_client_ids_same_ports_slave_tcp.json.in @@ -0,0 +1,166 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "diagnosis" : "0x63", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"initial_event_test_service_four", + "id":"0x4444" + }, + { + "name":"initial_event_test_service_five", + "id":"0x5555" + }, + { + "name":"initial_event_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x4444", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x4445", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x4446", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x4447", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x4448", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x5555", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x5556", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x5557", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x5558", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x5559", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x6666", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x6667", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x6668", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x6669", + "is_field" : "true", + "is_reliable" : "true" + }, + { + "event" : "0x666a", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x9999", + "instance":"0x0001", + "unreliable":"9999" + } + ], + "routing":"initial_event_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +}
\ No newline at end of file diff --git a/test/initial_event_tests/initial_event_test_client.cpp b/test/initial_event_tests/initial_event_test_client.cpp index ba33265..22940eb 100644 --- a/test/initial_event_tests/initial_event_test_client.cpp +++ b/test/initial_event_tests/initial_event_test_client.cpp @@ -93,7 +93,7 @@ public: other_services_available_[std::make_pair(i.service_id, i.instance_id)] = false; for (std::uint32_t j = 0; j < events_to_subscribe_; j++ ) { - other_services_received_notification_[std::make_pair(i.service_id, i.method_id+j)] = 0; + other_services_received_notification_[std::make_pair(i.service_id, i.method_id + j)] = 0; } if (!subscribe_on_available_) { if (events_to_subscribe_ == 1 ) { @@ -306,6 +306,8 @@ public: ADD_FAILURE() << "[" << std::setw(4) << std::setfill('0') << std::hex << client_number_ << "] " << " Received too much initial events twice: " << received_twice; + } else if (received_normal == (events_to_subscribe_ * (service_infos_.size() - 1))) { + return true; } return false; } diff --git a/test/offered_services_info_test/offered_services_info_test_client.cpp b/test/offered_services_info_test/offered_services_info_test_client.cpp new file mode 100644 index 0000000..13adc58 --- /dev/null +++ b/test/offered_services_info_test/offered_services_info_test_client.cpp @@ -0,0 +1,326 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.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 <chrono> +#include <condition_variable> +#include <iomanip> +#include <iostream> +#include <sstream> +#include <thread> +#include <map> +#include <algorithm> +#include <atomic> + +#include <gtest/gtest.h> + +#include <vsomeip/vsomeip.hpp> +#include "../../implementation/logging/include/logger.hpp" +#include "../../implementation/configuration/include/internal.hpp" + +#include "offered_services_info_test_globals.hpp" + +enum operation_mode_e { + SUBSCRIBE, + METHODCALL +}; + +std::map<vsomeip::service_t, std::set<vsomeip::instance_t>> all_offered_services; +std::map<vsomeip::service_t, std::set<vsomeip::instance_t>> local_offered_services; +std::map<vsomeip::service_t, std::set<vsomeip::instance_t>> remote_offered_services; + +class offered_services_info_test_client { +public: + offered_services_info_test_client(struct offer_test::service_info _service_info,offer_test::service_info _remote_service_info, operation_mode_e _mode) : + service_info_(_service_info), + remote_service_info_(_remote_service_info), + operation_mode_(_mode), + app_(vsomeip::runtime::get()->create_application("offered_services_info_test_client")), + service_available_(false), + wait_until_registered_(true), + wait_until_service_available_(true), + wait_for_stop_(true), + last_received_counter_(0), + last_received_response_(std::chrono::steady_clock::now()), + number_received_responses_(0), + stop_thread_(std::bind(&offered_services_info_test_client::wait_for_stop, this)), + test_offered_services_thread_(std::bind(&offered_services_info_test_client::test_offered_services, this)) { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + + local_offered_services[service_info_.service_id].insert(service_info_.instance_id); + all_offered_services[service_info_.service_id].insert(service_info_.instance_id); + + local_offered_services[service_info_.service_id].insert((vsomeip::instance_t)(service_info_.instance_id + 1)); + all_offered_services[service_info_.service_id].insert((vsomeip::instance_t)(service_info_.instance_id + 1)); + + // offer remote service ID 0x2222 instance ID 0x2 (port configuration added to json file) + remote_offered_services[remote_service_info_.service_id].insert(remote_service_info_.instance_id); + all_offered_services[remote_service_info_.service_id].insert(remote_service_info_.instance_id); + + remote_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 1)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 1)); + all_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 1)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 1)); + + remote_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 2)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 2)); + all_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 2)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 2)); + + app_->register_state_handler( + std::bind(&offered_services_info_test_client::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(vsomeip::ANY_SERVICE, + vsomeip::ANY_INSTANCE, vsomeip::ANY_METHOD, + std::bind(&offered_services_info_test_client::on_message, this, + std::placeholders::_1)); + + app_->register_availability_handler(service_info_.service_id, + service_info_.instance_id, + std::bind(&offered_services_info_test_client::on_availability, this, + std::placeholders::_1, std::placeholders::_2, + std::placeholders::_3)); + app_->request_service(service_info_.service_id, + service_info_.instance_id); + + app_->start(); + } + + ~offered_services_info_test_client() { + test_offered_services_thread_.join(); + stop_thread_.join(); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard<std::mutex> its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_availability(vsomeip::service_t _service, + vsomeip::instance_t _instance, bool _is_available) { + VSOMEIP_INFO << "Service [" << std::setw(4) + << std::setfill('0') << std::hex << _service << "." << _instance + << "] is " << (_is_available ? "available":"not available") << "."; + std::lock_guard<std::mutex> its_lock(mutex_); + if(_is_available) { + wait_until_service_available_ = false; + condition_.notify_one(); + } else { + wait_until_service_available_ = true; + condition_.notify_one(); + } + } + + void on_message(const std::shared_ptr<vsomeip::message> &_message) { + if (_message->get_message_type() == vsomeip::message_type_e::MT_RESPONSE) { + on_response(_message); + } + } + + void on_response(const std::shared_ptr<vsomeip::message> &_message) { + ++number_received_responses_; + static bool first(true); + if (first) { + first = false; + last_received_response_ = std::chrono::steady_clock::now(); + return; + } + EXPECT_EQ(service_info_.service_id, _message->get_service()); + EXPECT_EQ(service_info_.method_id, _message->get_method()); + EXPECT_EQ(service_info_.instance_id, _message->get_instance()); + ASSERT_LT(std::chrono::duration_cast<std::chrono::milliseconds>( + std::chrono::steady_clock::now() - last_received_response_).count(), + (std::chrono::milliseconds(VSOMEIP_DEFAULT_WATCHDOG_TIMEOUT) + + std::chrono::milliseconds(1000)).count()); + last_received_response_ = std::chrono::steady_clock::now(); + std::cout << "."; + std::cout.flush(); + } + + void test_offered_services() { + if (operation_mode_ != operation_mode_e::METHODCALL) { + return; + } + std::unique_lock<std::mutex> its_lock(mutex_); + while (wait_until_registered_) { + condition_.wait(its_lock); + } + + while (wait_until_service_available_) { + condition_.wait(its_lock); + } + its_lock.unlock(); + its_lock.release(); + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + VSOMEIP_INFO << "TEST LOCAL SERVICES"; + app_->get_offered_services_async(vsomeip::offer_type_e::OT_LOCAL, std::bind(&offered_services_info_test_client::on_offered_services_local, this, std::placeholders::_1)); + + VSOMEIP_INFO << "TEST REMOTE SERVICES"; + app_->get_offered_services_async(vsomeip::offer_type_e::OT_REMOTE, std::bind(&offered_services_info_test_client::on_offered_services_remote, this, std::placeholders::_1)); + + VSOMEIP_INFO << "TEST ALL SERVICES"; + app_->get_offered_services_async(vsomeip::offer_type_e::OT_ALL, std::bind(&offered_services_info_test_client::on_offered_services_all, this, std::placeholders::_1)); + + + // send shutdown command to service + bool send(false); + { + std::lock_guard<std::mutex> its_lock(mutex_); + send = !wait_until_service_available_; + } + if (send) { + std::shared_ptr<vsomeip::message> its_req = vsomeip::runtime::get()->create_request(); + its_req->set_service(service_info_.service_id); + its_req->set_instance(service_info_.instance_id); + its_req->set_method(service_info_.shutdown_method_id); + app_->send(its_req); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + } else { + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + { + std::lock_guard<std::mutex> its_lock(stop_mutex_); + wait_for_stop_ = false; + VSOMEIP_INFO << "going down. Sent shutdown command to service"; + stop_condition_.notify_one(); + } + } + + void on_offered_services_local( const std::vector<std::pair<vsomeip::service_t, vsomeip::instance_t>> &_services) { + std::cout << "ON OFFERED SERVICES LOCAL CALLBACK START" << std::endl; + bool local_service_test_failed(true); + for (auto its_pair : _services) { + local_service_test_failed = true; + std::cout << "CALLBACK VALUE -> Service: "<< std::hex << std::get<0>(its_pair) << " instance: " << std::get<1>(its_pair) << std::endl; + auto found_service = local_offered_services.find(its_pair.first); + if (found_service != local_offered_services.end()) { + auto found_instance = found_service->second.find(its_pair.second); + if (found_instance != found_service->second.end()) { + local_service_test_failed = false; + } + } + EXPECT_FALSE(local_service_test_failed); + } + std::cout << "ON OFFERED SERVICES LOCAL CALLBACK END" << std::endl; + } + + void on_offered_services_remote( const std::vector<std::pair<vsomeip::service_t, vsomeip::instance_t>> &_services) { + std::cout << "ON OFFERED SERVICES REMOTE CALLBACK START" << std::endl; + bool remote_service_test_failed(true); + for (auto its_pair : _services) { + remote_service_test_failed = true; + std::cout << "CALLBACK VALUE -> Service: " << std::hex << std::get<0>(its_pair) << " instance: " << std::get<1>(its_pair) << std::endl; + auto found_service = remote_offered_services.find(its_pair.first); + if (found_service != remote_offered_services.end()) { + auto found_instance = found_service->second.find(its_pair.second); + if (found_instance != found_service->second.end()) { + remote_service_test_failed = false; + } + } + EXPECT_FALSE(remote_service_test_failed); + } + std::cout << "ON OFFERED SERVICES REMOTE CALLBACK END" << std::endl; + } + + void on_offered_services_all( const std::vector<std::pair<vsomeip::service_t, vsomeip::instance_t>> &_services) { + std::cout << "ON OFFERED SERVICES ALL CALLBACK START" << std::endl; + bool all_service_test_failed(true); + for (auto its_pair : _services) { + all_service_test_failed = true; + std::cout << "CALLBACK VALUE -> Service: " << std::hex << std::get<0>(its_pair) << " instance: " << std::get<1>(its_pair) << std::endl; + auto found_service = all_offered_services.find(its_pair.first); + if (found_service != all_offered_services.end()) { + auto found_instance = found_service->second.find(its_pair.second); + if (found_instance != found_service->second.end()) { + all_service_test_failed = false; + } + } + EXPECT_FALSE(all_service_test_failed); + } + std::cout << "ON OFFERED SERVICES ALL CALLBACK END" << std::endl; + } + + void wait_for_stop() { + std::unique_lock<std::mutex> its_lock(stop_mutex_); + while (wait_for_stop_) { + stop_condition_.wait(its_lock); + } + VSOMEIP_INFO << "going down"; + app_->clear_all_handler(); + app_->stop(); + } + +private: + struct offer_test::service_info service_info_; + struct offer_test::service_info remote_service_info_; + operation_mode_e operation_mode_; + std::shared_ptr<vsomeip::application> app_; + bool service_available_; + + bool wait_until_registered_; + bool wait_until_service_available_; + std::mutex mutex_; + std::condition_variable condition_; + + bool wait_for_stop_; + std::mutex stop_mutex_; + std::condition_variable stop_condition_; + + std::uint32_t last_received_counter_; + std::chrono::steady_clock::time_point last_received_response_; + std::atomic<std::uint32_t> number_received_responses_; + std::thread stop_thread_; + std::thread test_offered_services_thread_; +}; + +static operation_mode_e passed_mode = operation_mode_e::METHODCALL; + +TEST(someip_offered_services_info_test, check_offered_services) +{ + offered_services_info_test_client its_sample(offer_test::service, offer_test::remote_service, passed_mode); +} + +#ifndef _WIN32 +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + if(argc < 2) { + std::cerr << "Please specify a operation mode, like: " << argv[0] << " SUBSCRIBE" << std::endl; + std::cerr << "Valid operation modes are SUBSCRIBE and METHODCALL" << std::endl; + return 1; + } + + if (std::string("SUBSCRIBE") == std::string(argv[1])) { + passed_mode = operation_mode_e::SUBSCRIBE; + } else if (std::string("METHODCALL") == std::string(argv[1])) { + passed_mode = operation_mode_e::METHODCALL; + } else { + std::cerr << "Wrong operation mode passed, exiting" << std::endl; + std::cerr << "Please specify a operation mode, like: " << argv[0] << " SUBSCRIBE" << std::endl; + std::cerr << "Valid operation modes are SUBSCRIBE and METHODCALL" << std::endl; + return 1; + } + +#if 0 + if (argc >= 4 && std::string("SAME_SERVICE_ID") == std::string(argv[3])) { + use_same_service_id = true; + } else { + use_same_service_id = false; + } +#endif + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/offered_services_info_test/offered_services_info_test_globals.hpp b/test/offered_services_info_test/offered_services_info_test_globals.hpp new file mode 100644 index 0000000..b74dfab --- /dev/null +++ b/test/offered_services_info_test/offered_services_info_test_globals.hpp @@ -0,0 +1,29 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.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 OFFER_TEST_GLOBALS_HPP_ +#define OFFER_TEST_GLOBALS_HPP_ + +namespace offer_test { + +struct service_info { + vsomeip::service_t service_id; + vsomeip::instance_t instance_id; + vsomeip::method_t method_id; + vsomeip::event_t event_id; + vsomeip::eventgroup_t eventgroup_id; + vsomeip::method_t shutdown_method_id; +}; + +uint8_t num_all_offered_services = 5; +uint8_t num_local_offered_services = 2; +uint8_t num_remote_offered_services = 3; + + +struct service_info service = { 0x1111, 0x1, 0x1111, 0x1111, 0x1000, 0x1404 }; +struct service_info remote_service = { 0x2222, 0x2, 0x2222, 0x2222, 0x2000, 0x2808 }; +} + +#endif /* OFFER_TEST_GLOBALS_HPP_ */ diff --git a/test/offered_services_info_test/offered_services_info_test_local.json b/test/offered_services_info_test/offered_services_info_test_local.json new file mode 100644 index 0000000..768a7ca --- /dev/null +++ b/test/offered_services_info_test/offered_services_info_test_local.json @@ -0,0 +1,57 @@ +{ + "unicast" : "127.0.0.1", + "diagnosis":"0x12", + "logging" : + { + "level" : "debug", + "console" : "true", + "file" : + { + "enable" : "false", + "path" : "/tmp/vsomeip.log" + }, + + "dlt" : "false" + }, + + "applications" : + [ + { + "name" : "offered_services_info_test_service", + "id" : "0x1277" + } + ], + + "services" : + [ + { + "service" : "0x1111", + "instance" : "0x1" + }, + { + "service" : "0x2222", + "instance" : "0x2", + "reliable" : { "port" : "30502" }, + "unreliable" : "31002" + }, + { + "service" : "0x2223", + "instance" : "0x3", + "reliable" : { "port" : "30503" } + }, + { + "service" : "0x2224", + "instance" : "0x4", + "unreliable" : "31004" + } + ], + + "routing" : "vsomeipd", + "service-discovery" : + { + "enable" : "false", + "multicast" : "224.0.0.1", + "port" : "30490", + "protocol" : "udp" + } +} diff --git a/test/offered_services_info_test/offered_services_info_test_local_starter.sh b/test/offered_services_info_test/offered_services_info_test_local_starter.sh new file mode 100755 index 0000000..68482f9 --- /dev/null +++ b/test/offered_services_info_test/offered_services_info_test_local_starter.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# Copyright (C) 2015-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# Purpose: This script is needed to start the services with +# one command. This is necessary as ctest - which is used to run the +# tests - isn't able to start multiple binaries for one testcase. Therefore +# the testcase simply executes this script. This script then runs the services +# and checks that all exit successfully. + +FAIL=0 + +cat <<End-of-message +******************************************************************************* +******************************************************************************* +** Running first test +******************************************************************************* +******************************************************************************* +End-of-message + +# Rejecting offer of service instance whose hosting application is still +# alive: +# * start application which offers service +# * start two clients which continuously exchanges messages with the service +# * start application which offers the same service again -> should be +# rejected and an error message should be printed. +# * Message exchange with client application should not be interrupted. + +# Array for client pids +CLIENT_PIDS=() +export VSOMEIP_CONFIGURATION=offered_services_info_test_local.json +# Start the services (vsomeipd as app name) +./offered_services_info_test_service 1 & #vsomeipd as app name +PID_SERVICE_ONE=$! +./offered_services_info_test_client METHODCALL & +CLIENT_PIDS+=($!) + +# Wait until all clients are finished +for job in ${CLIENT_PIDS[*]} +do + # Fail gets incremented if a client exits with a non-zero exit code + wait $job || FAIL=$(($FAIL+1)) +done + +# kill the services +kill $PID_SERVICE_ONE +sleep 1 + + +# Check if everything went well +if [ $FAIL -eq 0 ] +then + exit 0 +else + exit 1 +fi diff --git a/test/offered_services_info_test/offered_services_info_test_service.cpp b/test/offered_services_info_test/offered_services_info_test_service.cpp new file mode 100644 index 0000000..0476f30 --- /dev/null +++ b/test/offered_services_info_test/offered_services_info_test_service.cpp @@ -0,0 +1,254 @@ +// Copyright (C) 2014-2017 Bayerische Motoren Werke Aktiengesellschaft (BMW AG) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.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 <chrono> +#include <condition_variable> +#include <iomanip> +#include <iostream> +#include <sstream> +#include <thread> +#include <map> +#include <algorithm> +#include <atomic> + +#include <gtest/gtest.h> + +#include <vsomeip/vsomeip.hpp> +#include "../../implementation/logging/include/logger.hpp" + +#include "offered_services_info_test_globals.hpp" + +static std::string service_number; +std::map<vsomeip::service_t, std::set<vsomeip::instance_t>> all_offered_services; +std::map<vsomeip::service_t, std::set<vsomeip::instance_t>> local_offered_services; +std::map<vsomeip::service_t, std::set<vsomeip::instance_t>> remote_offered_services; + + +class offer_test_service { +public: + offer_test_service(struct offer_test::service_info _service_info, struct offer_test::service_info _remote_service_info) : + service_info_(_service_info), + remote_service_info_(_remote_service_info), + // service with number 1 uses "vsomeipd" as application name + // this way the same json file can be reused for all local tests + // including the ones with vsomeipd + app_(vsomeip::runtime::get()->create_application( + (service_number == "1") ? "vsomeipd" : + "offered_services_info_test_service" + service_number)), + counter_(0), + wait_until_registered_(true), + shutdown_method_called_(false), + offer_thread_(std::bind(&offer_test_service::run, this)) { + if (!app_->init()) { + ADD_FAILURE() << "Couldn't initialize application"; + return; + } + app_->register_state_handler( + std::bind(&offer_test_service::on_state, this, + std::placeholders::_1)); + + app_->register_message_handler(service_info_.service_id, + service_info_.instance_id, service_info_.method_id, + std::bind(&offer_test_service::on_request, this, + std::placeholders::_1)); + + app_->register_message_handler(service_info_.service_id, + service_info_.instance_id, service_info_.shutdown_method_id, + std::bind(&offer_test_service::on_shutdown_method_called, this, + std::placeholders::_1)); + app_->start(); + } + + ~offer_test_service() { + offer_thread_.join(); + } + + void offer() { + //offer local services + app_->offer_service(service_info_.service_id, service_info_.instance_id); + local_offered_services[service_info_.service_id].insert(service_info_.instance_id); + all_offered_services[service_info_.service_id].insert(service_info_.instance_id); + + app_->offer_service(service_info_.service_id, (vsomeip::instance_t)(service_info_.instance_id + 1)); + local_offered_services[service_info_.service_id].insert((vsomeip::instance_t)(service_info_.instance_id + 1)); + all_offered_services[service_info_.service_id].insert((vsomeip::instance_t)(service_info_.instance_id + 1)); + + // offer remote service ID 0x2222 instance ID 0x2 (port configuration added to json file) + app_->offer_service(remote_service_info_.service_id, remote_service_info_.instance_id); // reliable and unreliable port + remote_offered_services[remote_service_info_.service_id].insert(remote_service_info_.instance_id); + all_offered_services[remote_service_info_.service_id].insert(remote_service_info_.instance_id); + + + app_->offer_service((vsomeip::service_t)(remote_service_info_.service_id + 1), (vsomeip::instance_t)(remote_service_info_.instance_id + 1)); // only reliable port + remote_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 1)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 1)); + all_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 1)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 1)); + + + app_->offer_service((vsomeip::service_t)(remote_service_info_.service_id + 2), (vsomeip::instance_t)(remote_service_info_.instance_id + 2)); // only unreliable port + remote_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 2)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 2)); + all_offered_services[(vsomeip::service_t)(remote_service_info_.service_id + 2)].insert((vsomeip::instance_t)(remote_service_info_.instance_id + 2)); + } + + void on_state(vsomeip::state_type_e _state) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_state == vsomeip::state_type_e::ST_REGISTERED ? + "registered." : "deregistered."); + + if (_state == vsomeip::state_type_e::ST_REGISTERED) { + std::lock_guard<std::mutex> its_lock(mutex_); + wait_until_registered_ = false; + condition_.notify_one(); + } + } + + void on_request(const std::shared_ptr<vsomeip::message> &_message) { + app_->send(vsomeip::runtime::get()->create_response(_message)); + } + + void on_shutdown_method_called(const std::shared_ptr<vsomeip::message> &_message) { + (void)_message; + shutdown_method_called_ = true; + + app_->stop_offer_service(service_info_.service_id, service_info_.instance_id); + app_->stop_offer_service(service_info_.service_id, (vsomeip::instance_t)(service_info_.instance_id + 1)); + + app_->stop_offer_service(remote_service_info_.service_id, remote_service_info_.instance_id); // reliable and unreliable port + app_->stop_offer_service((vsomeip::service_t)(remote_service_info_.service_id + 1), (vsomeip::instance_t)(remote_service_info_.instance_id + 1)); // only reliable port + app_->stop_offer_service((vsomeip::service_t)(remote_service_info_.service_id + 2), (vsomeip::instance_t)(remote_service_info_.instance_id + 2)); // only unreliable port + + app_->clear_all_handler(); + app_->stop(); + } + + void run() { + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Running"; + std::unique_lock<std::mutex> its_lock(mutex_); + while (wait_until_registered_) { + condition_.wait(its_lock); + } + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Offering"; + offer(); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + + VSOMEIP_INFO << "TEST LOCAL SERVICES"; + app_->get_offered_services_async(vsomeip::offer_type_e::OT_LOCAL, std::bind(&offer_test_service::on_offered_services_local, this, std::placeholders::_1)); + + VSOMEIP_INFO << "TEST REMOTE SERVICES"; + app_->get_offered_services_async(vsomeip::offer_type_e::OT_REMOTE, std::bind(&offer_test_service::on_offered_services_remote, this, std::placeholders::_1)); + + VSOMEIP_INFO << "TEST ALL SERVICES"; + app_->get_offered_services_async(vsomeip::offer_type_e::OT_ALL, std::bind(&offer_test_service::on_offered_services_all, this, std::placeholders::_1)); + + VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex + << service_info_.service_id << "] Notifying"; + + while(!shutdown_method_called_) { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + } + + + void on_offered_services_local( const std::vector<std::pair<vsomeip::service_t, vsomeip::instance_t>> &_services) { + std::cout << "ON OFFERED SERVICES LOCAL CALLBACK START" << std::endl; + bool local_service_test_failed(true); + uint16_t i=0; + for (auto its_pair : _services) { + local_service_test_failed = true; + std::cout << "CALLBACK VALUE -> Service: "<< std::hex << std::get<0>(its_pair) << " instance: " << std::get<1>(its_pair) << std::endl; + auto found_service = local_offered_services.find(its_pair.first); + if (found_service != local_offered_services.end()) { + auto found_instance = found_service->second.find(its_pair.second); + if (found_instance != found_service->second.end()) { + i++; + local_service_test_failed = false; + } + } + EXPECT_FALSE(local_service_test_failed); + } + EXPECT_EQ(offer_test::num_local_offered_services, i); + + std::cout << "ON OFFERED SERVICES LOCAL CALLBACK END" << std::endl; + } + + + void on_offered_services_remote( const std::vector<std::pair<vsomeip::service_t, vsomeip::instance_t>> &_services) { + std::cout << "ON OFFERED SERVICES REMOTE CALLBACK START" << std::endl; + bool remote_service_test_failed(true); + uint16_t i=0; + for (auto its_pair : _services) { + remote_service_test_failed = true; + std::cout << "CALLBACK VALUE -> Service: " << std::hex << std::get<0>(its_pair) << " instance: " << std::get<1>(its_pair) << std::endl; + auto found_service = remote_offered_services.find(its_pair.first); + if (found_service != remote_offered_services.end()) { + auto found_instance = found_service->second.find(its_pair.second); + if (found_instance != found_service->second.end()) { + i++; + remote_service_test_failed = false; + } + } + EXPECT_FALSE(remote_service_test_failed); + } + EXPECT_EQ(offer_test::num_remote_offered_services, i); + + std::cout << "ON OFFERED SERVICES REMOTE CALLBACK END" << std::endl; + } + + + void on_offered_services_all( const std::vector<std::pair<vsomeip::service_t, vsomeip::instance_t>> &_services) { + + std::cout << "ON OFFERED SERVICES ALL CALLBACK START" << std::endl; + bool all_service_test_failed(true); + uint16_t i=0; + for (auto its_pair : _services) { + all_service_test_failed = true; + std::cout << "CALLBACK VALUE -> Service: " << std::hex << std::get<0>(its_pair) << " instance: " << std::get<1>(its_pair) << std::endl; + auto found_service = all_offered_services.find(its_pair.first); + if (found_service != all_offered_services.end()) { + auto found_instance = found_service->second.find(its_pair.second); + if (found_instance != found_service->second.end()) { + i++; + all_service_test_failed = false; + } + } + EXPECT_FALSE(all_service_test_failed); + } + EXPECT_EQ(offer_test::num_all_offered_services, i); + std::cout << "ON OFFERED SERVICES ALL CALLBACK END" << std::endl; + } + +private: + struct offer_test::service_info service_info_; + struct offer_test::service_info remote_service_info_; + std::shared_ptr<vsomeip::application> app_; + std::uint32_t counter_; + + bool wait_until_registered_; + std::mutex mutex_; + std::condition_variable condition_; + std::atomic<bool> shutdown_method_called_; + std::thread offer_thread_; +}; + +TEST(someip_offer_test, notify_increasing_counter) +{ + offer_test_service its_sample(offer_test::service, offer_test::remote_service); +} + +#ifndef _WIN32 +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + if(argc < 2) { + std::cerr << "Please specify a service number, like: " << argv[0] << " 2" << std::endl; + return 1; + } + + service_number = std::string(argv[1]); + return RUN_ALL_TESTS(); +} +#endif diff --git a/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_tcp.json.in b/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_tcp.json.in new file mode 100644 index 0000000..b684f56 --- /dev/null +++ b/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_master_tcp.json.in @@ -0,0 +1,104 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_one_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_one_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_one_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30001", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x1111", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30002", + "reliable": + { + "port":"40002", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x2222", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30003", + "reliable": + { + "port":"40003", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x3333", + "is_field" : "true", + "is_reliable" : "true" + } + ] + } + ], + "routing":"subscribe_notify_one_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + }, + "supports_selective_broadcasts" : + { + "address" : "@TEST_IP_SLAVE@" + } +}
\ No newline at end of file diff --git a/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_tcp.json.in b/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_tcp.json.in new file mode 100644 index 0000000..dbe0635 --- /dev/null +++ b/test/subscribe_notify_one_tests/conf/subscribe_notify_one_test_diff_client_ids_diff_ports_slave_tcp.json.in @@ -0,0 +1,104 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_one_test_service_four", + "id":"0x4444" + }, + { + "name":"subscribe_notify_one_test_service_five", + "id":"0x5555" + }, + { + "name":"subscribe_notify_one_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30004", + "reliable": + { + "port":"40004", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x4444", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30005", + "reliable": + { + "port":"40005", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x5555", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30006", + "reliable": + { + "port":"40006", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x6666", + "is_field" : "true", + "is_reliable" : "true" + } + ] + } + ], + "routing":"subscribe_notify_one_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + }, + "supports_selective_broadcasts" : + { + "address" : "@TEST_IP_MASTER@" + } +}
\ No newline at end of file diff --git a/test/subscribe_notify_one_tests/subscribe_notify_one_test_service.cpp b/test/subscribe_notify_one_tests/subscribe_notify_one_test_service.cpp index b035b96..9c96f73 100644 --- a/test/subscribe_notify_one_tests/subscribe_notify_one_test_service.cpp +++ b/test/subscribe_notify_one_tests/subscribe_notify_one_test_service.cpp @@ -171,6 +171,7 @@ public: } bool on_subscription(vsomeip::client_t _client, bool _subscribed) { + std::lock_guard<std::mutex> its_subscribers_lock(subscribers_mutex_); // check if all other services have subscribed: // -1 for placeholder in array and -1 for the service itself if (subscribers_.size() == subscribe_notify_one_test::service_infos.size() - 2) { @@ -467,6 +468,8 @@ private: std::unordered_set<vsomeip::client_t> subscribers_; std::atomic<uint32_t> subscription_state_handler_called_; std::atomic<bool> subscription_error_occured_; + + std::mutex subscribers_mutex_; }; static int service_number; diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_tcp.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_tcp.json.in new file mode 100644 index 0000000..785bec0 --- /dev/null +++ b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_master_tcp.json.in @@ -0,0 +1,100 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30001", + "reliable": + { + "port":"40001", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x1111", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30002", + "reliable": + { + "port":"40002", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x2222", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30003", + "reliable": + { + "port":"40003", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x3333", + "is_field" : "true", + "is_reliable" : "true" + } + ] + } + ], + "routing":"subscribe_notify_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_tcp.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_tcp.json.in new file mode 100644 index 0000000..d431acf --- /dev/null +++ b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_diff_ports_slave_tcp.json.in @@ -0,0 +1,100 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_four", + "id":"0x4444" + }, + { + "name":"subscribe_notify_test_service_five", + "id":"0x5555" + }, + { + "name":"subscribe_notify_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30004", + "reliable": + { + "port":"40004", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x4444", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30005", + "reliable": + { + "port":"40005", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x5555", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30006", + "reliable": + { + "port":"40006", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x6666", + "is_field" : "true", + "is_reliable" : "true" + } + ] + } + ], + "routing":"subscribe_notify_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +} diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_tcp.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_tcp.json.in new file mode 100644 index 0000000..376642e --- /dev/null +++ b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_master_tcp.json.in @@ -0,0 +1,100 @@ +{ + "unicast":"@TEST_IP_MASTER@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_one", + "id":"0x1111" + }, + { + "name":"subscribe_notify_test_service_two", + "id":"0x2222" + }, + { + "name":"subscribe_notify_test_service_three", + "id":"0x3333" + } + ], + "services": + [ + { + "service":"0x1111", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x1111", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x2222", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x2222", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x3333", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x3333", + "is_field" : "true", + "is_reliable" : "true" + } + ] + } + ], + "routing":"subscribe_notify_test_service_one", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +}
\ No newline at end of file diff --git a/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_tcp.json.in b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_tcp.json.in new file mode 100644 index 0000000..a0a4b2c --- /dev/null +++ b/test/subscribe_notify_tests/conf/subscribe_notify_test_diff_client_ids_same_ports_slave_tcp.json.in @@ -0,0 +1,100 @@ +{ + "unicast":"@TEST_IP_SLAVE@", + "logging": + { + "level":"warning", + "console":"true", + "file": + { + "enable":"false", + "path":"/tmp/vsomeip.log" + }, + "dlt":"false" + }, + "applications": + [ + { + "name":"subscribe_notify_test_service_four", + "id":"0x4444" + }, + { + "name":"subscribe_notify_test_service_five", + "id":"0x5555" + }, + { + "name":"subscribe_notify_test_service_six", + "id":"0x6666" + } + ], + "services": + [ + { + "service":"0x4444", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x4444", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x5555", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x5555", + "is_field" : "true", + "is_reliable" : "true" + } + ] + }, + { + "service":"0x6666", + "instance":"0x0001", + "unreliable":"30000", + "reliable": + { + "port":"40000", + "enable-magic-cookies":"false" + }, + "events" : + [ + { + "event" : "0x6666", + "is_field" : "true", + "is_reliable" : "true" + } + ] + } + ], + "routing":"subscribe_notify_test_service_four", + "service-discovery": + { + "enable":"true", + "multicast":"224.0.0.1", + "port":"30490", + "protocol":"udp", + "initial_delay_min" : "10", + "initial_delay_max" : "10", + "repetitions_base_delay" : "30", + "repetitions_max" : "3", + "cyclic_offer_delay" : "1000", + "ttl" : "3" + } +}
\ No newline at end of file diff --git a/test/subscribe_notify_tests/subscribe_notify_test_service.cpp b/test/subscribe_notify_tests/subscribe_notify_test_service.cpp index b49831c..343976e 100644 --- a/test/subscribe_notify_tests/subscribe_notify_test_service.cpp +++ b/test/subscribe_notify_tests/subscribe_notify_test_service.cpp @@ -170,6 +170,7 @@ public: } bool on_subscription(vsomeip::client_t _client, bool _subscribed) { + std::lock_guard<std::mutex> its_lock(subscribers_mutex_); static bool notified(false); if (_subscribed) { subscribers_.insert(_client); @@ -239,7 +240,7 @@ public: } break; case vsomeip::subscription_type_e::SU_RELIABLE_AND_UNRELIABLE: - if (all_notifications_received_tcp_and_udp()) { + if (all_notifications_received()) { notify = true; } break; @@ -459,6 +460,8 @@ private: std::thread notify_thread_; std::atomic<uint32_t> subscription_state_handler_called_; std::atomic<bool> subscription_error_occured_; + + std::mutex subscribers_mutex_; }; static int service_number; |