diff options
15 files changed, 174 insertions, 50 deletions
diff --git a/config/vsomeip.xml b/config/vsomeip.xml index 0fb5dfd..1221f55 100644 --- a/config/vsomeip.xml +++ b/config/vsomeip.xml @@ -1,6 +1,6 @@ <!-- vsomeip test configuration file --> <someip> - <unicast>127.0.0.1</unicast> + <address>10.0.2.15</address> <logging> <level>trace</level> <console>true</console> @@ -42,7 +42,8 @@ </service> </servicegroup> <servicegroup> - <address>10.0.2.15</address> + <name>remote</name> + <address>10.0.2.17</address> <service> <service-id>0x4466</service-id> <instance-id>0x0421</instance-id> diff --git a/exportmap.gcc b/exportmap.gcc index 2bcbb11..62963b6 100644 --- a/exportmap.gcc +++ b/exportmap.gcc @@ -5,6 +5,10 @@ global: vsomeip::configuration::*; *vsomeip::deserializer; vsomeip::deserializer::*; + *vsomeip::tcp*; + vsomeip::tcp*; + *vsomeip::udp*; + vsomeip::udp*; *vsomeip::logger; vsomeip::logger::get*; *vsomeip::message_base_impl; diff --git a/implementation/configuration/include/configuration_impl.hpp b/implementation/configuration/include/configuration_impl.hpp index fde5f0b..9a1d14b 100644 --- a/implementation/configuration/include/configuration_impl.hpp +++ b/implementation/configuration/include/configuration_impl.hpp @@ -48,6 +48,7 @@ public: std::string get_group(service_t _service, instance_t _instance) const; std::set< std::string > get_servicegroups() const; + bool is_local_servicegroup(const std::string &_name) const; uint32_t get_min_initial_delay(const std::string &_name) const; uint32_t get_max_initial_delay(const std::string &_name) const; uint32_t get_repetition_base_delay(const std::string &_name) const; diff --git a/implementation/configuration/src/configuration_impl.cpp b/implementation/configuration/src/configuration_impl.cpp index 3230c1f..53bad42 100644 --- a/implementation/configuration/src/configuration_impl.cpp +++ b/implementation/configuration/src/configuration_impl.cpp @@ -436,6 +436,18 @@ std::set< std::string > configuration_impl::get_servicegroups() const { return its_keys; } +bool configuration_impl::is_local_servicegroup(const std::string &_name) const { + bool is_local(false); + + servicegroup *its_servicegroup = find_servicegroup(_name); + if (its_servicegroup) { + is_local = (its_servicegroup->address_ == "local" || + its_servicegroup->address_ == get_address().to_string()); + } + + return is_local; +} + uint32_t configuration_impl::get_min_initial_delay(const std::string &_name) const { uint32_t its_delay = 0; diff --git a/implementation/routing/include/routing_manager.hpp b/implementation/routing/include/routing_manager.hpp index f66839d..022aefa 100644 --- a/implementation/routing/include/routing_manager.hpp +++ b/implementation/routing/include/routing_manager.hpp @@ -81,6 +81,8 @@ public: service_t _service, instance_t _instance, event_t _event, const std::vector< byte_t > &_value) = 0; + virtual bool is_available(service_t _service, instance_t _instance) const = 0; + virtual endpoint * find_local(client_t _client) = 0; virtual endpoint * find_local(service_t _service, instance_t _instance) = 0; virtual endpoint * find_or_create_local(client_t _client) = 0; diff --git a/implementation/routing/include/routing_manager_impl.hpp b/implementation/routing/include/routing_manager_impl.hpp index 776c328..f10440b 100644 --- a/implementation/routing/include/routing_manager_impl.hpp +++ b/implementation/routing/include/routing_manager_impl.hpp @@ -104,6 +104,8 @@ public: void on_message(const byte_t *_data, length_t _length, endpoint *_receiver); + bool is_available(service_t _service, instance_t _instance) const; + endpoint * find_local(client_t _client); endpoint * find_or_create_local(client_t _client); void remove_local(client_t _client); @@ -140,13 +142,20 @@ private: std::shared_ptr< sd::service_discovery > discovery_; // Routing info + + // Local std::map< client_t, std::shared_ptr< endpoint > > local_clients_; std::map< service_t, std::map< instance_t, client_t > > local_services_; - std::map< client_t, std::shared_ptr< endpoint > > clients_; + // Server endpoints for local services std::map< uint16_t, std::map< bool, std::shared_ptr< endpoint > > > service_endpoints_; std::map< service_t, std::map< endpoint *, instance_t > > service_instances_; + // Client endpoints for remote services + std::map< service_t, + std::map< instance_t, + std::map< bool, std::shared_ptr< endpoint > > > > remote_services_; + // Servicegroups std::map< std::string, std::shared_ptr< servicegroup > > servicegroups_; std::map< service_t, std::map< instance_t, std::shared_ptr< serviceinfo > > > services_; @@ -158,6 +167,7 @@ private: std::set< std::shared_ptr< endpoint > > > > > eventgroups_; std::map< service_t, std::map< instance_t, std::map< event_t, eventgroup_t > > > events_; + // Mutexes std::recursive_mutex endpoint_mutex_; std::mutex serialize_mutex_; }; diff --git a/implementation/routing/include/routing_manager_proxy.hpp b/implementation/routing/include/routing_manager_proxy.hpp index 75335a4..361446e 100644 --- a/implementation/routing/include/routing_manager_proxy.hpp +++ b/implementation/routing/include/routing_manager_proxy.hpp @@ -86,13 +86,13 @@ public: void on_message(const byte_t *_data, length_t _length, endpoint *_receiver); void on_routing_info(const byte_t *_data, uint32_t _size); + bool is_available(service_t _service, instance_t _instance) const; + endpoint * find_local(client_t _client); endpoint * find_local(service_t _service, instance_t _instance); endpoint * find_or_create_local(client_t _client); void remove_local(client_t _client); - std::set< std::shared_ptr< service_info > > get_services() const; - private: void register_application(); void deregister_application(); diff --git a/implementation/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp index b43cb7c..9196d28 100644 --- a/implementation/routing/src/routing_manager_impl.cpp +++ b/implementation/routing/src/routing_manager_impl.cpp @@ -303,6 +303,26 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, insta } } +bool routing_manager_impl::is_available(service_t _service, instance_t _instance) const { + auto find_local_service = local_services_.find(_service); + if (find_local_service != local_services_.end()) { + auto find_local_instance = find_local_service->second.find(_instance); + if (find_local_instance != find_local_service->second.end()) { + return true; + } + } + + auto find_remote_service = remote_services_.find(_service); + if (find_remote_service != remote_services_.end()) { + auto find_remote_instance = find_remote_service->second.find(_instance); + if (find_remote_instance != find_remote_service->second.end()) { + return true; + } + } + + return false; +} + const std::map< std::string, std::shared_ptr< servicegroup > > & routing_manager_impl::get_servicegroups() const { return servicegroups_; } @@ -421,8 +441,8 @@ endpoint * routing_manager_impl::find_or_create_service_endpoint(uint16_t _port, endpoint * routing_manager_impl::find_local(client_t _client) { std::unique_lock< std::recursive_mutex > its_lock(endpoint_mutex_); endpoint *its_endpoint(0); - auto found_endpoint = clients_.find(_client); - if (found_endpoint != clients_.end()) { + auto found_endpoint = local_clients_.find(_client); + if (found_endpoint != local_clients_.end()) { its_endpoint = found_endpoint->second.get(); } return its_endpoint; @@ -439,7 +459,7 @@ endpoint * routing_manager_impl::create_local(client_t _client) { shared_from_this(), boost::asio::local::stream_protocol::endpoint(its_path.str()), io_); - clients_[_client] = its_endpoint; + local_clients_[_client] = its_endpoint; its_endpoint->start(); return its_endpoint.get(); } @@ -456,7 +476,7 @@ void routing_manager_impl::remove_local(client_t _client) { std::unique_lock< std::recursive_mutex > its_lock(endpoint_mutex_); endpoint *its_endpoint = find_local(_client); its_endpoint->stop(); - clients_.erase(_client); + local_clients_.erase(_client); } endpoint * routing_manager_impl::find_local(service_t _service, instance_t _instance) { diff --git a/implementation/routing/src/routing_manager_proxy.cpp b/implementation/routing/src/routing_manager_proxy.cpp index febdfbc..7c34feb 100644 --- a/implementation/routing/src/routing_manager_proxy.cpp +++ b/implementation/routing/src/routing_manager_proxy.cpp @@ -405,9 +405,17 @@ void routing_manager_proxy::on_routing_info(const byte_t *_data, uint32_t _size) } } -std::set< std::shared_ptr< service_info > > routing_manager_proxy::get_services() const { - std::set< std::shared_ptr< service_info > > its_services; - return its_services; +bool routing_manager_proxy::is_available(service_t _service, instance_t _instance) const { + auto found_local_service = local_services_.find(_service); + if (found_local_service != local_services_.end()) { + auto found_local_instance = found_local_service->second.find(_instance); + if (found_local_instance != found_local_service->second.end()) { + return true; + } + } + + // TODO: ask routing manager for external services + return false; } void routing_manager_proxy::register_application() { diff --git a/implementation/runtime/src/application_impl.cpp b/implementation/runtime/src/application_impl.cpp index 9440a9d..838627d 100644 --- a/implementation/runtime/src/application_impl.cpp +++ b/implementation/runtime/src/application_impl.cpp @@ -166,7 +166,7 @@ void application_impl::unsubscribe( } bool application_impl::is_available(service_t _service, instance_t _instance) { - return true; // TODO: ask routing manager (proxy) + return routing_->is_available(_service, _instance); } std::shared_ptr< event > application_impl::add_event( diff --git a/implementation/service_discovery/include/service_discovery_fsm.hpp b/implementation/service_discovery/include/service_discovery_fsm.hpp index f5d3109..74eaaf5 100644 --- a/implementation/service_discovery/include/service_discovery_fsm.hpp +++ b/implementation/service_discovery/include/service_discovery_fsm.hpp @@ -49,6 +49,7 @@ struct fsm: uint32_t cyclic_offer_delay_; bool is_up_; + uint8_t run_; }; struct inactive: @@ -123,11 +124,18 @@ public: const std::string & get_name() const; boost::asio::io_service & get_io(); + void start(); + void stop(); + + inline void process(const sc::event_base &_event) { + fsm_->process_event(_event); + } + private: std::string name_; service_discovery *discovery_; - _sd::fsm fsm_; + std::shared_ptr< _sd::fsm > fsm_ ; }; } // namespace sd diff --git a/implementation/service_discovery/include/service_discovery_impl.hpp b/implementation/service_discovery/include/service_discovery_impl.hpp index 918e92b..d63c382 100644 --- a/implementation/service_discovery/include/service_discovery_impl.hpp +++ b/implementation/service_discovery/include/service_discovery_impl.hpp @@ -25,7 +25,8 @@ class service_discovery_host; class service_discovery_impl: public service_discovery, - public endpoint_host { + public endpoint_host, + public std::enable_shared_from_this< service_discovery_impl > { public: service_discovery_impl(service_discovery_host *_host); virtual ~service_discovery_impl(); diff --git a/implementation/service_discovery/src/service_discovery_fsm.cpp b/implementation/service_discovery/src/service_discovery_fsm.cpp index c89af28..6694c44 100644 --- a/implementation/service_discovery/src/service_discovery_fsm.cpp +++ b/implementation/service_discovery/src/service_discovery_fsm.cpp @@ -38,7 +38,8 @@ void fsm::timer_expired(const boost::system::error_code &_error) { // State "Inactive" /////////////////////////////////////////////////////////////////////////////// inactive::inactive(my_context context): sc::state< inactive, fsm >(context) { - VSOMEIP_DEBUG << "sd::inactive"; + VSOMEIP_DEBUG << "sd<" << outermost_context().fsm_->get_name() << ">::inactive"; + outermost_context().run_ = 0; } sc::result inactive::react(const ev_none &_event) { @@ -62,10 +63,11 @@ sc::result inactive::react(const ev_status_change &_event) { // State "Active" /////////////////////////////////////////////////////////////////////////////// active::active(my_context _context): sc::state< active, fsm, initial >(_context) { - VSOMEIP_DEBUG << "sd::active"; + VSOMEIP_DEBUG << "sd<" << outermost_context().fsm_->get_name() << ">::active"; } active::~active() { + outermost_context().stop_timer(); } sc::result active::react(const ev_status_change &_event) { @@ -80,7 +82,7 @@ sc::result active::react(const ev_status_change &_event) { // State "Active.Initial" /////////////////////////////////////////////////////////////////////////////// initial::initial(my_context _context): sc::state< initial, active >(_context) { - VSOMEIP_DEBUG << "sd::inactive.initial"; + VSOMEIP_DEBUG << "sd<" << outermost_context().fsm_->get_name() << ">::active.initial"; outermost_context().start_timer(outermost_context().initial_delay_); } @@ -92,11 +94,17 @@ sc::result initial::react(const ev_timeout &_event) { // State "Active.Repeat" /////////////////////////////////////////////////////////////////////////////// repeat::repeat(my_context _context): sc::state< repeat, active >(_context) { - VSOMEIP_DEBUG << "sd::inactive.repeat"; + VSOMEIP_DEBUG << "sd<" << outermost_context().fsm_->get_name() << ">::active.repeat"; + uint32_t its_timeout = (outermost_context().repetition_base_delay_ << outermost_context().run_); + outermost_context().run_ ++; + outermost_context().start_timer(its_timeout); } sc::result repeat::react(const ev_timeout &_event) { - return discard_event(); + if (outermost_context().run_ < outermost_context().repetition_max_) + return transit< repeat >(); + + return transit< announce >(); } sc::result repeat::react(const ev_find_service &_event) { @@ -107,11 +115,12 @@ sc::result repeat::react(const ev_find_service &_event) { // State "Active.Announce" /////////////////////////////////////////////////////////////////////////////// announce::announce(my_context _context): sc::state< announce, active >(_context) { - VSOMEIP_DEBUG << "sd::inactive.announce"; + VSOMEIP_DEBUG << "sd<" << outermost_context().fsm_->get_name() << ">::active.announce"; + outermost_context().start_timer(outermost_context().cyclic_offer_delay_); } sc::result announce::react(const ev_timeout &_event) { - return discard_event(); + return transit< announce >(); } sc::result announce::react(const ev_find_service &_event) { @@ -125,7 +134,7 @@ sc::result announce::react(const ev_find_service &_event) { /////////////////////////////////////////////////////////////////////////////// service_discovery_fsm::service_discovery_fsm( const std::string &_name, service_discovery *_discovery) - : name_(_name), discovery_(_discovery), fsm_(this) { + : name_(_name), discovery_(_discovery), fsm_(std::make_shared< _sd::fsm >(this)) { std::shared_ptr< configuration > its_configuration = discovery_->get_configuration(); @@ -135,21 +144,21 @@ service_discovery_fsm::service_discovery_fsm( its_configuration->get_min_initial_delay(name_), its_configuration->get_max_initial_delay(name_) ); - fsm_.initial_delay_ = its_distribution(its_generator); + fsm_->initial_delay_ = its_distribution(its_generator); - fsm_.repetition_base_delay_ + fsm_->repetition_base_delay_ = its_configuration->get_repetition_base_delay(name_); - fsm_.repetition_max_ + fsm_->repetition_max_ = its_configuration->get_repetition_max(name_); - fsm_.cyclic_offer_delay_ + fsm_->cyclic_offer_delay_ = its_configuration->get_cyclic_offer_delay(name_); VSOMEIP_INFO << "SD configuration [" - << fsm_.initial_delay_ << ":" - << fsm_.repetition_base_delay_ << ":" - << (int)fsm_.repetition_max_ << ":" - << fsm_.cyclic_offer_delay_ << "]"; + << fsm_->initial_delay_ << ":" + << fsm_->repetition_base_delay_ << ":" + << (int)fsm_->repetition_max_ << ":" + << fsm_->cyclic_offer_delay_ << "]"; } const std::string & service_discovery_fsm::get_name() const { @@ -160,5 +169,12 @@ boost::asio::io_service & service_discovery_fsm::get_io() { return discovery_->get_io(); } +void service_discovery_fsm::start() { + fsm_->initiate(); +} + +void service_discovery_fsm::stop() { +} + } // namespace sd } // namespace vsomeip diff --git a/implementation/service_discovery/src/service_discovery_impl.cpp b/implementation/service_discovery/src/service_discovery_impl.cpp index d3cef62..9675943 100644 --- a/implementation/service_discovery/src/service_discovery_impl.cpp +++ b/implementation/service_discovery/src/service_discovery_impl.cpp @@ -10,21 +10,22 @@ #include "../include/service_discovery_fsm.hpp" #include "../include/service_discovery_host.hpp" #include "../include/service_discovery_impl.hpp" +#include "../../endpoints/include/tcp_server_endpoint_impl.hpp" +#include "../../endpoints/include/udp_server_endpoint_impl.hpp" #include "../../routing/include/servicegroup.hpp" namespace vsomeip { namespace sd { -service_discovery_impl::service_discovery_impl(service_discovery_host *_host) - : host_(_host), - io_(_host->get_io()), - default_(std::make_shared< service_discovery_fsm >("default", this)) { +service_discovery_impl::service_discovery_impl(service_discovery_host *_host) : + host_(_host), io_(_host->get_io()), default_( + std::make_shared < service_discovery_fsm > ("default", this)) { } service_discovery_impl::~service_discovery_impl() { } -std::shared_ptr< configuration > service_discovery_impl::get_configuration() const { +std::shared_ptr<configuration> service_discovery_impl::get_configuration() const { return host_->get_configuration(); } @@ -33,45 +34,83 @@ boost::asio::io_service & service_discovery_impl::get_io() { } void service_discovery_impl::init() { - std::shared_ptr< configuration > its_configuration = host_->get_configuration(); + std::shared_ptr<configuration> its_configuration = + host_->get_configuration(); if (its_configuration) { - std::set< std::string > its_servicegroups = its_configuration->get_servicegroups(); + std::set < std::string > its_servicegroups = + its_configuration->get_servicegroups(); for (auto its_group : its_servicegroups) { - if (its_group != "default") { - additional_[its_group] = std::make_shared< service_discovery_fsm >(its_group, this); + if (its_group != "default" + && its_configuration->is_local_servicegroup(its_group)) { + additional_[its_group] = std::make_shared + < service_discovery_fsm > (its_group, this); } } } else { VSOMEIP_ERROR << "SD: no configuration found!"; } + + // SD endpoint + boost::asio::ip::address its_address = its_configuration->get_address(); + uint16_t its_port = its_configuration->get_service_discovery_port(); + if (its_configuration->get_service_discovery_protocol() == "tcp") { + endpoint_ = std::make_shared< tcp_server_endpoint_impl >( + shared_from_this(), + boost::asio::ip::tcp::endpoint(its_address, its_port), + io_); + } else { + endpoint_ = std::make_shared< udp_server_endpoint_impl >( + shared_from_this(), + boost::asio::ip::udp::endpoint(its_address, its_port), + io_); + } } void service_discovery_impl::start() { + endpoint_->start(); + default_->start(); + for (auto &its_group : additional_) { + its_group.second->start(); + } + + default_->process(ev_none()); + for (auto &its_group : additional_) { + its_group.second->process(ev_none()); + } } void service_discovery_impl::stop() { } -void service_discovery_impl::offer_service(service_t _service, instance_t _instance) { - VSOMEIP_DEBUG << "sdi::offer_service [" << std::hex << _service << "." << _instance << "]"; +void service_discovery_impl::offer_service(service_t _service, + instance_t _instance) { + VSOMEIP_DEBUG << "sdi::offer_service [" << std::hex << _service << "." + << _instance << "]"; } -void service_discovery_impl::stop_offer_service(service_t _service, instance_t _instance) { - VSOMEIP_DEBUG << "sdi::stop_offer_service [" << std::hex << _service << "." << _instance << "]"; +void service_discovery_impl::stop_offer_service(service_t _service, + instance_t _instance) { + VSOMEIP_DEBUG << "sdi::stop_offer_service [" << std::hex << _service << "." + << _instance << "]"; } -void service_discovery_impl::request_service(service_t _service, instance_t _instance, - major_version_t _major, minor_version_t _minor, ttl_t _ttl) { - VSOMEIP_DEBUG << "sdi::request_service [" << std::hex << _service << "." << _instance << "]"; +void service_discovery_impl::request_service(service_t _service, + instance_t _instance, major_version_t _major, minor_version_t _minor, + ttl_t _ttl) { + VSOMEIP_DEBUG << "sdi::request_service [" << std::hex << _service << "." + << _instance << "]"; } -void service_discovery_impl::release_service(service_t _service, instance_t _instance) { - VSOMEIP_DEBUG << "sdi::release_service [" << std::hex << _service << "." << _instance << "]"; +void service_discovery_impl::release_service(service_t _service, + instance_t _instance) { + VSOMEIP_DEBUG << "sdi::release_service [" << std::hex << _service << "." + << _instance << "]"; } // Interface endpoint_host -void service_discovery_impl::on_message(const byte_t *_data, length_t _length, endpoint *_receiver) { +void service_discovery_impl::on_message(const byte_t *_data, length_t _length, + endpoint *_receiver) { VSOMEIP_DEBUG << "sdi::on_message"; } diff --git a/interface/vsomeip/configuration.hpp b/interface/vsomeip/configuration.hpp index d165d69..10f3459 100644 --- a/interface/vsomeip/configuration.hpp +++ b/interface/vsomeip/configuration.hpp @@ -45,6 +45,8 @@ public: virtual std::string get_address(service_t _service, instance_t _instance) const = 0; virtual std::set< std::string > get_servicegroups() const = 0; + + virtual bool is_local_servicegroup(const std::string &_name) const = 0; virtual uint32_t get_min_initial_delay(const std::string &_name) const = 0; virtual uint32_t get_max_initial_delay(const std::string &_name) const = 0; virtual uint32_t get_repetition_base_delay(const std::string &_name) const = 0; |