diff options
29 files changed, 451 insertions, 235 deletions
diff --git a/config/vsomeip-tcp-client.xml b/config/vsomeip-tcp-client.xml index 0126e1d..af93600 100644 --- a/config/vsomeip-tcp-client.xml +++ b/config/vsomeip-tcp-client.xml @@ -1,8 +1,8 @@ <!-- vsomeip test configuration file --> <someip> - <address>192.168.56.101</address> + <address>192.168.56.102</address> <logging> - <level>trace</level> + <level>debug</level> <console>true</console> <file> <enable>false</enable> diff --git a/config/vsomeip-tcp-service.xml b/config/vsomeip-tcp-service.xml index 87541ac..37751c8 100644 --- a/config/vsomeip-tcp-service.xml +++ b/config/vsomeip-tcp-service.xml @@ -1,8 +1,8 @@ <!-- vsomeip test configuration file --> <someip> - <address>192.168.56.102</address> + <address>192.168.56.101</address> <logging> - <level>trace</level> + <level>debug</level> <console>true</console> <file> <enable>false</enable> diff --git a/examples/service-sample.cpp b/examples/service-sample.cpp index 43b1b8a..13f134b 100644 --- a/examples/service-sample.cpp +++ b/examples/service-sample.cpp @@ -4,8 +4,11 @@ // 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 <vsomeip/vsomeip.hpp> @@ -17,10 +20,13 @@ public: service_sample(bool _use_tcp) : app_(vsomeip::runtime::get()->create_application()), is_registered_(false), - use_tcp_(_use_tcp) { + use_tcp_(_use_tcp), + offer_thread_(std::bind(&service_sample::run, this)) { } void init() { + std::lock_guard< std::mutex > its_lock(mutex_); + app_->init(); app_->register_message_handler( SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_METHOD_ID, @@ -31,6 +37,9 @@ public: app_->register_event_handler( std::bind(&service_sample::on_event, this, std::placeholders::_1)); + + blocked_ = true; + condition_.notify_one(); } void start() { @@ -41,6 +50,10 @@ public: app_->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID); } + void stop_offer() { + app_->stop_offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID); + } + void on_event(vsomeip::event_type_e _event) { VSOMEIP_INFO << "Application " << app_->get_name() << " is " @@ -49,7 +62,6 @@ public: if (_event == vsomeip::event_type_e::REGISTERED) { if (!is_registered_) { is_registered_= true; - offer(); } } else { is_registered_ = false; @@ -75,13 +87,29 @@ public: app_->send(its_response, true, use_tcp_); } + void run() { + std::unique_lock< std::mutex > its_lock(mutex_); + while (!blocked_) condition_.wait(its_lock); + + bool is_offer(true); + while (true) { + if (is_offer) offer(); + else stop_offer(); + std::this_thread::sleep_for(std::chrono::milliseconds(10000)); + is_offer = !is_offer; + } + } + private: std::shared_ptr< vsomeip::application > app_; bool is_registered_; bool use_tcp_; + std::thread offer_thread_; + std::mutex mutex_; + std::condition_variable condition_; + bool blocked_; }; - int main(int argc, char **argv) { bool use_tcp = false; diff --git a/implementation/endpoints/include/endpoint.hpp b/implementation/endpoints/include/endpoint.hpp index ecfaccf..f0007d1 100644 --- a/implementation/endpoints/include/endpoint.hpp +++ b/implementation/endpoints/include/endpoint.hpp @@ -29,8 +29,8 @@ public: virtual void join(const std::string &_multicast_address) = 0;
virtual void leave(const std::string &_multicast_address) = 0;
- virtual bool is_v4() const = 0;
- virtual bool get_address(std::vector< byte_t > &_address) const = 0;
+ virtual bool get_address(ipv4_address_t &_address) const = 0;
+ virtual bool get_address(ipv6_address_t &_address) const = 0;
virtual unsigned short get_port() const = 0;
virtual bool is_udp() const = 0;
};
diff --git a/implementation/endpoints/include/endpoint_impl.hpp b/implementation/endpoints/include/endpoint_impl.hpp index 5fa054c..61d89bb 100644 --- a/implementation/endpoints/include/endpoint_impl.hpp +++ b/implementation/endpoints/include/endpoint_impl.hpp @@ -35,8 +35,8 @@ public: // Dummy implementations as we only need these for server endpoints
// TODO: redesign to avoid dummy implementations
- bool is_v4() const;
- bool get_address(std::vector< byte_t > &_address) const;
+ bool get_address(ipv4_address_t &_address) const;
+ bool get_address(ipv6_address_t &_address) const;
unsigned short get_port() const;
bool is_udp() const;
diff --git a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp index 923189e..5085bbf 100644 --- a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp @@ -39,8 +39,8 @@ public: void join(const std::string &);
void leave(const std::string &);
- bool is_v4() const;
- bool get_address(std::vector< byte_t > &_address) const;
+ bool get_address(ipv4_address_t &_address) const;
+ bool get_address(ipv6_address_t &_address) const;
unsigned short get_port() const;
bool is_udp() const;
diff --git a/implementation/endpoints/include/udp_server_endpoint_impl.hpp b/implementation/endpoints/include/udp_server_endpoint_impl.hpp index ba37459..4b8f3aa 100644 --- a/implementation/endpoints/include/udp_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/udp_server_endpoint_impl.hpp @@ -45,8 +45,8 @@ public: void join(const std::string &_multicast_address);
void leave(const std::string &_multicast_address);
- bool is_v4() const;
- bool get_address(std::vector< byte_t > &_address) const;
+ bool get_address(ipv4_address_t &_address) const;
+ bool get_address(ipv6_address_t &_address) const;
unsigned short get_port() const;
bool is_udp() const;
diff --git a/implementation/endpoints/src/endpoint_impl.cpp b/implementation/endpoints/src/endpoint_impl.cpp index d386b3d..a1e2e21 100644 --- a/implementation/endpoints/src/endpoint_impl.cpp +++ b/implementation/endpoints/src/endpoint_impl.cpp @@ -115,12 +115,12 @@ bool endpoint_impl< MaxBufferSize >::resync_on_magic_cookie(message_buffer_t &_b }
template < int MaxBufferSize >
-bool endpoint_impl< MaxBufferSize >::is_v4() const {
+bool endpoint_impl< MaxBufferSize >::get_address(ipv4_address_t &_address) const {
return false;
}
template < int MaxBufferSize >
-bool endpoint_impl< MaxBufferSize >::get_address(std::vector< byte_t > &_address) const {
+bool endpoint_impl< MaxBufferSize >::get_address(ipv6_address_t &_address) const {
return false;
}
diff --git a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp index 4629fd9..f865bf7 100644 --- a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp @@ -83,20 +83,22 @@ void tcp_server_endpoint_impl::join(const std::string &) { void tcp_server_endpoint_impl::leave(const std::string &) {
}
-bool tcp_server_endpoint_impl::is_v4() const {
- return acceptor_.local_endpoint().address().is_v4();
+bool tcp_server_endpoint_impl::get_address(ipv4_address_t &_address) const {
+ boost::asio::ip::address its_address = acceptor_.local_endpoint().address();
+ if (its_address.is_v4()) {
+ _address = its_address.to_v4().to_bytes();
+ } else {
+ return false;
+ }
+ return true;
}
-bool tcp_server_endpoint_impl::get_address(std::vector< byte_t > &_address) const {
+bool tcp_server_endpoint_impl::get_address(ipv6_address_t &_address) const {
boost::asio::ip::address its_address = acceptor_.local_endpoint().address();
- if (its_address.is_v4()) {
- boost::asio::ip::address_v4 its_address_v4 = its_address.to_v4();
- boost::asio::ip::address_v4::bytes_type its_bytes = its_address_v4.to_bytes();
- _address.assign(its_bytes.data(), its_bytes.data() + sizeof(its_bytes));
+ if (its_address.is_v6()) {
+ _address = its_address.to_v6().to_bytes();
} else {
- boost::asio::ip::address_v6 its_address_v6 = its_address.to_v6();
- boost::asio::ip::address_v6::bytes_type its_bytes = its_address_v6.to_bytes();
- _address.assign(its_bytes.data(), its_bytes.data() + sizeof(its_bytes));
+ return false;
}
return true;
}
diff --git a/implementation/endpoints/src/udp_server_endpoint_impl.cpp b/implementation/endpoints/src/udp_server_endpoint_impl.cpp index b47b4c5..53df320 100644 --- a/implementation/endpoints/src/udp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/udp_server_endpoint_impl.cpp @@ -62,7 +62,7 @@ void udp_server_endpoint_impl::restart() { }
void udp_server_endpoint_impl::send_queued(endpoint_type _target, message_buffer_ptr_t _buffer) {
-#if 1
+#if 0
std::stringstream msg;
msg << "usei::sq(" << _target.address().to_string() << ":" << _target.port() << "): ";
for (std::size_t i = 0; i < _buffer->size(); ++i)
@@ -122,20 +122,22 @@ void udp_server_endpoint_impl::leave(const std::string &_multicast_address) { }
}
-bool udp_server_endpoint_impl::is_v4() const {
- return socket_.local_endpoint().address().is_v4();
+bool udp_server_endpoint_impl::get_address(ipv4_address_t &_address) const {
+ boost::asio::ip::address its_address = socket_.local_endpoint().address();
+ if (its_address.is_v4()) {
+ _address = its_address.to_v4().to_bytes();
+ } else {
+ return false;
+ }
+ return true;
}
-bool udp_server_endpoint_impl::get_address(std::vector< byte_t > &_address) const {
+bool udp_server_endpoint_impl::get_address(ipv6_address_t &_address) const {
boost::asio::ip::address its_address = socket_.local_endpoint().address();
- if (its_address.is_v4()) {
- boost::asio::ip::address_v4 its_address_v4 = its_address.to_v4();
- boost::asio::ip::address_v4::bytes_type its_bytes = its_address_v4.to_bytes();
- _address.assign(its_bytes.data(), its_bytes.data() + sizeof(its_bytes));
+ if (its_address.is_v6()) {
+ _address = its_address.to_v6().to_bytes();
} else {
- boost::asio::ip::address_v6 its_address_v6 = its_address.to_v6();
- boost::asio::ip::address_v6::bytes_type its_bytes = its_address_v6.to_bytes();
- _address.assign(its_bytes.data(), its_bytes.data() + sizeof(its_bytes));
+ return false;
}
return true;
}
diff --git a/implementation/logging/src/logger_impl.cpp b/implementation/logging/src/logger_impl.cpp index 8dc6ebe..7f38caf 100644 --- a/implementation/logging/src/logger_impl.cpp +++ b/implementation/logging/src/logger_impl.cpp @@ -59,8 +59,9 @@ boost::log::sources::severity_logger< boost::log::trivial::severity_level > & lo void logger_impl::init(const std::string &_path) {
configuration *its_configuration = configuration::get(_path);
-
the_logger__.loglevel_ = its_configuration->get_loglevel();
+ logging::core::get()->set_filter(
+ logging::trivial::severity >= the_logger__.loglevel_);
if (its_configuration->has_console_log())
the_logger__.enable_console();
diff --git a/implementation/routing/include/routing_manager_impl.hpp b/implementation/routing/include/routing_manager_impl.hpp index f6637d6..bcde868 100644 --- a/implementation/routing/include/routing_manager_impl.hpp +++ b/implementation/routing/include/routing_manager_impl.hpp @@ -12,6 +12,7 @@ #include <mutex> #include <vector> +#include <boost/asio/ip/address.hpp> #include <boost/asio/io_service.hpp> #include "routing_manager.hpp" @@ -129,21 +130,25 @@ private: client_t find_local_client(service_t _service, instance_t _instance); instance_t find_instance(service_t _service, endpoint *_endpoint); - serviceinfo * find_service(service_t _service, instance_t _instance); - void create_service(service_t _service, instance_t _instance, - major_version_t _major, minor_version_t _minor, ttl_t _ttl); + std::shared_ptr< serviceinfo > find_service(service_t _service, instance_t _instance); + std::shared_ptr< serviceinfo > create_service(service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor, ttl_t _ttl); std::shared_ptr< endpoint > find_remote_client(service_t _service, instance_t _instance, bool _reliable); - std::shared_ptr< endpoint > create_client_endpoint(const std::string &_address, uint16_t _port, bool _reliable); - std::shared_ptr< endpoint > find_client_endpoint(const std::string &_address, uint16_t _port, bool _reliable); - std::shared_ptr< endpoint > find_or_create_client_endpoint(const std::string &_address, uint16_t _port, bool _reliable); + std::shared_ptr< endpoint > create_client_endpoint(const boost::asio::ip::address &_address, uint16_t _port, bool _reliable); + std::shared_ptr< endpoint > find_client_endpoint(const boost::asio::ip::address &_address, uint16_t _port, bool _reliable); + std::shared_ptr< endpoint > find_or_create_client_endpoint(const boost::asio::ip::address &_address, uint16_t _port, bool _reliable); std::shared_ptr< endpoint > create_server_endpoint(uint16_t _port, bool _reliable); std::shared_ptr< endpoint > find_server_endpoint(uint16_t _port, bool _reliable); std::shared_ptr< endpoint > find_or_create_server_endpoint(uint16_t _port, bool _reliable); void init_routing_info(); + void add_routing_info(service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor, ttl_t _ttl, + const boost::asio::ip::address &_address, uint16_t _port, bool _reliable); + void del_routing_info(service_t _service, instance_t _instance, bool _reliable); private: boost::asio::io_service &io_; @@ -168,7 +173,7 @@ private: std::map< service_t, std::map< endpoint *, instance_t > > service_instances_; // Client endpoints for remote services - std::map< std::string, + std::map< boost::asio::ip::address, std::map< uint16_t, std::map< bool, std::shared_ptr< endpoint > > > > client_endpoints_; std::map< service_t, diff --git a/implementation/routing/include/routing_manager_stub.hpp b/implementation/routing/include/routing_manager_stub.hpp index 134797f..bf51251 100644 --- a/implementation/routing/include/routing_manager_stub.hpp +++ b/implementation/routing/include/routing_manager_stub.hpp @@ -37,6 +37,7 @@ public: void on_message(const byte_t *_data, const length_t _length, endpoint *_receiver); void on_offer_service(client_t _client, service_t _service, instance_t _instance); + void on_stop_offer_service(client_t _client, service_t _service, instance_t _instance); private: void broadcast(std::vector< byte_t > &_command) const; @@ -44,8 +45,6 @@ private: void on_register_application(client_t _client); void on_deregister_application(client_t _client); - void on_stop_offer_service(client_t _client, service_t _service, instance_t _instance); - void broadcast_routing_info(); void send_routing_info(client_t _client); diff --git a/implementation/routing/include/serviceinfo.hpp b/implementation/routing/include/serviceinfo.hpp index 981b7e7..3d34f25 100644 --- a/implementation/routing/include/serviceinfo.hpp +++ b/implementation/routing/include/serviceinfo.hpp @@ -15,34 +15,37 @@ namespace vsomeip { class endpoint; +class servicegroup; class serviceinfo { public: serviceinfo(major_version_t _major, minor_version_t _minor, ttl_t _ttl); ~serviceinfo(); + servicegroup * get_group() const; + void set_group(servicegroup *_group); + major_version_t get_major() const; minor_version_t get_minor() const; ttl_t get_ttl() const; void set_ttl(ttl_t _ttl); - std::shared_ptr< endpoint > & get_reliable_endpoint(); - void set_reliable_endpoint(std::shared_ptr< endpoint > &_endpoint); - - std::shared_ptr< endpoint > & get_unreliable_endpoint(); - void set_unreliable_endpoint(std::shared_ptr< endpoint > &_endpoint); + std::shared_ptr< endpoint > & get_endpoint(bool _reliable); + void set_endpoint(std::shared_ptr< endpoint > &_endpoint, bool _reliable); void add_client(client_t _client); void remove_client(client_t _client); private: + servicegroup *group_; + major_version_t major_; minor_version_t minor_; ttl_t ttl_; - std::shared_ptr< endpoint > reliable_endpoint_; - std::shared_ptr< endpoint > unreliable_endpoint_; + std::shared_ptr< endpoint > reliable_; + std::shared_ptr< endpoint > unreliable_; std::set< client_t > requesters_; }; diff --git a/implementation/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp index cb43f6d..26b2b3a 100644 --- a/implementation/routing/src/routing_manager_impl.cpp +++ b/implementation/routing/src/routing_manager_impl.cpp @@ -98,47 +98,38 @@ void routing_manager_impl::stop() { void routing_manager_impl::offer_service(client_t _client, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor, ttl_t _ttl) { -#if 0 - VSOMEIP_DEBUG << "RM: Client [ " << std::hex << _client << "] offers service [" - << std::hex << _service << "." << _instance << "]"; -#endif - // Local route local_services_[_service][_instance] = _client; // Remote route (incoming only) - serviceinfo *its_info = find_service(_service, _instance); + std::shared_ptr< serviceinfo > its_info(find_service(_service, _instance)); if (its_info) { if (its_info->get_major() == _major && its_info->get_minor() == _minor) { + VSOMEIP_DEBUG << "Setting TTL=" << std::dec << _ttl; its_info->set_ttl(_ttl); } else { host_->on_error(error_code_e::SERVICE_PROPERTY_MISMATCH); } } else { - create_service(_service, _instance, _major, _minor, _ttl); + (void)create_service(_service, _instance, _major, _minor, _ttl); } host_->on_availability(_service, _instance, true); - - if (discovery_) - discovery_->offer_service(_service, _instance); } void routing_manager_impl::stop_offer_service(client_t its_client, service_t _service, instance_t _instance) { - auto found_service = services_.find(_service); - if (found_service != services_.end()) { - auto found_instance = found_service->second.find(_instance); - if (found_instance != found_service->second.end()) { - found_service->second.erase(found_instance); - if (0 == found_service->second.size()) - services_.erase(found_service); + if (discovery_) { + auto found_service = services_.find(_service); + if (found_service != services_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + found_instance->second->set_ttl(0); + } } + } else { + del_routing_info(_service, _instance, false); + del_routing_info(_service, _instance, true); } - - host_->on_availability(_service, _instance, false); - - if (discovery_) - discovery_->stop_offer_service(_service, _instance); } void routing_manager_impl::publish_eventgroup(client_t its_client, @@ -176,8 +167,8 @@ void routing_manager_impl::request_service(client_t _client, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor, ttl_t _ttl) { - serviceinfo *its_info = find_service(_service, _instance); - if (nullptr != its_info) { + std::shared_ptr< serviceinfo > its_info(find_service(_service, _instance)); + if (its_info) { if ((_major > its_info->get_major()) || (_major == its_info->get_major() && _minor > its_info->get_minor()) || (_ttl > its_info->get_ttl())) { @@ -193,8 +184,8 @@ void routing_manager_impl::request_service(client_t _client, void routing_manager_impl::release_service(client_t _client, service_t _service, instance_t _instance) { - serviceinfo *its_info = find_service(_service, _instance); - if (nullptr != its_info) { + std::shared_ptr< serviceinfo > its_info(find_service(_service, _instance)); + if (its_info) { its_info->remove_client(_client); } else { if (discovery_) @@ -259,14 +250,9 @@ void routing_manager_impl::send(client_t _client, VSOMEIP_ERROR << "Routing error. Client from remote service could not be found!"; } } else { - serviceinfo *its_info = find_service(its_service, _instance); + std::shared_ptr< serviceinfo > its_info(find_service(its_service, _instance)); if (its_info) { - if (_reliable) { - its_target = its_info->get_reliable_endpoint(); - } else { - its_target = its_info->get_unreliable_endpoint(); - } - + its_target = its_info->get_endpoint(_reliable); if (its_target) { its_target->send(_data, _size, _flush); } else { @@ -287,7 +273,7 @@ void routing_manager_impl::set(client_t its_client, } void routing_manager_impl::on_message(const byte_t *_data, length_t _size, endpoint *_receiver) { -#if 1 +#if 0 std::stringstream msg; msg << "rmi::on_message: "; for (uint32_t i = 0; i < _size; ++i) @@ -406,13 +392,9 @@ void routing_manager_impl::create_service_discovery_endpoint( if (!its_service_endpoint) { its_service_endpoint = create_server_endpoint(_port, is_reliable); - std::shared_ptr< serviceinfo > its_info(std::make_shared< serviceinfo >( - any_major, any_minor, any_ttl)); - if (is_reliable) { - its_info->set_reliable_endpoint(its_service_endpoint); - } else { - its_info->set_unreliable_endpoint(its_service_endpoint); - } + std::shared_ptr< serviceinfo > its_info( + std::make_shared< serviceinfo >(any_major, any_minor, any_ttl)); + its_info->set_endpoint(its_service_endpoint, is_reliable); // routing info services_[VSOMEIP_SD_SERVICE][VSOMEIP_SD_INSTANCE] = its_info; @@ -436,32 +418,35 @@ service_map_t routing_manager_impl::get_offered_services(const std::string &_nam /////////////////////////////////////////////////////////////////////////////// // PRIVATE /////////////////////////////////////////////////////////////////////////////// -serviceinfo * routing_manager_impl::find_service( - service_t _service, instance_t _instance) { - serviceinfo *its_info = 0; +std::shared_ptr< serviceinfo > routing_manager_impl::find_service( + service_t _service, instance_t _instance) { + std::shared_ptr< serviceinfo > its_info; auto found_service = services_.find(_service); if (found_service != services_.end()) { auto found_instance = found_service->second.find(_instance); if (found_instance != found_service->second.end()) { - its_info = found_instance->second.get(); + its_info = found_instance->second; } } return its_info; } -void routing_manager_impl::create_service( - service_t _service, instance_t _instance, - major_version_t _major, minor_version_t _minor, ttl_t _ttl) { +std::shared_ptr< serviceinfo > routing_manager_impl::create_service( + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor, ttl_t _ttl) { + std::shared_ptr< serviceinfo > its_info; if (configuration_) { - std::shared_ptr< serviceinfo > its_info(std::make_shared< serviceinfo >(_major, _minor, _ttl)); + its_info = std::make_shared< serviceinfo >(_major, _minor, _ttl); - uint16_t its_reliable_port = configuration_->get_reliable_port(_service, _instance); - uint16_t its_unreliable_port = configuration_->get_unreliable_port(_service, _instance); + uint16_t its_reliable_port + = configuration_->get_reliable_port(_service, _instance); + uint16_t its_unreliable_port + = configuration_->get_unreliable_port(_service, _instance); if (its_reliable_port != illegal_port) { std::shared_ptr< endpoint > its_reliable_endpoint( find_or_create_server_endpoint(its_reliable_port, true)); - its_info->set_reliable_endpoint(its_reliable_endpoint); + its_info->set_endpoint(its_reliable_endpoint, true); // TODO: put this in a method and check whether an assignment already exists! service_instances_[_service][its_reliable_endpoint.get()] = _instance; @@ -470,7 +455,7 @@ void routing_manager_impl::create_service( if (its_unreliable_port != illegal_port) { std::shared_ptr< endpoint > its_unreliable_endpoint( find_or_create_server_endpoint(its_unreliable_port, false)); - its_info->set_unreliable_endpoint(its_unreliable_endpoint); + its_info->set_endpoint(its_unreliable_endpoint, false); service_instances_[_service][its_unreliable_endpoint.get()] = _instance; } @@ -489,27 +474,28 @@ void routing_manager_impl::create_service( } else { host_->on_error(error_code_e::CONFIGURATION_MISSING); } + + return its_info; } std::shared_ptr< endpoint > routing_manager_impl::create_client_endpoint( - const std::string &_address, uint16_t _port, bool _reliable) { + const boost::asio::ip::address &_address, uint16_t _port, bool _reliable) { std::shared_ptr< endpoint > its_endpoint; - try { - boost::asio::ip::address its_address = boost::asio::ip::address::from_string(_address); if (_reliable) { its_endpoint = std::make_shared< tcp_client_endpoint_impl >( shared_from_this(), - boost::asio::ip::tcp::endpoint(its_address, _port), + boost::asio::ip::tcp::endpoint(_address, _port), io_ ); - if (configuration_->has_enabled_magic_cookies(_address, _port)) { + + if (configuration_->has_enabled_magic_cookies(_address.to_string(), _port)) { its_endpoint->enable_magic_cookies(); } } else { its_endpoint = std::make_shared< udp_client_endpoint_impl >( shared_from_this(), - boost::asio::ip::udp::endpoint(its_address, _port), + boost::asio::ip::udp::endpoint(_address, _port), io_ ); } @@ -525,7 +511,7 @@ std::shared_ptr< endpoint > routing_manager_impl::create_client_endpoint( } std::shared_ptr< endpoint > routing_manager_impl::find_client_endpoint( - const std::string &_address, uint16_t _port, bool _reliable) { + const boost::asio::ip::address &_address, uint16_t _port, bool _reliable) { std::shared_ptr< endpoint > its_endpoint; auto found_address = client_endpoints_.find(_address); if (found_address != client_endpoints_.end()) { @@ -541,7 +527,7 @@ std::shared_ptr< endpoint > routing_manager_impl::find_client_endpoint( } std::shared_ptr< endpoint > routing_manager_impl::find_or_create_client_endpoint( - const std::string &_address, uint16_t _port, bool _reliable) { + const boost::asio::ip::address &_address, uint16_t _port, bool _reliable) { std::shared_ptr< endpoint > its_endpoint = find_client_endpoint(_address, _port, _reliable); if (0 == its_endpoint) { its_endpoint = create_client_endpoint(_address, _port, _reliable); @@ -691,38 +677,79 @@ std::shared_ptr< endpoint > routing_manager_impl::find_remote_client( return its_endpoint; } +void routing_manager_impl::add_routing_info( + service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor, ttl_t _ttl, + const boost::asio::ip::address &_address, uint16_t _port, bool _reliable) { + std::shared_ptr< serviceinfo > its_info(find_service(_service, _instance)); + if (!its_info) + its_info = create_service(_service, _instance, _major, _minor, _ttl); + + std::shared_ptr< endpoint > its_endpoint(create_client_endpoint(_address, _port, _reliable)); + its_info->set_endpoint(its_endpoint, _reliable); + remote_services_[_service][_instance][_reliable] = its_endpoint; + service_instances_[_service][its_endpoint.get()] = _instance; + services_[_service][_instance] = its_info; + stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance); + host_->on_availability(_service, _instance, true); +} + +void routing_manager_impl::del_routing_info( + service_t _service, instance_t _instance, bool _reliable) { + std::shared_ptr< serviceinfo > its_info(find_service(_service, _instance)); + if (its_info) { + std::shared_ptr< endpoint > its_empty_endpoint; + host_->on_availability(_service, _instance, false); + stub_->on_stop_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance); + + std::shared_ptr< endpoint > its_endpoint = its_info->get_endpoint(_reliable); + if (its_endpoint) { + if (1 >= service_instances_[_service].size()) { + service_instances_.erase(_service); + } else { + service_instances_[_service].erase(its_endpoint.get()); + } + + remote_services_[_service][_instance].erase(_reliable); + auto found_endpoint = remote_services_[_service][_instance].find(!_reliable); + if (found_endpoint == remote_services_[_service][_instance].end()) { + remote_services_[_service].erase(_instance); + } + if (1 >= remote_services_[_service].size()) { + remote_services_.erase(_service); + } + } + + if (!its_info->get_endpoint(!_reliable)) { + its_info->get_group()->remove_service(_service, _instance); + if (1 >= services_[_service].size()) { + services_.erase(_service); + } else { + services_[_service].erase(_instance); + } + } else { + its_info->set_endpoint(its_empty_endpoint, _reliable); + } + } +} + void routing_manager_impl::init_routing_info() { VSOMEIP_INFO << "Service Discovery disabled. Using static routing information."; for (auto i : configuration_->get_remote_services()) { - std::shared_ptr< serviceinfo > its_info(std::make_shared< serviceinfo >( - default_major, default_minor, default_ttl)); - std::string its_address = configuration_->get_address(i.first, i.second); - uint16_t its_reliable_port = configuration_->get_reliable_port(i.first, i.second); - uint16_t its_unreliable_port = configuration_->get_unreliable_port(i.first, i.second); - - if (VSOMEIP_INVALID_PORT != its_reliable_port) { - VSOMEIP_DEBUG << "Routing info: [" << std::hex << i.first << "." << i.second - << "] -> TCP:" << its_address << ":" << std::dec << its_reliable_port; - std::shared_ptr< endpoint > its_endpoint(create_client_endpoint(its_address, its_reliable_port, true)); - remote_services_[i.first][i.second][true] = its_endpoint; - service_instances_[i.first][its_endpoint.get()] = i.second; - its_info->set_reliable_endpoint(its_endpoint); - } - - if (VSOMEIP_INVALID_PORT != its_unreliable_port) { - VSOMEIP_DEBUG << "Routing info: [" << std::hex << i.first << "." << i.second - << "] --> UDP:" << its_address << ":" << std::dec << its_unreliable_port; - std::shared_ptr< endpoint > its_endpoint(create_client_endpoint(its_address, its_unreliable_port, false)); - remote_services_[i.first][i.second][false] = its_endpoint; - service_instances_[i.first][its_endpoint.get()] = i.second; - its_info->set_reliable_endpoint(its_endpoint); + uint16_t its_reliable = configuration_->get_reliable_port(i.first, i.second); + uint16_t its_unreliable = configuration_->get_unreliable_port(i.first, i.second); + + if (VSOMEIP_INVALID_PORT != its_reliable) { + add_routing_info(i.first, i.second, + default_major, default_minor, default_ttl, + boost::asio::ip::address::from_string(its_address), its_reliable, true); } - if (VSOMEIP_INVALID_PORT != its_reliable_port || VSOMEIP_INVALID_PORT != its_unreliable_port) { - services_[i.first][i.second] = its_info; - stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, i.first, i.second); - host_->on_availability(i.first, i.second, true); + if (VSOMEIP_INVALID_PORT != its_unreliable) { + add_routing_info(i.first, i.second, + default_major, default_minor, default_ttl, + boost::asio::ip::address::from_string(its_address), its_reliable, true); } } } diff --git a/implementation/routing/src/servicegroup.cpp b/implementation/routing/src/servicegroup.cpp index d75ba80..ffdcbac 100644 --- a/implementation/routing/src/servicegroup.cpp +++ b/implementation/routing/src/servicegroup.cpp @@ -5,6 +5,7 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include "../include/servicegroup.hpp" +#include "../include/serviceinfo.hpp" namespace vsomeip { @@ -35,6 +36,8 @@ bool servicegroup::add_service( services_[_service][_instance] = _info; } + _info->set_group(this); + return its_result; } diff --git a/implementation/routing/src/serviceinfo.cpp b/implementation/routing/src/serviceinfo.cpp index 69095b5..a991466 100644 --- a/implementation/routing/src/serviceinfo.cpp +++ b/implementation/routing/src/serviceinfo.cpp @@ -9,12 +9,20 @@ namespace vsomeip { serviceinfo::serviceinfo(major_version_t _major, minor_version_t _minor, ttl_t _ttl) - : major_(_major), minor_(_minor), ttl_(_ttl) { + : group_(0), major_(_major), minor_(_minor), ttl_(_ttl) { } serviceinfo::~serviceinfo() { } +servicegroup * serviceinfo::get_group() const { + return group_; +} + +void serviceinfo::set_group(servicegroup *_group) { + group_ = _group; +} + major_version_t serviceinfo::get_major() const { return major_; } @@ -31,20 +39,19 @@ void serviceinfo::set_ttl(ttl_t _ttl) { ttl_ = _ttl; } -std::shared_ptr< endpoint > & serviceinfo::get_reliable_endpoint() { - return reliable_endpoint_; -} - -void serviceinfo::set_reliable_endpoint(std::shared_ptr< endpoint > &_endpoint) { - reliable_endpoint_ = _endpoint; -} +std::shared_ptr< endpoint > & serviceinfo::get_endpoint(bool _reliable) { + if (_reliable) + return reliable_; -std::shared_ptr< endpoint > & serviceinfo::get_unreliable_endpoint() { - return unreliable_endpoint_; + return unreliable_; } -void serviceinfo::set_unreliable_endpoint(std::shared_ptr< endpoint > &_endpoint) { - unreliable_endpoint_ = _endpoint; +void serviceinfo::set_endpoint(std::shared_ptr< endpoint > &_endpoint, bool _reliable) { + if (_reliable) { + reliable_ = _endpoint; + } else { + unreliable_ = _endpoint; + } } void serviceinfo::add_client(client_t _client) { diff --git a/implementation/service_discovery/include/ipv4_option_impl.hpp b/implementation/service_discovery/include/ipv4_option_impl.hpp index f6ec0d2..8184a23 100644 --- a/implementation/service_discovery/include/ipv4_option_impl.hpp +++ b/implementation/service_discovery/include/ipv4_option_impl.hpp @@ -7,8 +7,6 @@ #ifndef VSOMEIP_SD_IPV4_OPTION_IMPL_HPP
#define VSOMEIP_SD_IPV4_OPTION_IMPL_HPP
-#include <vector>
-
#include <vsomeip/primitive_types.hpp>
#include "option_impl.hpp"
@@ -22,8 +20,8 @@ public: virtual ~ipv4_option_impl();
bool operator == (const option_impl &_option) const;
- const std::vector< byte_t > & get_address() const;
- void set_address(const std::vector< byte_t > &_address);
+ const ipv4_address_t & get_address() const;
+ void set_address(const ipv4_address_t &_address);
unsigned short get_port() const;
void set_port(unsigned short _port);
@@ -37,7 +35,7 @@ public: bool deserialize(vsomeip::deserializer *_from);
protected:
- std::vector< byte_t > address_;
+ ipv4_address_t address_;
unsigned short port_;
bool is_udp_;
};
diff --git a/implementation/service_discovery/include/ipv6_option_impl.hpp b/implementation/service_discovery/include/ipv6_option_impl.hpp index 8904c1d..e1aea29 100644 --- a/implementation/service_discovery/include/ipv6_option_impl.hpp +++ b/implementation/service_discovery/include/ipv6_option_impl.hpp @@ -22,8 +22,8 @@ public: virtual ~ipv6_option_impl();
bool operator == (const option_impl &_option) const;
- const std::vector< byte_t > & get_address() const;
- void set_address(const std::vector< byte_t > &_address);
+ const ipv6_address_t & get_address() const;
+ void set_address(const ipv6_address_t &_address);
unsigned short get_port() const;
void set_port(unsigned short _port);
@@ -37,7 +37,7 @@ public: bool deserialize(vsomeip::deserializer *_from);
protected:
- std::vector< byte_t > address_;
+ ipv6_address_t address_;
unsigned short port_;
bool is_udp_;
};
diff --git a/implementation/service_discovery/include/message_impl.hpp b/implementation/service_discovery/include/message_impl.hpp index a0cd30c..788782a 100755 --- a/implementation/service_discovery/include/message_impl.hpp +++ b/implementation/service_discovery/include/message_impl.hpp @@ -54,8 +54,8 @@ public: std::shared_ptr< load_balancing_option_impl > create_load_balancing_option();
std::shared_ptr< protection_option_impl > create_protection_option();
- const std::vector< std::shared_ptr< entry_impl > > get_entries() const;
- const std::vector< std::shared_ptr< option_impl > > get_options() const;
+ const std::vector< std::shared_ptr< entry_impl > > & get_entries() const;
+ const std::vector< std::shared_ptr< option_impl > > & get_options() const;
int16_t get_option_index(const std::shared_ptr< option_impl > &_option) const;
diff --git a/implementation/service_discovery/include/service_discovery.hpp b/implementation/service_discovery/include/service_discovery.hpp index 4fd2a30..b488493 100644 --- a/implementation/service_discovery/include/service_discovery.hpp +++ b/implementation/service_discovery/include/service_discovery.hpp @@ -28,9 +28,6 @@ public: virtual void start() = 0; virtual void stop() = 0; - virtual void offer_service(service_t _service, instance_t _instance) = 0; - virtual void stop_offer_service(service_t _service, instance_t _instance) = 0; - virtual void request_service(service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor, ttl_t _ttl) = 0; virtual void release_service(service_t _service, instance_t _instance) = 0; diff --git a/implementation/service_discovery/include/service_discovery_host.hpp b/implementation/service_discovery/include/service_discovery_host.hpp index 8a9d486..ccd0801 100644 --- a/implementation/service_discovery/include/service_discovery_host.hpp +++ b/implementation/service_discovery/include/service_discovery_host.hpp @@ -10,6 +10,7 @@ #include <map> #include <memory> +#include <boost/asio/ip/address.hpp> #include <boost/asio/io_service.hpp> #include "../../routing/include/routing_types.hpp" @@ -25,14 +26,24 @@ public: virtual ~service_discovery_host() {}; virtual boost::asio::io_service & get_io() = 0; - virtual std::shared_ptr< configuration > get_configuration() const = 0; + virtual std::shared_ptr<configuration> get_configuration() const = 0; - virtual void create_service_discovery_endpoint( - const std::string &_address, uint16_t _port, const std::string &_protocol) = 0; + virtual void create_service_discovery_endpoint(const std::string &_address, + uint16_t _port, const std::string &_protocol) = 0; - virtual service_map_t get_offered_services(const std::string &_name) const = 0; + virtual service_map_t get_offered_services( + const std::string &_name) const = 0; - virtual void send(client_t _client, std::shared_ptr< message > _message, bool _flush, bool _reliable) = 0; + virtual void send(client_t _client, std::shared_ptr<message> _message, + bool _flush, bool _reliable) = 0; + + virtual void add_routing_info(service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor, ttl_t _ttl, + const boost::asio::ip::address &_address, uint16_t _port, + bool _reliable) = 0; + + virtual void del_routing_info(service_t _service, instance_t _instance, + bool _reliable) = 0; }; } // namespace sd diff --git a/implementation/service_discovery/include/service_discovery_impl.hpp b/implementation/service_discovery/include/service_discovery_impl.hpp index 7868b5c..3fdae51 100644 --- a/implementation/service_discovery/include/service_discovery_impl.hpp +++ b/implementation/service_discovery/include/service_discovery_impl.hpp @@ -20,6 +20,9 @@ class endpoint; namespace sd { +class eventgroupentry_impl; +class option_impl; +class serviceentry_impl; class service_discovery_fsm; class service_discovery_host; @@ -37,9 +40,6 @@ public: void start(); void stop(); - void offer_service(service_t _service, instance_t _instance); - void stop_offer_service(service_t _service, instance_t _instance); - void request_service(service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor, ttl_t _ttl); void release_service(service_t _service, instance_t _instance); @@ -49,9 +49,17 @@ public: void on_message(const byte_t *_data, length_t _length); private: + void insert_service_option(std::shared_ptr< message_impl > &_message, + std::shared_ptr< serviceentry_impl > &_entry, + std::shared_ptr< endpoint > _endpoint); void insert_service_entries(std::shared_ptr< message_impl > &_message, service_map_t &_services, bool _is_offer); + void process_serviceentry(std::shared_ptr< serviceentry_impl > &_entry, + const std::vector< std::shared_ptr< option_impl > > &_options); + void process_eventgroupentry(std::shared_ptr< eventgroupentry_impl > &_entry, + const std::vector< std::shared_ptr< option_impl > > &_options); + private: boost::asio::io_service &io_; service_discovery_host *host_; diff --git a/implementation/service_discovery/src/ipv4_option_impl.cpp b/implementation/service_discovery/src/ipv4_option_impl.cpp index 2b68a07..33dd864 100644 --- a/implementation/service_discovery/src/ipv4_option_impl.cpp +++ b/implementation/service_discovery/src/ipv4_option_impl.cpp @@ -30,11 +30,11 @@ bool ipv4_option_impl::operator ==(const option_impl &_other) const { return true;
}
-const std::vector< byte_t > & ipv4_option_impl::get_address() const {
+const ipv4_address_t & ipv4_option_impl::get_address() const {
return address_;
}
-void ipv4_option_impl::set_address(const std::vector< byte_t > &_address) {
+void ipv4_option_impl::set_address(const ipv4_address_t &_address) {
address_ = _address;
}
@@ -70,8 +70,7 @@ bool ipv4_option_impl::serialize(vsomeip::serializer *_to) const { bool ipv4_option_impl::deserialize(vsomeip::deserializer *_from) {
bool is_successful = option_impl::deserialize(_from);
uint8_t its_reserved;
- address_.resize(4);
- _from->deserialize(address_);
+ _from->deserialize(address_.data(), 4);
_from->deserialize(its_reserved);
_from->deserialize(its_reserved);
is_udp_ = (protocol::udp == its_reserved);
diff --git a/implementation/service_discovery/src/ipv6_option_impl.cpp b/implementation/service_discovery/src/ipv6_option_impl.cpp index 654de29..26a711d 100755 --- a/implementation/service_discovery/src/ipv6_option_impl.cpp +++ b/implementation/service_discovery/src/ipv6_option_impl.cpp @@ -32,11 +32,11 @@ bool ipv6_option_impl::operator ==(const option_impl &_other) const { return true; // TODO:
}
-const std::vector< byte_t > & ipv6_option_impl::get_address() const {
+const ipv6_address_t & ipv6_option_impl::get_address() const {
return address_;
}
-void ipv6_option_impl::set_address(const std::vector< byte_t > &_address) {
+void ipv6_option_impl::set_address(const ipv6_address_t &_address) {
address_ = _address;
}
@@ -68,7 +68,7 @@ bool ipv6_option_impl::serialize(vsomeip::serializer *_to) const { bool ipv6_option_impl::deserialize(vsomeip::deserializer *_from) {
bool is_successful = option_impl::deserialize(_from);
uint8_t its_reserved;
- _from->deserialize(&address_[0], 16);
+ _from->deserialize(address_.data(), 16);
_from->deserialize(its_reserved);
_from->deserialize(its_reserved);
is_udp_ = (protocol::udp == its_reserved);
diff --git a/implementation/service_discovery/src/message_impl.cpp b/implementation/service_discovery/src/message_impl.cpp index 63af016..31da16b 100755 --- a/implementation/service_discovery/src/message_impl.cpp +++ b/implementation/service_discovery/src/message_impl.cpp @@ -131,11 +131,11 @@ std::shared_ptr< protection_option_impl > message_impl::create_protection_option return its_option;
}
-const std::vector< std::shared_ptr< entry_impl > > message_impl::get_entries() const {
+const std::vector< std::shared_ptr< entry_impl > > & message_impl::get_entries() const {
return entries_;
}
-const std::vector< std::shared_ptr< option_impl > > message_impl::get_options() const {
+const std::vector< std::shared_ptr< option_impl > > & message_impl::get_options() const {
return options_;
}
diff --git a/implementation/service_discovery/src/service_discovery_fsm.cpp b/implementation/service_discovery/src/service_discovery_fsm.cpp index 60a38a7..df0f070 100644 --- a/implementation/service_discovery/src/service_discovery_fsm.cpp +++ b/implementation/service_discovery/src/service_discovery_fsm.cpp @@ -41,7 +41,7 @@ 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<" << outermost_context().fsm_->get_name() << ">::inactive"; + VSOMEIP_TRACE << "sd<" << outermost_context().fsm_->get_name() << ">::inactive"; outermost_context().run_ = 0; } @@ -66,7 +66,7 @@ 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<" << outermost_context().fsm_->get_name() << ">::active"; + VSOMEIP_TRACE << "sd<" << outermost_context().fsm_->get_name() << ">::active"; } active::~active() { @@ -85,7 +85,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<" << outermost_context().fsm_->get_name() << ">::active.initial"; + VSOMEIP_TRACE << "sd<" << outermost_context().fsm_->get_name() << ">::active.initial"; outermost_context().start_timer(outermost_context().initial_delay_); } @@ -97,7 +97,7 @@ sc::result initial::react(const ev_timeout &_event) { // State "Active.Repeat" /////////////////////////////////////////////////////////////////////////////// repeat::repeat(my_context _context): sc::state< repeat, active >(_context) { - VSOMEIP_DEBUG << "sd<" << outermost_context().fsm_->get_name() << ">::active.repeat"; + VSOMEIP_TRACE << "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().fsm_->send(false); @@ -119,7 +119,7 @@ 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<" << outermost_context().fsm_->get_name() << ">::active.announce"; + VSOMEIP_TRACE << "sd<" << outermost_context().fsm_->get_name() << ">::active.announce"; outermost_context().start_timer(outermost_context().cyclic_offer_delay_); outermost_context().fsm_->send(true); } @@ -147,7 +147,7 @@ service_discovery_fsm::service_discovery_fsm( int32_t its_min_initial_delay = its_configuration->get_min_initial_delay(name_); int32_t its_max_initial_delay = its_configuration->get_max_initial_delay(name_); - VSOMEIP_DEBUG << "Inital delay [" + VSOMEIP_TRACE << "Inital delay [" << its_min_initial_delay << ", " << its_max_initial_delay << "]"; boost::random::mt19937 its_generator; diff --git a/implementation/service_discovery/src/service_discovery_impl.cpp b/implementation/service_discovery/src/service_discovery_impl.cpp index 30f27da..f0b1b19 100644 --- a/implementation/service_discovery/src/service_discovery_impl.cpp +++ b/implementation/service_discovery/src/service_discovery_impl.cpp @@ -10,6 +10,8 @@ #include "../include/constants.hpp" #include "../include/defines.hpp" #include "../include/deserializer.hpp" +#include "../include/enumeration_types.hpp" +#include "../include/eventgroupentry_impl.hpp" #include "../include/ipv4_option_impl.hpp" #include "../include/ipv6_option_impl.hpp" #include "../include/message_impl.hpp" @@ -18,6 +20,7 @@ #include "../include/service_discovery_host.hpp" #include "../include/service_discovery_impl.hpp" #include "../include/serviceentry_impl.hpp" +#include "../../configuration/include/internal.hpp" #include "../../endpoints/include/tcp_server_endpoint_impl.hpp" #include "../../endpoints/include/udp_server_endpoint_impl.hpp" #include "../../routing/include/servicegroup.hpp" @@ -83,18 +86,6 @@ void service_discovery_impl::start() { 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::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) { @@ -123,6 +114,36 @@ void service_discovery_impl::release_service(service_t _service, } } +void service_discovery_impl::insert_service_option( + std::shared_ptr< message_impl > &_message, + std::shared_ptr< serviceentry_impl > &_entry, + std::shared_ptr< endpoint > _endpoint) { + + ipv4_address_t its_address; + if (_endpoint->get_address(its_address)) { + std::shared_ptr< ipv4_option_impl > its_option + = _message->create_ipv4_option(false); + if (its_option) { + its_option->set_address(its_address); + its_option->set_port(_endpoint->get_port()); + its_option->set_udp(_endpoint->is_udp()); + _entry->assign_option(its_option, 1); + } + } else { + ipv6_address_t its_address; + if (_endpoint->get_address(its_address)) { + std::shared_ptr< ipv6_option_impl > its_option + = _message->create_ipv6_option(false); + if (its_option) { + its_option->set_address(its_address); + its_option->set_port(_endpoint->get_port()); + its_option->set_udp(_endpoint->is_udp()); + _entry->assign_option(its_option, 1); + } + } + } +} + void service_discovery_impl::insert_service_entries( std::shared_ptr< message_impl > &_message, service_map_t &_services, bool _is_offer) { @@ -141,37 +162,19 @@ void service_discovery_impl::insert_service_entries( its_entry->set_minor_version(its_info->get_minor()); its_entry->set_ttl(its_info->get_ttl()); - std::shared_ptr< endpoint > its_endpoint - = its_info->get_reliable_endpoint(); + std::shared_ptr< endpoint > its_endpoint = its_info->get_endpoint(true); if (its_endpoint) { - if (its_endpoint->is_v4()) { - std::shared_ptr< ipv4_option_impl > its_option - = _message->create_ipv4_option(false); - if (its_option) { - std::vector< byte_t > its_address; - if (its_endpoint->get_address(its_address)) { - its_option->set_address(its_address); - its_option->set_port(its_endpoint->get_port()); - its_option->set_udp(its_endpoint->is_udp()); - its_entry->assign_option(its_option, 1); - } - } - } else { - std::shared_ptr< ipv6_option_impl > its_option - = _message->create_ipv6_option(false); - if (its_option) { - std::shared_ptr< ipv4_option_impl > its_option - = _message->create_ipv4_option(false); - if (its_option) { - std::vector< byte_t > its_address; - if (its_endpoint->get_address(its_address)) { - its_option->set_address(its_address); - its_option->set_port(its_endpoint->get_port()); - its_option->set_udp(its_endpoint->is_udp()); - its_entry->assign_option(its_option, 1); - } - } - } + insert_service_option(_message, its_entry, its_endpoint); + if (0 == its_info->get_ttl()) { + host_->del_routing_info(its_service.first, its_instance.first, true); + } + } + + its_endpoint = its_info->get_endpoint(false); + if (its_endpoint) { + insert_service_option(_message, its_entry, its_endpoint); + if (0 == its_info->get_ttl()) { + host_->del_routing_info(its_service.first, its_instance.first, false); } } } else { @@ -183,8 +186,6 @@ void service_discovery_impl::insert_service_entries( void service_discovery_impl::send(const std::string &_name, bool _is_announcing) { - //std::unique_lock its_lock(serializer_mutex_); - std::shared_ptr< message_impl > its_message = runtime::get()->create_message(); // TODO: optimize building of SD message (common options) @@ -204,12 +205,132 @@ void service_discovery_impl::send(const std::string &_name, bool _is_announcing) // Interface endpoint_host void service_discovery_impl::on_message(const byte_t *_data, length_t _length) { +#if 0 + std::stringstream msg; + msg << "sdi::on_message: "; + for (length_t i = 0; i < _length; ++i) + msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; + VSOMEIP_DEBUG << msg.str(); +#endif deserializer_->set_data(_data, _length); std::shared_ptr< message_impl > its_message(deserializer_->deserialize_sd_message()); if (its_message) { - VSOMEIP_DEBUG << "Got a Service Discovery message."; + std::vector< std::shared_ptr< option_impl > > its_options + = its_message->get_options(); + for (auto its_entry : its_message->get_entries()) { + if (its_entry->is_service_entry()) { + std::shared_ptr< serviceentry_impl > its_service_entry + = std::dynamic_pointer_cast< serviceentry_impl >(its_entry); + process_serviceentry(its_service_entry, its_options); + } else { + std::shared_ptr< eventgroupentry_impl > its_eventgroup_entry + = std::dynamic_pointer_cast< eventgroupentry_impl >(its_entry); + process_eventgroupentry(its_eventgroup_entry, its_options); + } + } + } +} + +// Entry processing +void service_discovery_impl::process_serviceentry( + std::shared_ptr< serviceentry_impl > &_entry, + const std::vector< std::shared_ptr< option_impl > > &_options) { + service_t its_service = _entry->get_service(); + instance_t its_instance = _entry->get_instance(); + major_version_t its_major = _entry->get_major_version(); + minor_version_t its_minor = _entry->get_minor_version(); + ttl_t its_ttl = _entry->get_ttl(); + + VSOMEIP_DEBUG << "Service [" + << std::hex << std::setw(4) << std::setfill('0') + << its_service << "." << its_instance + << "], version " + << std::dec + << (int)its_major << "." << its_minor + << " is offered for " + << its_ttl + << " seconds."; + + // process options + for (auto i : { 1, 2 }) { + for (auto its_index : _entry->get_options(i)) { + std::vector< byte_t > its_option_address; + uint16_t its_option_port = VSOMEIP_INVALID_PORT; + std::shared_ptr< option_impl > its_option = _options[its_index]; + switch (its_option->get_type()) { + case option_type_e::IP4_ENDPOINT: + { + std::shared_ptr< ipv4_option_impl > its_ipv4_option + = std::dynamic_pointer_cast< ipv4_option_impl >(its_option); + + boost::asio::ip::address_v4 its_ipv4_address(its_ipv4_option->get_address()); + boost::asio::ip::address its_address(its_ipv4_address); + + its_option_port = its_ipv4_option->get_port(); + + if (0 < its_ttl) { + host_->add_routing_info(its_service, its_instance, + its_major, its_minor, its_ttl, + its_address, its_option_port, + !its_ipv4_option->is_udp()); + } else { + host_->del_routing_info(its_service, its_instance, + !its_ipv4_option->is_udp()); + } + } + break; + case option_type_e::IP6_ENDPOINT: + { + std::shared_ptr< ipv6_option_impl > its_ipv6_option + = std::dynamic_pointer_cast< ipv6_option_impl >(its_option); + + boost::asio::ip::address_v6 its_ipv6_address(its_ipv6_option->get_address()); + boost::asio::ip::address its_address(its_ipv6_address); + + its_option_port = its_ipv6_option->get_port(); + + if (0 < its_ttl) { + host_->add_routing_info(its_service, its_instance, + its_major, its_minor, its_ttl, + its_address, its_option_port, + !its_ipv6_option->is_udp()); + } else { + host_->del_routing_info(its_service, its_instance, + !its_ipv6_option->is_udp()); + } + } + break; + case option_type_e::IP4_MULTICAST: + case option_type_e::IP6_MULTICAST: + VSOMEIP_ERROR << "Invalid service option (Multicast)"; + break; + default: + VSOMEIP_WARNING << "Unsupported service option"; + break; + } + } } } +void service_discovery_impl::process_eventgroupentry( + std::shared_ptr< eventgroupentry_impl > &_entry, + const std::vector< std::shared_ptr< option_impl > > &_options) { + service_t its_service = _entry->get_service(); + instance_t its_instance = _entry->get_instance(); + eventgroup_t its_eventgroup = _entry->get_eventgroup(); + major_version_t its_major = _entry->get_major_version(); + ttl_t its_ttl = _entry->get_ttl(); + + VSOMEIP_DEBUG << "Eventgroup [" + << std::hex << std::setw(4) << std::setfill('0') + << its_service << "." << its_instance << "." << its_eventgroup + << "], version " + << std::dec + << (int)its_major + << " is offered for " + << its_ttl + << " seconds."; +} + } // namespace sd } // namespace vsomeip diff --git a/interface/vsomeip/primitive_types.hpp b/interface/vsomeip/primitive_types.hpp index 9ad4ff7..7a30033 100644 --- a/interface/vsomeip/primitive_types.hpp +++ b/interface/vsomeip/primitive_types.hpp @@ -7,6 +7,7 @@ #ifndef VSOMEIP_PRIMITIVE_TYPES_HPP #define VSOMEIP_PRIMITIVE_TYPES_HPP +#include <array> #include <cstdint> namespace vsomeip { @@ -35,6 +36,10 @@ typedef uint8_t interface_version_t; typedef uint8_t byte_t; +// Addresses +typedef std::array< byte_t, 4 > ipv4_address_t; +typedef std::array< byte_t, 16 > ipv6_address_t; + } // namespace vsomeip #endif // VSOMEIP_PRIMITIVE_TYPES_HPP |