diff options
author | Lutz Bichler <Lutz.Bichler@bmw.de> | 2014-08-01 14:19:24 +0200 |
---|---|---|
committer | Lutz Bichler <Lutz.Bichler@bmw.de> | 2014-08-01 14:19:24 +0200 |
commit | 8dfb0d6a1bf29e1d4dc7ff3a0788be3a4d01bec1 (patch) | |
tree | 692560f88b37545414d15cf861a405d983dbc71b | |
parent | af46f8a2270af686af2d8b4bcb5750539a12a52d (diff) | |
download | vSomeIP-8dfb0d6a1bf29e1d4dc7ff3a0788be3a4d01bec1.tar.gz |
First part of event/eventgroup implementation. Subscription works.
Second part (routing) is missing.
67 files changed, 3717 insertions, 2644 deletions
diff --git a/config/vsomeip-tcp-client.json b/config/vsomeip-tcp-client.json index 2a7a8c7..e0c50c9 100644 --- a/config/vsomeip-tcp-client.json +++ b/config/vsomeip-tcp-client.json @@ -3,7 +3,7 @@ "netmask" : "255.255.255.0", "logging" : { - "level" : "debug", + "level" : "info", "console" : "true", "file" : { "enable" : "true", "path" : "/var/log/vsomeip.log" }, "dlt" : "true" @@ -42,32 +42,29 @@ [ { "event" : "0x0777", - "is_field" : true + "is_field" : "true" }, { "event" : "0x0778", - "is_field" : false + "is_field" : "false" }, { "event" : "0x0779", - "is_field" : true + "is_field" : "true" } ], "eventgroups" : [ { "eventgroup" : "0x4455", - "multicast" : "224.225.226.223", "events" : [ "0x777", "0x778" ] }, { "eventgroup" : "0x4465", - "multicast" : "224.225.226.228", "events" : [ "0x778", "0x779" ] }, { "eventgroup" : "0x4555", - "multicast" : "224.225.226.233", "events" : [ "0x777", "0x779" ] } ] diff --git a/config/vsomeip-tcp-service.json b/config/vsomeip-tcp-service.json index 816c577..9e6583b 100644 --- a/config/vsomeip-tcp-service.json +++ b/config/vsomeip-tcp-service.json @@ -1,5 +1,5 @@ { - "unicast" : "192.168.56.102", + "unicast" : "192.168.56.101", "logging" : { "level" : "debug", diff --git a/config/vsomeip-udp-client.json b/config/vsomeip-udp-client.json index 544778d..1cdc55d 100644 --- a/config/vsomeip-udp-client.json +++ b/config/vsomeip-udp-client.json @@ -1,9 +1,9 @@ { - "unicast" : "192.168.56.101", + "unicast" : "192.168.56.104", "netmask" : "255.255.255.0", "logging" : { - "level" : "debug", + "level" : "trace", "console" : "true", "file" : { "enable" : "true", "path" : "/var/log/vsomeip.log" }, "dlt" : "true" @@ -15,15 +15,15 @@ "id" : "0x1343" }, { - "name" : "client-sample", + "name" : "second-client-sample", "id" : "0x1344" }, { - "name" : "client-sample", + "name" : "third-client-sample", "id" : "0x1345" }, { - "name" : "client-sample", + "name" : "fourth-client-sample", "id" : "0x1346" } ], @@ -31,13 +31,18 @@ [ { "name" : "remote", - "address" : "192.168.56.102", + "unicast" : "192.168.56.101", "services" : [ { "service" : "0x1234", "instance" : "0x5678", "unreliable" : "30509", + "multicast" : + { + "address" : "224.225.226.233", + "port" : "32344" + }, "events" : [ { @@ -57,17 +62,15 @@ [ { "eventgroup" : "0x4455", - "multicast" : "224.225.226.223", "events" : [ "0x777", "0x778" ] }, { "eventgroup" : "0x4465", - "multicast" : "224.225.226.228", - "events" : [ "0x778", "0x779" ] + "events" : [ "0x778", "0x779" ], + "is_multicast" : "true" }, { "eventgroup" : "0x4555", - "multicast" : "224.225.226.233", "events" : [ "0x777", "0x779" ] } ] @@ -79,7 +82,7 @@ "service-discovery" : { "enable" : "true", - "multicast" : "224.244.224.224", + "multicast" : "224.244.224.245", "port" : "30490", "protocol" : "udp" } diff --git a/config/vsomeip-udp-service.json b/config/vsomeip-udp-service.json index cba6b6e..406f2f3 100644 --- a/config/vsomeip-udp-service.json +++ b/config/vsomeip-udp-service.json @@ -1,12 +1,12 @@ { - "unicast" : "192.168.56.102", + "unicast" : "192.168.56.101", "logging" : { - "level" : "debug", + "level" : "trace", "console" : "true", "file" : { "enable" : "false", "path" : "/tmp/vsomeip.log" }, - "dlt" : "false", - } + "dlt" : "false" + }, "applications" : [ { @@ -18,9 +18,14 @@ [ { "name" : "default", + "unicast" : "local", "delays" : { - "initial" : { "minimum" : "10", "maximum" : 100 }, + "initial" : + { + "minimum" : "10", + "maximum" : 100 + }, "repetition-base" : "200", "repetition-max" : "3", "cyclic-offer" : "2000", @@ -30,12 +35,50 @@ [ { "service" : "0x1234", - "instance" : "0x5678" + "instance" : "0x5678", "unreliable" : "30509", + "multicast" : + { + "address" : "224.225.226.233", + "port" : "32344" + }, + "events" : + [ + { + "event" : "0x0777", + "is_field" : "true", + "update-cycle" : 2000 + }, + { + "event" : "0x0778", + "is_field" : "false", + "update-cycle" : 0 + }, + { + "event" : "0x0779", + "is_field" : "true" + } + ], + "eventgroups" : + [ + { + "eventgroup" : "0x4455", + "events" : [ "0x777", "0x778" ] + }, + { + "eventgroup" : "0x4465", + "events" : [ "0x778", "0x779" ], + "is_multicast" : "true" + }, + { + "eventgroup" : "0x4555", + "events" : [ "0x777", "0x779" ] + } + ] } ] } - ] + ], "routing" : "service-sample", "service-discovery" : { diff --git a/documentation/readme.txt b/documentation/readme.txt new file mode 100644 index 0000000..4d1376a --- /dev/null +++ b/documentation/readme.txt @@ -0,0 +1,3 @@ +To use IP multicast, the route must be added. In Linux this can be done +by "route add -net 224.0.0.0/4 dev eth0". + diff --git a/examples/client-sample.cpp b/examples/client-sample.cpp index 7d27222..c500d77 100644 --- a/examples/client-sample.cpp +++ b/examples/client-sample.cpp @@ -55,6 +55,9 @@ public: this, std::placeholders::_1)); + app_->subscribe(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENTGROUP_ID, + vsomeip::ANY_MAJOR, vsomeip::ANY_TTL); + request_->set_service(SAMPLE_SERVICE_ID); request_->set_instance(SAMPLE_INSTANCE_ID); request_->set_method(SAMPLE_METHOD_ID); diff --git a/examples/sample-ids.hpp b/examples/sample-ids.hpp index 3fc097f..45a6f85 100644 --- a/examples/sample-ids.hpp +++ b/examples/sample-ids.hpp @@ -9,7 +9,10 @@ #define SAMPLE_SERVICE_ID 0x1234 #define SAMPLE_INSTANCE_ID 0x5678 -#define SAMPLE_METHOD_ID 0x0421 +#define SAMPLE_METHOD_ID 0x8421 +#define SAMPLE_EVENT_ID 0x0778 + +#define SAMPLE_EVENTGROUP_ID 0x4465 #define OTHER_SAMPLE_SERVICE_ID 0x0248 #define OTHER_SAMPLE_INSTANCE_ID 0x5422 diff --git a/examples/service-sample.cpp b/examples/service-sample.cpp index 13f134b..98b8c66 100644 --- a/examples/service-sample.cpp +++ b/examples/service-sample.cpp @@ -16,120 +16,165 @@ #include "sample-ids.hpp" class service_sample { -public: - service_sample(bool _use_tcp) - : app_(vsomeip::runtime::get()->create_application()), - is_registered_(false), - 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, - std::bind(&service_sample::on_message, - this, - std::placeholders::_1) - ); - - app_->register_event_handler( - std::bind(&service_sample::on_event, this, std::placeholders::_1)); - - blocked_ = true; - condition_.notify_one(); - } - - void start() { - app_->start(); - } - - void offer() { - 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 " - << (_event == vsomeip::event_type_e::REGISTERED ? "registered." : "deregistered."); - - if (_event == vsomeip::event_type_e::REGISTERED) { - if (!is_registered_) { - is_registered_= true; - } - } else { - is_registered_ = false; - } - } - - void on_message(std::shared_ptr< vsomeip::message > &_request) { - VSOMEIP_INFO << "Received a message with Client/Session [" - << std::setw(4) << std::setfill('0') << std::hex << _request->get_client() - << "/" - << std::setw(4) << std::setfill('0') << std::hex << _request->get_session() - << "]"; - - std::shared_ptr< vsomeip::message > its_response - = vsomeip::runtime::get()->create_response(_request); - - std::shared_ptr< vsomeip::payload > its_payload = vsomeip::runtime::get()->create_payload(); - std::vector< vsomeip::byte_t > its_payload_data; - for (std::size_t i = 0; i < 120; ++i) its_payload_data.push_back(i % 256); - its_payload->set_data(its_payload_data); - its_response->set_payload(its_payload); - - 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_; + public: + service_sample(bool _use_tcp) + : app_(vsomeip::runtime::get()->create_application()), + is_registered_(false), + use_tcp_(_use_tcp), + offer_thread_(std::bind(&service_sample::run, this)), + notification_thread_(std::bind(&service_sample::notify, 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, + std::bind(&service_sample::on_message, this, std::placeholders::_1)); + + app_->register_event_handler( + std::bind(&service_sample::on_event, this, std::placeholders::_1)); + + blocked_ = true; + condition_.notify_one(); + } + + void start() { + app_->start(); + } + + void offer() { + VSOMEIP_INFO << "Offering service."; + //std::lock_guard < std::mutex > its_lock(notification_mutex_); + app_->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID); + + notification_blocked_ = true; + //condition_.notify_one(); + } + + void stop_offer() { + VSOMEIP_INFO << "Stop offering service."; + app_->stop_offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID); + notification_blocked_ = false; + } + + void update() { + static std::shared_ptr<vsomeip::payload> its_payload = + vsomeip::runtime::get()->create_payload(); + + static vsomeip::byte_t its_data[1000]; + static uint32_t its_size = 0; + + its_size++; + for (uint32_t i = 0; i < its_size; ++i) + its_data[i] = (i % 256); + + its_payload->set_data(its_data, its_size); + + VSOMEIP_INFO << "Updating event to " << its_size << " bytes."; + app_->set(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, + its_payload); + } + + void on_event(vsomeip::event_type_e _event) { + VSOMEIP_INFO << "Application " << app_->get_name() << " is " + << (_event == vsomeip::event_type_e::REGISTERED ? + "registered." : "deregistered."); + + if (_event == vsomeip::event_type_e::REGISTERED) { + if (!is_registered_) { + is_registered_ = true; + } + } else { + is_registered_ = false; + } + } + + void on_message(std::shared_ptr<vsomeip::message> &_request) { + VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4) + << std::setfill('0') << std::hex << _request->get_client() << "/" + << std::setw(4) << std::setfill('0') << std::hex + << _request->get_session() << "]"; + + std::shared_ptr<vsomeip::message> its_response = vsomeip::runtime::get() + ->create_response(_request); + + std::shared_ptr<vsomeip::payload> its_payload = vsomeip::runtime::get() + ->create_payload(); + std::vector<vsomeip::byte_t> its_payload_data; + for (std::size_t i = 0; i < 120; ++i) + its_payload_data.push_back(i % 256); + its_payload->set_data(its_payload_data); + its_response->set_payload(its_payload); + + 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; + } + } + + void notify() { + while (true) { + //std::unique_lock < std::mutex > its_lock(notification_mutex_); + //while (!notification_blocked_) + // notification_condition_.wait(its_lock); + //while (notification_blocked_) { + std::this_thread::sleep_for(std::chrono::milliseconds(500)); + if (notification_blocked_) update(); + //} + } + } + + 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_; + + std::thread notification_thread_; + std::mutex notification_mutex_; + std::condition_variable notification_condition_; + bool notification_blocked_; }; int main(int argc, char **argv) { - bool use_tcp = false; - - std::string tcp_enable("--tcp"); - std::string udp_enable("--udp"); - - for (int i = 1; i < argc; i++) { - if (tcp_enable == argv[i]) { - use_tcp = true; - break; - } - if (udp_enable == argv[i]) { - use_tcp = false; - break; - } - } - - service_sample its_sample(use_tcp); - its_sample.init(); - its_sample.start(); - - return 0; + bool use_tcp = false; + + std::string tcp_enable("--tcp"); + std::string udp_enable("--udp"); + + for (int i = 1; i < argc; i++) { + if (tcp_enable == argv[i]) { + use_tcp = true; + break; + } + if (udp_enable == argv[i]) { + use_tcp = false; + break; + } + } + + service_sample its_sample(use_tcp); + its_sample.init(); + its_sample.start(); + + return 0; } diff --git a/exportmap.gcc b/exportmap.gcc index 92cc98c..a86d0e4 100644 --- a/exportmap.gcc +++ b/exportmap.gcc @@ -21,6 +21,8 @@ global: vsomeip::runtime::get*; *vsomeip::application_impl; vsomeip::application_impl*; + *vsomeip::eventgroupinfo; + vsomeip::eventgroupinfo::*; *vsomeip::servicegroup; vsomeip::servicegroup::*; *vsomeip::serviceinfo; diff --git a/implementation/configuration/include/configuration_impl.hpp b/implementation/configuration/include/configuration_impl.hpp index 612bc4d..15c1680 100644 --- a/implementation/configuration/include/configuration_impl.hpp +++ b/implementation/configuration/include/configuration_impl.hpp @@ -51,7 +51,11 @@ public: int32_t get_cyclic_offer_delay(const std::string &_name) const; int32_t get_cyclic_request_delay(const std::string &_name) const; - std::string get_address(service_t _service, instance_t _instance) const; + std::string get_unicast(service_t _service, instance_t _instance) const; + std::string get_multicast_address(service_t _service, instance_t _instance) const; + uint16_t get_multicast_port(service_t _service, instance_t _instance) const; + uint16_t get_multicast_group(service_t _service, instance_t _instance) const; + uint16_t get_reliable_port(service_t _service, instance_t _instance) const; bool has_enabled_magic_cookies(std::string _address, uint16_t _port) const; uint16_t get_unreliable_port(service_t _service, instance_t _instance) const; @@ -67,6 +71,10 @@ public: std::set< std::pair< service_t, instance_t > > get_remote_services() const; + std::map<service_t, std::map<instance_t, std::map<eventgroup_t, std::set<event_t> > > > get_eventgroups() const; + std::map<service_t, std::map<instance_t, std::set<event_t> > > get_events() const; + void set_event(std::shared_ptr<event> &_event) const; + private: bool get_someip_configuration(boost::property_tree::ptree &_tree); bool get_logging_configuration(boost::property_tree::ptree &_tree); diff --git a/implementation/configuration/include/eventgroup.hpp b/implementation/configuration/include/eventgroup.hpp index cd58dee..377c17f 100644 --- a/implementation/configuration/include/eventgroup.hpp +++ b/implementation/configuration/include/eventgroup.hpp @@ -18,7 +18,6 @@ struct event; struct eventgroup { eventgroup_t id_; - std::string multicast_; std::set<std::shared_ptr<event> > events_; }; diff --git a/implementation/configuration/include/service.hpp b/implementation/configuration/include/service.hpp index 9459648..fd885e4 100644 --- a/implementation/configuration/include/service.hpp +++ b/implementation/configuration/include/service.hpp @@ -24,6 +24,10 @@ struct service { uint16_t reliable_; uint16_t unreliable_; + std::string multicast_address_; + uint16_t multicast_port_; + eventgroup_t multicast_group_; + bool use_magic_cookies_; std::shared_ptr<servicegroup> group_; diff --git a/implementation/configuration/src/configuration_impl.cpp b/implementation/configuration/src/configuration_impl.cpp index 4bc8621..ff2d5dc 100644 --- a/implementation/configuration/src/configuration_impl.cpp +++ b/implementation/configuration/src/configuration_impl.cpp @@ -20,6 +20,7 @@ #include "../include/servicegroup.hpp" #include "../include/service.hpp" #include "../../logging/include/logger_impl.hpp" +#include "../../routing/include/event.hpp" #include "../../service_discovery/include/defines.hpp" namespace vsomeip { @@ -29,696 +30,785 @@ std::map<std::string, configuration *> configuration_impl::the_configurations; std::mutex configuration_impl::mutex_; configuration * configuration_impl::get(const std::string &_path) { - configuration *its_configuration(0); + configuration *its_configuration(0); - bool is_freshly_loaded(false); - { - std::unique_lock < std::mutex > its_lock(mutex_); + bool is_freshly_loaded(false); + { + std::unique_lock < std::mutex > its_lock(mutex_); - auto found_configuration = the_configurations.find(_path); - if (found_configuration != the_configurations.end()) { - its_configuration = found_configuration->second; - } else { - its_configuration = new configuration_impl; - if (its_configuration->load(_path)) { - the_configurations[_path] = its_configuration; - is_freshly_loaded = true; - } else { - delete its_configuration; - its_configuration = 0; - } - } - } + auto found_configuration = the_configurations.find(_path); + if (found_configuration != the_configurations.end()) { + its_configuration = found_configuration->second; + } else { + its_configuration = new configuration_impl; + if (its_configuration->load(_path)) { + the_configurations[_path] = its_configuration; + is_freshly_loaded = true; + } else { + delete its_configuration; + its_configuration = 0; + } + } + } - if (is_freshly_loaded) - logger_impl::init(_path); + if (is_freshly_loaded) + logger_impl::init(_path); - return its_configuration; + return its_configuration; } -configuration_impl::configuration_impl() : - has_console_log_(true), has_file_log_(false), has_dlt_log_(false), logfile_( - "/tmp/vsomeip.log"), loglevel_( - boost::log::trivial::severity_level::info), routing_host_( - "vsomeipd"), is_service_discovery_enabled_(false) { +configuration_impl::configuration_impl() + : has_console_log_(true), + has_file_log_(false), + has_dlt_log_(false), + logfile_("/tmp/vsomeip.log"), + loglevel_(boost::log::trivial::severity_level::info), + routing_host_("vsomeipd"), + is_service_discovery_enabled_(false) { - unicast_ = unicast_.from_string("127.0.0.1"); + unicast_ = unicast_.from_string("127.0.0.1"); } configuration_impl::~configuration_impl() { } bool configuration_impl::load(const std::string &_path) { - bool is_loaded(true); - boost::property_tree::ptree its_tree; + bool is_loaded(true); + boost::property_tree::ptree its_tree; - try { - boost::property_tree::json_parser::read_json(_path, its_tree); + try { + boost::property_tree::json_parser::read_json(_path, its_tree); - // Read the configuration data - is_loaded = get_someip_configuration(its_tree); - is_loaded = get_logging_configuration(its_tree); - is_loaded = is_loaded && get_services_configuration(its_tree); - is_loaded = is_loaded && get_routing_configuration(its_tree); - is_loaded = is_loaded && get_service_discovery_configuration(its_tree); - is_loaded = is_loaded && get_applications_configuration(its_tree); - } catch (std::exception &e) { - std::cerr << e.what() << std::endl; - is_loaded = false; - } + // Read the configuration data + is_loaded = get_someip_configuration(its_tree); + is_loaded = get_logging_configuration(its_tree); + is_loaded = is_loaded && get_services_configuration(its_tree); + is_loaded = is_loaded && get_routing_configuration(its_tree); + is_loaded = is_loaded && get_service_discovery_configuration(its_tree); + is_loaded = is_loaded && get_applications_configuration(its_tree); + } catch (std::exception &e) { + std::cerr << e.what() << std::endl; + is_loaded = false; + } - return is_loaded; + return is_loaded; } bool configuration_impl::get_someip_configuration( - boost::property_tree::ptree &_tree) { - bool is_loaded(true); - try { - std::string its_value = _tree.get < std::string > ("unicast"); - unicast_ = unicast_.from_string(its_value); - } catch (...) { - is_loaded = false; - } - return is_loaded; + boost::property_tree::ptree &_tree) { + bool is_loaded(true); + try { + std::string its_value = _tree.get < std::string > ("unicast"); + unicast_ = unicast_.from_string(its_value); + } catch (...) { + is_loaded = false; + } + return is_loaded; } bool configuration_impl::get_logging_configuration( - boost::property_tree::ptree &_tree) { - bool is_loaded(true); - try { - auto its_logging = _tree.get_child("logging"); - for (auto i = its_logging.begin(); i != its_logging.end(); ++i) { - std::string its_key(i->first); - if (its_key == "console") { - std::string its_value(i->second.data()); - has_console_log_ = (its_value == "true"); - } else if (its_key == "file") { - for (auto j : i->second) { - std::string its_sub_key(j.first); - std::string its_sub_value(j.second.data()); - if (its_sub_key == "enable") { - has_file_log_ = (its_sub_value == "true"); - } else if (its_sub_key == "path") { - logfile_ = its_sub_value; - } - } - } else if (its_key == "dlt") { - std::string its_value(i->second.data()); - has_dlt_log_ = (its_value == "true"); - } else if (its_key == "level") { - std::string its_value(i->second.data()); - loglevel_ = - (its_value == "trace" ? - boost::log::trivial::severity_level::trace : - (its_value == "debug" ? - boost::log::trivial::severity_level::debug : - (its_value == "info" ? - boost::log::trivial::severity_level::info : - (its_value == "warning" ? - boost::log::trivial::severity_level::warning : - (its_value == "error" ? - boost::log::trivial::severity_level::error : - (its_value - == "fatal" ? - boost::log::trivial::severity_level::fatal : - boost::log::trivial::severity_level::info)))))); - } - } - } catch (...) { - is_loaded = false; - } - return is_loaded; + boost::property_tree::ptree &_tree) { + bool is_loaded(true); + try { + auto its_logging = _tree.get_child("logging"); + for (auto i = its_logging.begin(); i != its_logging.end(); ++i) { + std::string its_key(i->first); + if (its_key == "console") { + std::string its_value(i->second.data()); + has_console_log_ = (its_value == "true"); + } else if (its_key == "file") { + for (auto j : i->second) { + std::string its_sub_key(j.first); + std::string its_sub_value(j.second.data()); + if (its_sub_key == "enable") { + has_file_log_ = (its_sub_value == "true"); + } else if (its_sub_key == "path") { + logfile_ = its_sub_value; + } + } + } else if (its_key == "dlt") { + std::string its_value(i->second.data()); + has_dlt_log_ = (its_value == "true"); + } else if (its_key == "level") { + std::string its_value(i->second.data()); + loglevel_ = + (its_value == "trace" ? + boost::log::trivial::severity_level::trace : + (its_value == "debug" ? + boost::log::trivial::severity_level::debug : + (its_value == "info" ? + boost::log::trivial::severity_level::info : + (its_value == "warning" ? + boost::log::trivial::severity_level::warning : + (its_value == "error" ? + boost::log::trivial::severity_level::error : + (its_value == "fatal" ? + boost::log::trivial::severity_level::fatal : + boost::log::trivial::severity_level::info)))))); + } + } + } catch (...) { + is_loaded = false; + } + return is_loaded; } bool configuration_impl::get_services_configuration( - boost::property_tree::ptree &_tree) { - bool is_loaded(true); - try { - auto its_services = _tree.get_child("servicegroups"); - for (auto i = its_services.begin(); i != its_services.end(); ++i) - is_loaded = is_loaded && get_servicegroup_configuration(i->second); - } catch (...) { - is_loaded = false; - } - return is_loaded; + boost::property_tree::ptree &_tree) { + bool is_loaded(true); + try { + auto its_services = _tree.get_child("servicegroups"); + for (auto i = its_services.begin(); i != its_services.end(); ++i) + is_loaded = is_loaded && get_servicegroup_configuration(i->second); + } catch (...) { + is_loaded = false; + } + return is_loaded; } bool configuration_impl::get_servicegroup_configuration( - const boost::property_tree::ptree &_tree) { - bool is_loaded(true); - try { - std::shared_ptr<servicegroup> its_servicegroup( - std::make_shared<servicegroup>()); - its_servicegroup->unicast_ = "local"; // Default - for (auto i = _tree.begin(); i != _tree.end(); ++i) { - std::string its_key(i->first); - if (its_key == "name") { - its_servicegroup->name_ = i->second.data(); - } else if (its_key == "unicast") { - its_servicegroup->unicast_ = i->second.data(); - } else if (its_key == "delays") { - is_loaded = is_loaded - && get_delays_configuration(its_servicegroup, - i->second); - } else if (its_key == "services") { - for (auto j = i->second.begin(); j != i->second.end(); ++j) - is_loaded = is_loaded - && get_service_configuration(its_servicegroup, - j->second); - } - } - servicegroups_[its_servicegroup->name_] = its_servicegroup; - } catch (...) { - is_loaded = false; - } - return is_loaded; + const boost::property_tree::ptree &_tree) { + bool is_loaded(true); + try { + std::shared_ptr<servicegroup> its_servicegroup( + std::make_shared<servicegroup>()); + its_servicegroup->unicast_ = "local"; // Default + for (auto i = _tree.begin(); i != _tree.end(); ++i) { + std::string its_key(i->first); + if (its_key == "name") { + its_servicegroup->name_ = i->second.data(); + } else if (its_key == "unicast") { + its_servicegroup->unicast_ = i->second.data(); + } else if (its_key == "delays") { + is_loaded = is_loaded + && get_delays_configuration(its_servicegroup, i->second); + } else if (its_key == "services") { + for (auto j = i->second.begin(); j != i->second.end(); ++j) + is_loaded = is_loaded + && get_service_configuration(its_servicegroup, j->second); + } + } + servicegroups_[its_servicegroup->name_] = its_servicegroup; + } catch (...) { + is_loaded = false; + } + return is_loaded; } bool configuration_impl::get_delays_configuration( - std::shared_ptr<servicegroup> &_group, - const boost::property_tree::ptree &_tree) { - bool is_loaded(true); - try { - std::stringstream its_converter; - for (auto i = _tree.begin(); i != _tree.end(); ++i) { - std::string its_key(i->first); - if (its_key == "initial") { - _group->min_initial_delay_ = i->second.get < uint32_t - > ("minimum"); - _group->max_initial_delay_ = i->second.get < uint32_t - > ("maximum"); - } else if (its_key == "repetition-base") { - its_converter << std::dec << i->second.data(); - its_converter >> _group->repetition_base_delay_; - } else if (its_key == "repetition-max") { - int tmp_repetition_max; - its_converter << std::dec << i->second.data(); - its_converter >> tmp_repetition_max; - _group->repetition_max_ = tmp_repetition_max; - } else if (its_key == "cyclic-offer") { - its_converter << std::dec << i->second.data(); - its_converter >> _group->cyclic_offer_delay_; - } else if (its_key == "cyclic-request") { - its_converter << std::dec << i->second.data(); - its_converter >> _group->cyclic_request_delay_; - } - its_converter.str(""); - its_converter.clear(); - } - } catch (...) { - is_loaded = false; - } - return is_loaded; + std::shared_ptr<servicegroup> &_group, + const boost::property_tree::ptree &_tree) { + bool is_loaded(true); + try { + std::stringstream its_converter; + for (auto i = _tree.begin(); i != _tree.end(); ++i) { + std::string its_key(i->first); + if (its_key == "initial") { + _group->min_initial_delay_ = i->second.get < uint32_t > ("minimum"); + _group->max_initial_delay_ = i->second.get < uint32_t > ("maximum"); + } else if (its_key == "repetition-base") { + its_converter << std::dec << i->second.data(); + its_converter >> _group->repetition_base_delay_; + } else if (its_key == "repetition-max") { + int tmp_repetition_max; + its_converter << std::dec << i->second.data(); + its_converter >> tmp_repetition_max; + _group->repetition_max_ = tmp_repetition_max; + } else if (its_key == "cyclic-offer") { + its_converter << std::dec << i->second.data(); + its_converter >> _group->cyclic_offer_delay_; + } else if (its_key == "cyclic-request") { + its_converter << std::dec << i->second.data(); + its_converter >> _group->cyclic_request_delay_; + } + its_converter.str(""); + its_converter.clear(); + } + } catch (...) { + is_loaded = false; + } + return is_loaded; } bool configuration_impl::get_service_configuration( - std::shared_ptr<servicegroup> &_group, - const boost::property_tree::ptree &_tree) { - bool is_loaded(true); - try { - bool use_magic_cookies(false); - - std::shared_ptr<service> its_service(std::make_shared<service>()); - its_service->reliable_ = its_service->unreliable_ = ILLEGAL_PORT; - its_service->use_magic_cookies_ = false; - its_service->group_ = _group; - - for (auto i = _tree.begin(); i != _tree.end(); ++i) { - std::string its_key(i->first); - std::string its_value(i->second.data()); - std::stringstream its_converter; - - if (its_key == "reliable") { - try { - its_value = i->second.get_child("port").data(); - its_converter << its_value; - its_converter >> its_service->reliable_; - } catch (...) { - its_converter << its_value; - its_converter >> its_service->reliable_; - } - try { - its_value = - i->second.get_child("enable-magic-cookies").data(); - use_magic_cookies = ("true" == its_value); - } catch (...) { - - } - } else if (its_key == "unreliable") { - its_converter << its_value; - its_converter >> its_service->unreliable_; - } else if (its_key == "events") { - get_event_configuration(its_service, i->second); - } else if (its_key == "eventgroups") { - get_eventgroup_configuration(its_service, i->second); - } else { - // Trim "its_value" - if (its_value[0] == '0' && its_value[1] == 'x') { - its_converter << std::hex << its_value; - } else { - its_converter << std::dec << its_value; - } - - if (its_key == "service") { - its_converter >> its_service->service_; - } else if (its_key == "instance") { - its_converter >> its_service->instance_; - } - } - } - - auto found_service = services_.find(its_service->service_); - if (found_service != services_.end()) { - auto found_instance = found_service->second.find( - its_service->instance_); - if (found_instance != found_service->second.end()) { - is_loaded = false; - } - } - - if (is_loaded) { - services_[its_service->service_][its_service->instance_] = - its_service; - } - - if (use_magic_cookies) { - std::string its_unicast(_group->unicast_); - if (its_unicast == "local") - its_unicast = unicast_.to_string(); - magic_cookies_[its_unicast].insert(its_service->reliable_); - } - } catch (...) { - is_loaded = false; - } - return is_loaded; + std::shared_ptr<servicegroup> &_group, + const boost::property_tree::ptree &_tree) { + bool is_loaded(true); + try { + bool use_magic_cookies(false); + + std::shared_ptr<service> its_service(std::make_shared<service>()); + its_service->reliable_ = its_service->unreliable_ = ILLEGAL_PORT; + its_service->use_magic_cookies_ = false; + its_service->group_ = _group; + its_service->multicast_address_ = ""; + its_service->multicast_port_ = ILLEGAL_PORT; + its_service->multicast_group_ = 0xFFFF; // TODO: use symbolic constant + + for (auto i = _tree.begin(); i != _tree.end(); ++i) { + std::string its_key(i->first); + std::string its_value(i->second.data()); + std::stringstream its_converter; + + if (its_key == "reliable") { + try { + its_value = i->second.get_child("port").data(); + its_converter << its_value; + its_converter >> its_service->reliable_; + } catch (...) { + its_converter << its_value; + its_converter >> its_service->reliable_; + } + try { + its_value = i->second.get_child("enable-magic-cookies").data(); + use_magic_cookies = ("true" == its_value); + } catch (...) { + + } + } else if (its_key == "unreliable") { + its_converter << its_value; + its_converter >> its_service->unreliable_; + } else if (its_key == "multicast") { + try { + its_value = i->second.get_child("address").data(); + its_service->multicast_address_ = its_value; + its_value = i->second.get_child("port").data(); + its_converter << its_value; + its_converter >> its_service->multicast_port_; + } catch (...) { + } + } else if (its_key == "events") { + get_event_configuration(its_service, i->second); + } else if (its_key == "eventgroups") { + get_eventgroup_configuration(its_service, i->second); + } else { + // Trim "its_value" + if (its_value[0] == '0' && its_value[1] == 'x') { + its_converter << std::hex << its_value; + } else { + its_converter << std::dec << its_value; + } + + if (its_key == "service") { + its_converter >> its_service->service_; + } else if (its_key == "instance") { + its_converter >> its_service->instance_; + } + } + } + + auto found_service = services_.find(its_service->service_); + if (found_service != services_.end()) { + auto found_instance = found_service->second.find(its_service->instance_); + if (found_instance != found_service->second.end()) { + is_loaded = false; + } + } + + if (is_loaded) { + services_[its_service->service_][its_service->instance_] = its_service; + } + + if (use_magic_cookies) { + std::string its_unicast(_group->unicast_); + if (its_unicast == "local") + its_unicast = unicast_.to_string(); + magic_cookies_[its_unicast].insert(its_service->reliable_); + } + } catch (...) { + is_loaded = false; + } + return is_loaded; } bool configuration_impl::get_event_configuration( - std::shared_ptr<service> &_service, - const boost::property_tree::ptree &_tree) { - bool is_loaded(true); - for (auto i = _tree.begin(); i != _tree.end(); ++i) { - event_t its_event_id(0); - bool its_is_field(false); - - for (auto j = i->second.begin(); j != i->second.end(); ++j) { - std::string its_key(j->first); - std::string its_value(j->second.data()); - if (its_key == "event") { - std::stringstream its_converter; - if (its_value[0] == '0' && its_value[1] == 'x') { - its_converter << std::hex << its_value; - } else { - its_converter << std::dec << its_value; - } - its_converter >> its_event_id; - } else if (its_key == "is_field") { - its_is_field = (its_value == "true"); - } - } - - if (its_event_id > 0) { - auto found_event = _service->events_.find(its_event_id); - if (found_event != _service->events_.end()) { - found_event->second->is_field_ = its_is_field; - } else { - std::shared_ptr<event> its_event = std::make_shared<event>(its_event_id, its_is_field); - _service->events_[its_event_id] = its_event; - } - } - } - return is_loaded; + std::shared_ptr<service> &_service, + const boost::property_tree::ptree &_tree) { + bool is_loaded(true); + for (auto i = _tree.begin(); i != _tree.end(); ++i) { + event_t its_event_id(0); + bool its_is_field(false); + + for (auto j = i->second.begin(); j != i->second.end(); ++j) { + std::string its_key(j->first); + std::string its_value(j->second.data()); + if (its_key == "event") { + std::stringstream its_converter; + if (its_value[0] == '0' && its_value[1] == 'x') { + its_converter << std::hex << its_value; + } else { + its_converter << std::dec << its_value; + } + its_converter >> its_event_id; + } else if (its_key == "is_field") { + its_is_field = (its_value == "true"); + } + } + + if (its_event_id > 0) { + auto found_event = _service->events_.find(its_event_id); + if (found_event != _service->events_.end()) { + found_event->second->is_field_ = its_is_field; + } else { + std::shared_ptr<event> its_event = std::make_shared < event + > (its_event_id, its_is_field); + _service->events_[its_event_id] = its_event; + } + } + } + return is_loaded; } bool configuration_impl::get_eventgroup_configuration( - std::shared_ptr<service> &_service, - const boost::property_tree::ptree &_tree) { - bool is_loaded(true); - for (auto i = _tree.begin(); i != _tree.end(); ++i) { - std::shared_ptr<eventgroup> its_eventgroup = std::make_shared<eventgroup>(); - for (auto j = i->second.begin(); j != i->second.end(); ++j) { - std::string its_key(j->first); - if (its_key == "eventgroup") { - std::stringstream its_converter; - std::string its_value(j->second.data()); - if (its_value[0] == '0' && its_value[1] == 'x') { - its_converter << std::hex << its_value; - } else { - its_converter << std::dec << its_value; - } - its_converter >> its_eventgroup->id_; - } else if (its_key == "multicast") { - std::string its_value(j->second.data()); - its_eventgroup->multicast_ = its_value; - } else if (its_key == "events") { - for (auto k = j->second.begin(); k != j->second.end(); ++k) { - std::stringstream its_converter; - std::string its_value(k->second.data()); - event_t its_event_id(0); - if (its_value[0] == '0' && its_value[1] == 'x') { - its_converter << std::hex << its_value; - } else { - its_converter << std::dec << its_value; - } - its_converter >> its_event_id; - if (0 < its_event_id) { - auto find_event = _service->events_.find(its_event_id); - if (find_event != _service->events_.end()) { - find_event->second->groups_.push_back(its_eventgroup); - } else { - std::shared_ptr<event> its_event = std::make_shared<event>(its_event_id, false); - its_event->groups_.push_back(its_eventgroup); - _service->events_[its_event_id] = its_event; - } - } - } - } - } - - if (its_eventgroup->id_ > 0) - _service->eventgroups_[its_eventgroup->id_] = its_eventgroup; - } - return is_loaded; + std::shared_ptr<service> &_service, + const boost::property_tree::ptree &_tree) { + bool is_loaded(true); + bool is_multicast; + for (auto i = _tree.begin(); i != _tree.end(); ++i) { + is_multicast = false; + std::shared_ptr<eventgroup> its_eventgroup = std::make_shared<eventgroup>(); + for (auto j = i->second.begin(); j != i->second.end(); ++j) { + std::string its_key(j->first); + if (its_key == "eventgroup") { + std::stringstream its_converter; + std::string its_value(j->second.data()); + if (its_value[0] == '0' && its_value[1] == 'x') { + its_converter << std::hex << its_value; + } else { + its_converter << std::dec << its_value; + } + its_converter >> its_eventgroup->id_; + } else if (its_key == "is_multicast") { + std::string its_value(j->second.data()); + is_multicast = (its_value == "true"); + } else if (its_key == "events") { + for (auto k = j->second.begin(); k != j->second.end(); ++k) { + std::stringstream its_converter; + std::string its_value(k->second.data()); + event_t its_event_id(0); + if (its_value[0] == '0' && its_value[1] == 'x') { + its_converter << std::hex << its_value; + } else { + its_converter << std::dec << its_value; + } + its_converter >> its_event_id; + if (0 < its_event_id) { + std::shared_ptr<event> its_event(nullptr); + auto find_event = _service->events_.find(its_event_id); + if (find_event != _service->events_.end()) { + its_event = find_event->second; + } else { + its_event = std::make_shared<event>(its_event_id, false); + } + if (its_event) { + its_event->groups_.push_back(its_eventgroup); + its_eventgroup->events_.insert(its_event); + _service->events_[its_event_id] = its_event; + } + } + } + } + } + + if (its_eventgroup->id_ > 0) { + if (is_multicast) { + _service->multicast_group_ = its_eventgroup->id_; + } + _service->eventgroups_[its_eventgroup->id_] = its_eventgroup; + } + } + return is_loaded; } bool configuration_impl::get_routing_configuration( - boost::property_tree::ptree &_tree) { - bool is_loaded(true); - try { - auto its_routing = _tree.get_child("routing"); - routing_host_ = its_routing.data(); - } catch (...) { - is_loaded = false; - } - return is_loaded; + boost::property_tree::ptree &_tree) { + bool is_loaded(true); + try { + auto its_routing = _tree.get_child("routing"); + routing_host_ = its_routing.data(); + } catch (...) { + is_loaded = false; + } + return is_loaded; } bool configuration_impl::get_service_discovery_configuration( - boost::property_tree::ptree &_tree) { - bool is_loaded(true); - try { - auto its_service_discovery = _tree.get_child("service-discovery"); - for (auto i = its_service_discovery.begin(); - i != its_service_discovery.end(); ++i) { - std::string its_key(i->first); - std::string its_value(i->second.data()); - if (its_key == "enable") { - is_service_discovery_enabled_ = (its_value == "true"); - } else if (its_key == "multicast") { - service_discovery_multicast_ = its_value; - } else if (its_key == "port") { - std::stringstream its_converter; - its_converter << its_value; - its_converter >> service_discovery_port_; - } else if (its_key == "protocol") { - service_discovery_protocol_ = its_value; - } - } - } catch (...) { - is_loaded = false; - } - - return is_loaded; + boost::property_tree::ptree &_tree) { + bool is_loaded(true); + try { + auto its_service_discovery = _tree.get_child("service-discovery"); + for (auto i = its_service_discovery.begin(); + i != its_service_discovery.end(); ++i) { + std::string its_key(i->first); + std::string its_value(i->second.data()); + if (its_key == "enable") { + is_service_discovery_enabled_ = (its_value == "true"); + } else if (its_key == "multicast") { + service_discovery_multicast_ = its_value; + } else if (its_key == "port") { + std::stringstream its_converter; + its_converter << its_value; + its_converter >> service_discovery_port_; + } else if (its_key == "protocol") { + service_discovery_protocol_ = its_value; + } + } + } catch (...) { + is_loaded = false; + } + + return is_loaded; } bool configuration_impl::get_applications_configuration( - boost::property_tree::ptree &_tree) { - bool is_loaded(true); - try { - std::stringstream its_converter; - auto its_applications = _tree.get_child("applications"); - for (auto i = its_applications.begin(); i != its_applications.end(); - ++i) - is_loaded = is_loaded && get_application_configuration(i->second); - } catch (...) { - is_loaded = false; - } + boost::property_tree::ptree &_tree) { + bool is_loaded(true); + try { + std::stringstream its_converter; + auto its_applications = _tree.get_child("applications"); + for (auto i = its_applications.begin(); i != its_applications.end(); ++i) + is_loaded = is_loaded && get_application_configuration(i->second); + } catch (...) { + is_loaded = false; + } - return is_loaded; + return is_loaded; } bool configuration_impl::get_application_configuration( - const boost::property_tree::ptree &_tree) { - bool is_loaded(true); - std::string its_name(""); - client_t its_id; - for (auto i = _tree.begin(); i != _tree.end(); ++i) { - std::string its_key(i->first); - std::string its_value(i->second.data()); - std::stringstream its_converter; - if (its_key == "name") { - its_name = its_value; - } else if (its_key == "id") { - if (its_value[0] == '0' && its_value[1] == 'x') { - its_converter << std::hex << its_value; - } else { - its_converter << std::dec << its_value; - } - its_converter >> its_id; - } - } - if (its_name != "" && its_id != 0) { - applications_[its_name] = its_id; - } - return is_loaded; + const boost::property_tree::ptree &_tree) { + bool is_loaded(true); + std::string its_name(""); + client_t its_id; + for (auto i = _tree.begin(); i != _tree.end(); ++i) { + std::string its_key(i->first); + std::string its_value(i->second.data()); + std::stringstream its_converter; + if (its_key == "name") { + its_name = its_value; + } else if (its_key == "id") { + if (its_value[0] == '0' && its_value[1] == 'x') { + its_converter << std::hex << its_value; + } else { + its_converter << std::dec << its_value; + } + its_converter >> its_id; + } + } + if (its_name != "" && its_id != 0) { + applications_[its_name] = its_id; + } + return is_loaded; } // Public interface const boost::asio::ip::address & configuration_impl::get_unicast() const { - return unicast_; + return unicast_; } bool configuration_impl::is_v4() const { - return unicast_.is_v4(); + return unicast_.is_v4(); } bool configuration_impl::is_v6() const { - return unicast_.is_v6(); + return unicast_.is_v6(); } bool configuration_impl::has_console_log() const { - return has_console_log_; + return has_console_log_; } bool configuration_impl::has_file_log() const { - return has_file_log_; + return has_file_log_; } bool configuration_impl::has_dlt_log() const { - return has_dlt_log_; + return has_dlt_log_; } const std::string & configuration_impl::get_logfile() const { - return logfile_; + return logfile_; } boost::log::trivial::severity_level configuration_impl::get_loglevel() const { - return loglevel_; + return loglevel_; } std::set<std::string> configuration_impl::get_servicegroups() const { - std::set < std::string > its_keys; - for (auto i : servicegroups_) - its_keys.insert(i.first); - return its_keys; + std::set < std::string > its_keys; + for (auto i : servicegroups_) + its_keys.insert(i.first); + return its_keys; } bool configuration_impl::is_local_servicegroup(const std::string &_name) const { - bool is_local(false); + bool is_local(false); - servicegroup *its_servicegroup = find_servicegroup(_name); - if (its_servicegroup) { - is_local = (its_servicegroup->unicast_ == "local" - || its_servicegroup->unicast_ == get_unicast().to_string()); - } + servicegroup *its_servicegroup = find_servicegroup(_name); + if (its_servicegroup) { + is_local = (its_servicegroup->unicast_ == "local" + || its_servicegroup->unicast_ == get_unicast().to_string()); + } - return is_local; + return is_local; } int32_t configuration_impl::get_min_initial_delay( - const std::string &_name) const { - int32_t its_delay = VSOMEIP_DEFAULT_MIN_INITIAL_DELAY; + const std::string &_name) const { + int32_t its_delay = VSOMEIP_DEFAULT_MIN_INITIAL_DELAY; - servicegroup *its_servicegroup = find_servicegroup(_name); - if (its_servicegroup) - its_delay = its_servicegroup->min_initial_delay_; + servicegroup *its_servicegroup = find_servicegroup(_name); + if (its_servicegroup) + its_delay = its_servicegroup->min_initial_delay_; - return its_delay; + return its_delay; } int32_t configuration_impl::get_max_initial_delay( - const std::string &_name) const { - int32_t its_delay = VSOMEIP_DEFAULT_MAX_INITIAL_DELAY; + const std::string &_name) const { + int32_t its_delay = VSOMEIP_DEFAULT_MAX_INITIAL_DELAY; - servicegroup *its_servicegroup = find_servicegroup(_name); - if (its_servicegroup) - its_delay = its_servicegroup->max_initial_delay_; + servicegroup *its_servicegroup = find_servicegroup(_name); + if (its_servicegroup) + its_delay = its_servicegroup->max_initial_delay_; - return its_delay; + return its_delay; } int32_t configuration_impl::get_repetition_base_delay( - const std::string &_name) const { - int32_t its_delay = VSOMEIP_DEFAULT_REPETITION_BASE_DELAY; + const std::string &_name) const { + int32_t its_delay = VSOMEIP_DEFAULT_REPETITION_BASE_DELAY; - servicegroup *its_servicegroup = find_servicegroup(_name); - if (its_servicegroup) - its_delay = its_servicegroup->repetition_base_delay_; + servicegroup *its_servicegroup = find_servicegroup(_name); + if (its_servicegroup) + its_delay = its_servicegroup->repetition_base_delay_; - return its_delay; + return its_delay; } uint8_t configuration_impl::get_repetition_max(const std::string &_name) const { - uint8_t its_max = VSOMEIP_DEFAULT_REPETITION_MAX; + uint8_t its_max = VSOMEIP_DEFAULT_REPETITION_MAX; - servicegroup *its_servicegroup = find_servicegroup(_name); - if (its_servicegroup) - its_max = its_servicegroup->repetition_max_; + servicegroup *its_servicegroup = find_servicegroup(_name); + if (its_servicegroup) + its_max = its_servicegroup->repetition_max_; - return its_max; + return its_max; } int32_t configuration_impl::get_cyclic_offer_delay( - const std::string &_name) const { - uint32_t its_delay = VSOMEIP_DEFAULT_CYCLIC_OFFER_DELAY; + const std::string &_name) const { + uint32_t its_delay = VSOMEIP_DEFAULT_CYCLIC_OFFER_DELAY; - servicegroup *its_servicegroup = find_servicegroup(_name); - if (its_servicegroup) - its_delay = its_servicegroup->cyclic_offer_delay_; + servicegroup *its_servicegroup = find_servicegroup(_name); + if (its_servicegroup) + its_delay = its_servicegroup->cyclic_offer_delay_; - return its_delay; + return its_delay; } int32_t configuration_impl::get_cyclic_request_delay( - const std::string &_name) const { - uint32_t its_delay = VSOMEIP_DEFAULT_CYCLIC_REQUEST_DELAY; + const std::string &_name) const { + uint32_t its_delay = VSOMEIP_DEFAULT_CYCLIC_REQUEST_DELAY; - servicegroup *its_servicegroup = find_servicegroup(_name); - if (its_servicegroup) - its_delay = its_servicegroup->cyclic_request_delay_; + servicegroup *its_servicegroup = find_servicegroup(_name); + if (its_servicegroup) + its_delay = its_servicegroup->cyclic_request_delay_; - return its_delay; + return its_delay; } std::string configuration_impl::get_group(service_t _service, - instance_t _instance) const { - std::string its_group("default"); - service *its_service = find_service(_service, _instance); - if (nullptr != its_service) { - its_group = its_service->group_->name_; - } - return its_group; -} - -std::string configuration_impl::get_address(service_t _service, - instance_t _instance) const { - std::string its_address(""); - - service *its_service = find_service(_service, _instance); - if (its_service) - its_address = its_service->group_->unicast_; - - return its_address; + instance_t _instance) const { + std::string its_group("default"); + service *its_service = find_service(_service, _instance); + if (nullptr != its_service) { + its_group = its_service->group_->name_; + } + return its_group; +} + +std::string configuration_impl::get_unicast(service_t _service, + instance_t _instance) const { + std::string its_unicast(""); + service *its_service = find_service(_service, _instance); + if (its_service) + its_unicast = its_service->group_->unicast_; + return its_unicast; +} + +std::string configuration_impl::get_multicast_address( + service_t _service, instance_t _instance) const { + std::string its_multicast_address(""); + service *its_service = find_service(_service, _instance); + if (its_service) + its_multicast_address = its_service->multicast_address_; + return its_multicast_address; +} + +uint16_t configuration_impl::get_multicast_port( + service_t _service, instance_t _instance) const { + uint16_t its_multicast_port(ILLEGAL_PORT); + service *its_service = find_service(_service, _instance); + if (its_service) + its_multicast_port = its_service->multicast_port_; + return its_multicast_port; +} + +uint16_t configuration_impl::get_multicast_group(service_t _service, + instance_t _instance) const { + uint16_t its_multicast_group(0xFFFF); + service *its_service = find_service(_service, _instance); + if (its_service) + its_multicast_group = its_service->multicast_group_; + return its_multicast_group; } uint16_t configuration_impl::get_reliable_port(service_t _service, - instance_t _instance) const { - uint16_t its_reliable = ILLEGAL_PORT; + instance_t _instance) const { + uint16_t its_reliable = ILLEGAL_PORT; - service *its_service = find_service(_service, _instance); - if (its_service) - its_reliable = its_service->reliable_; + service *its_service = find_service(_service, _instance); + if (its_service) + its_reliable = its_service->reliable_; - return its_reliable; + return its_reliable; } bool configuration_impl::has_enabled_magic_cookies(std::string _address, - uint16_t _port) const { - bool has_enabled(false); - auto find_address = magic_cookies_.find(_address); - if (find_address != magic_cookies_.end()) { - auto find_port = find_address->second.find(_port); - if (find_port != find_address->second.end()) { - has_enabled = true; - } - } - return has_enabled; + uint16_t _port) const { + bool has_enabled(false); + auto find_address = magic_cookies_.find(_address); + if (find_address != magic_cookies_.end()) { + auto find_port = find_address->second.find(_port); + if (find_port != find_address->second.end()) { + has_enabled = true; + } + } + return has_enabled; } uint16_t configuration_impl::get_unreliable_port(service_t _service, - instance_t _instance) const { - uint16_t its_unreliable = ILLEGAL_PORT; + instance_t _instance) const { + uint16_t its_unreliable = ILLEGAL_PORT; - service *its_service = find_service(_service, _instance); - if (its_service) - its_unreliable = its_service->unreliable_; + service *its_service = find_service(_service, _instance); + if (its_service) + its_unreliable = its_service->unreliable_; - return its_unreliable; + return its_unreliable; } const std::string & configuration_impl::get_routing_host() const { - return routing_host_; + return routing_host_; } bool configuration_impl::is_service_discovery_enabled() const { - return is_service_discovery_enabled_; + return is_service_discovery_enabled_; } const std::string & configuration_impl::get_service_discovery_protocol() const { - return service_discovery_protocol_; + return service_discovery_protocol_; } const std::string & configuration_impl::get_service_discovery_multicast() const { - return service_discovery_multicast_; + return service_discovery_multicast_; } uint16_t configuration_impl::get_service_discovery_port() const { - return service_discovery_port_; + return service_discovery_port_; } client_t configuration_impl::get_id(const std::string &_name) const { - client_t its_client = 0; + client_t its_client = 0; - auto found_application = applications_.find(_name); - if (found_application != applications_.end()) { - its_client = found_application->second; - } + auto found_application = applications_.find(_name); + if (found_application != applications_.end()) { + its_client = found_application->second; + } - return its_client; + return its_client; } std::set<std::pair<service_t, instance_t> > configuration_impl::get_remote_services() const { - std::set < std::pair<service_t, instance_t> > its_remote_services; - for (auto i : services_) { - for (auto j : i.second) { - if (j.second->group_->unicast_ != "local") - its_remote_services.insert(std::make_pair(i.first, j.first)); - } - } - return its_remote_services; + std::set < std::pair<service_t, instance_t> > its_remote_services; + for (auto i : services_) { + for (auto j : i.second) { + if (j.second->group_->unicast_ != "local") + its_remote_services.insert(std::make_pair(i.first, j.first)); + } + } + return its_remote_services; +} + +std::map<service_t, + std::map<instance_t, std::map<eventgroup_t, std::set<event_t> > > > configuration_impl::get_eventgroups() const { + std::map<service_t, + std::map<instance_t, std::map<eventgroup_t, std::set<event_t> > > > its_eventgroups; + for (auto i : services_) { + for (auto j : i.second) { + if (j.second->group_->unicast_ == "local") { + for (auto k : j.second->eventgroups_) { + for (auto l : k.second->events_) { + its_eventgroups[i.first][j.first][k.second->id_].insert(l->id_); + } + } + } + } + } + return its_eventgroups; +} + +std::map<service_t, std::map<instance_t, std::set<event_t> > > configuration_impl::get_events() const { + std::map<service_t, std::map<instance_t, std::set<event_t> > > its_events; + for (auto i : services_) { + for (auto j : i.second) { + if (j.second->group_->unicast_ == "local") { + for (auto k : j.second->events_) { + its_events[i.first][j.first].insert(k.first); + } + } + } + } + return its_events; +} + +void configuration_impl::set_event( + std::shared_ptr<vsomeip::event> &_event) const { + auto found_service = services_.find(_event->get_service()); + if (found_service != services_.end()) { + auto found_instance = found_service->second.find(_event->get_instance()); + if (found_instance != found_service->second.end()) { + auto found_event = found_instance->second->events_.find( + _event->get_event()); + if (found_event != found_instance->second->events_.end()) { + _event->set_field(found_event->second->is_field_); + } + } + } } servicegroup *configuration_impl::find_servicegroup( - const std::string &_name) const { - servicegroup *its_servicegroup(0); - auto find_servicegroup = servicegroups_.find(_name); - if (find_servicegroup != servicegroups_.end()) { - its_servicegroup = find_servicegroup->second.get(); - } - return its_servicegroup; + const std::string &_name) const { + servicegroup *its_servicegroup(0); + auto find_servicegroup = servicegroups_.find(_name); + if (find_servicegroup != servicegroups_.end()) { + its_servicegroup = find_servicegroup->second.get(); + } + return its_servicegroup; } service *configuration_impl::find_service(service_t _service, - instance_t _instance) const { - service *its_service(0); - auto find_service = services_.find(_service); - if (find_service != services_.end()) { - auto find_instance = find_service->second.find(_instance); - if (find_instance != find_service->second.end()) { - its_service = find_instance->second.get(); - } - } - return its_service; -} - -} // namespace config -} // namespace vsomeip + instance_t _instance) const { + service *its_service(0); + auto find_service = services_.find(_service); + if (find_service != services_.end()) { + auto find_instance = find_service->second.find(_instance); + if (find_instance != find_service->second.end()) { + its_service = find_instance->second.get(); + } + } + return its_service; +} + +} // namespace config +} // namespace vsomeip diff --git a/implementation/endpoints/include/client_endpoint_impl.hpp b/implementation/endpoints/include/client_endpoint_impl.hpp index f648484..f88ea93 100644 --- a/implementation/endpoints/include/client_endpoint_impl.hpp +++ b/implementation/endpoints/include/client_endpoint_impl.hpp @@ -38,6 +38,8 @@ public: virtual ~client_endpoint_impl();
bool send(const uint8_t *_data, uint32_t _size, bool _flush);
+ bool send_to(const boost::asio::ip::address &_address, uint16_t _port,
+ const byte_t *_data, uint32_t _size, bool _flush = true);
bool flush();
void stop();
diff --git a/implementation/endpoints/include/endpoint.hpp b/implementation/endpoints/include/endpoint.hpp index eb26b7f..f1e58aa 100644 --- a/implementation/endpoints/include/endpoint.hpp +++ b/implementation/endpoints/include/endpoint.hpp @@ -7,6 +7,8 @@ #ifndef VSOMEIP_ENDPOINT_HPP
#define VSOMEIP_ENDPOINT_HPP
+#include <boost/asio/ip/address.hpp>
+
#include <vsomeip/primitive_types.hpp>
namespace vsomeip {
@@ -22,19 +24,23 @@ public: virtual bool is_connected() const = 0;
virtual bool send(const byte_t *_data, uint32_t _size, bool _flush = true) = 0;
+ virtual bool send_to(const boost::asio::ip::address &_address, uint16_t _port,
+ const byte_t *_data, uint32_t _size, bool _flush = true) = 0;
virtual void enable_magic_cookies() = 0;
virtual void receive() = 0;
virtual void open_filter(service_t _service_id) = 0;
virtual void close_filter(service_t _service_id) = 0;
- virtual void join(const std::string &_multicast_address) = 0;
- virtual void leave(const std::string &_multicast_address) = 0;
+ virtual void join(const std::string &_address) = 0;
+ virtual void leave(const std::string &_address) = 0;
+
+ virtual void add_multicast(service_t _service, event_t _event,
+ const std::string &_address, uint16_t _port) = 0;
+ virtual void remove_multicast(service_t _service, event_t _event) = 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;
+ virtual bool is_reliable() const = 0;
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/endpoint_impl.hpp b/implementation/endpoints/include/endpoint_impl.hpp index 61d89bb..1be3474 100644 --- a/implementation/endpoints/include/endpoint_impl.hpp +++ b/implementation/endpoints/include/endpoint_impl.hpp @@ -33,12 +33,17 @@ public: void open_filter(service_t _service);
void close_filter(service_t _service);
+ // Dummy implementations as we only need these for UDP (servers)
+ // TODO: redesign
+ void join(const std::string &);
+ void leave(const std::string &);
+ void add_multicast(service_t, event_t, const std::string &, uint16_t);
+ void remove_multicast(service_t, event_t);
+
// Dummy implementations as we only need these for server endpoints
- // TODO: redesign to avoid dummy implementations
- bool get_address(ipv4_address_t &_address) const;
- bool get_address(ipv6_address_t &_address) const;
+ // TODO: redesign
unsigned short get_port() const;
- bool is_udp() const;
+ bool is_reliable() const;
public: // required
virtual bool is_client() const = 0;
diff --git a/implementation/endpoints/include/local_client_endpoint_impl.hpp b/implementation/endpoints/include/local_client_endpoint_impl.hpp index 04e91f2..d5abb92 100644 --- a/implementation/endpoints/include/local_client_endpoint_impl.hpp +++ b/implementation/endpoints/include/local_client_endpoint_impl.hpp @@ -30,9 +30,6 @@ public: void send_queued(message_buffer_ptr_t _data);
- void join(const std::string &);
- void leave(const std::string &);
-
private:
void send_magic_cookie();
diff --git a/implementation/endpoints/include/local_server_endpoint_impl.hpp b/implementation/endpoints/include/local_server_endpoint_impl.hpp index 1ed4721..11e26be 100644 --- a/implementation/endpoints/include/local_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/local_server_endpoint_impl.hpp @@ -38,12 +38,12 @@ public: void restart();
void receive();
+ bool send_to(const boost::asio::ip::address &_address, uint16_t _port,
+ const byte_t *_data, uint32_t _size, bool _flush);
void send_queued(endpoint_type _target, message_buffer_ptr_t _data);
- endpoint_type get_remote() const;
- endpoint_type get_cast() const;
- void join(const std::string &);
- void leave(const std::string &);
+ endpoint_type get_remote() const;
+ bool get_multicast(service_t, event_t, endpoint_type &) const;
private:
class connection
diff --git a/implementation/endpoints/include/server_endpoint_impl.hpp b/implementation/endpoints/include/server_endpoint_impl.hpp index 78a2e54..6d4b676 100644 --- a/implementation/endpoints/include/server_endpoint_impl.hpp +++ b/implementation/endpoints/include/server_endpoint_impl.hpp @@ -7,10 +7,10 @@ #ifndef VSOMEIP_SERVER_IMPL_HPP
#define VSOMEIP_SERVER_IMPL_HPP
-#include <deque>
#include <map>
#include <memory>
#include <mutex>
+#include <set>
#include <vector>
#include <boost/array.hpp>
@@ -21,47 +21,50 @@ namespace vsomeip {
-template < typename Protocol, int MaxBufferSize >
-class server_endpoint_impl
- : public endpoint_impl< MaxBufferSize >,
- public std::enable_shared_from_this< server_endpoint_impl<
- Protocol, MaxBufferSize > > {
-public:
- typedef typename Protocol::socket socket_type;
- typedef typename Protocol::endpoint endpoint_type;
- typedef boost::array< uint8_t, MaxBufferSize > buffer_type;
+template<typename Protocol, int MaxBufferSize>
+class server_endpoint_impl : public endpoint_impl<MaxBufferSize>,
+ public std::enable_shared_from_this<
+ server_endpoint_impl<Protocol, MaxBufferSize> > {
+ public:
+ typedef typename Protocol::socket socket_type;
+ typedef typename Protocol::endpoint endpoint_type;
+ typedef boost::array<uint8_t, MaxBufferSize> buffer_type;
- server_endpoint_impl(std::shared_ptr< endpoint_host > _host,
- endpoint_type _local, boost::asio::io_service &_io);
+ server_endpoint_impl(std::shared_ptr<endpoint_host> _host,
+ endpoint_type _local, boost::asio::io_service &_io);
- bool is_client() const;
- bool is_connected() const;
+ bool is_client() const;
+ bool is_connected() const;
- bool send(const uint8_t *_data, uint32_t _size, bool _flush);
- bool flush(endpoint_type _target);
+ bool send(const uint8_t *_data, uint32_t _size, bool _flush);
+ bool flush(endpoint_type _target);
-public:
- void connect_cbk(boost::system::error_code const &_error);
- void send_cbk(message_buffer_ptr_t _buffer,
- boost::system::error_code const &_error, std::size_t _bytes);
- void flush_cbk(endpoint_type _target, const boost::system::error_code &_error);
+ public:
+ void connect_cbk(boost::system::error_code const &_error);
+ void send_cbk(message_buffer_ptr_t _buffer,
+ boost::system::error_code const &_error, std::size_t _bytes);
+ void flush_cbk(endpoint_type _target,
+ const boost::system::error_code &_error);
-public:
- virtual void send_queued(endpoint_type _target, message_buffer_ptr_t _buffer) = 0;
- virtual endpoint_type get_remote() const = 0;
- virtual endpoint_type get_cast() const = 0;
+ public:
+ virtual bool send_intern(endpoint_type _target, const byte_t *_data, uint32_t _port, bool _flush);
+ virtual void send_queued(endpoint_type _target, message_buffer_ptr_t _buffer) = 0;
-protected:
- std::map< endpoint_type, message_buffer_ptr_t > packetizer_;
- std::map< client_t, std::map< session_t, endpoint_type > > clients_;
+ virtual endpoint_type get_remote() const = 0;
+ virtual bool get_multicast(service_t _service, event_t _event,
+ endpoint_type &_target) const = 0;
- boost::asio::system_timer flush_timer_;
+ protected:
+ std::map<endpoint_type, message_buffer_ptr_t> packetizer_;
+ std::map<client_t, std::map<session_t, endpoint_type> > clients_;
- endpoint_type local_;
+ boost::asio::system_timer flush_timer_;
- std::mutex mutex_;
+ endpoint_type local_;
+
+ std::mutex mutex_;
};
-} // namespace vsomeip
+} // namespace vsomeip
#endif // VSOMEIP_SERVICE_ENDPOINT_IMPL_HPP
diff --git a/implementation/endpoints/include/tcp_client_endpoint_impl.hpp b/implementation/endpoints/include/tcp_client_endpoint_impl.hpp index f3dd900..dc3f63d 100644 --- a/implementation/endpoints/include/tcp_client_endpoint_impl.hpp +++ b/implementation/endpoints/include/tcp_client_endpoint_impl.hpp @@ -28,8 +28,8 @@ public: void start();
void send_queued(message_buffer_ptr_t _buffer);
- void join(const std::string &);
- void leave(const std::string &);
+ unsigned short get_port() const;
+ bool is_reliable() const;
private:
bool is_magic_cookie() const;
diff --git a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp index 5085bbf..623634c 100644 --- a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp @@ -32,17 +32,15 @@ public: void start();
void stop();
+ bool send_to(const boost::asio::ip::address &_address, uint16_t _port,
+ const byte_t *_data, uint32_t _size, bool _flush);
void send_queued(endpoint_type _target, message_buffer_ptr_t _buffer);
- endpoint_type get_remote() const;
- endpoint_type get_cast() const;
- void join(const std::string &);
- void leave(const std::string &);
+ endpoint_type get_remote() const;
+ bool get_multicast(service_t, event_t, endpoint_type &) 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;
+ bool is_reliable() const;
// dummies to implement endpoint_impl interface
// TODO: think about a better design!
diff --git a/implementation/endpoints/include/udp_client_endpoint_impl.hpp b/implementation/endpoints/include/udp_client_endpoint_impl.hpp index 8918706..e0e348c 100644 --- a/implementation/endpoints/include/udp_client_endpoint_impl.hpp +++ b/implementation/endpoints/include/udp_client_endpoint_impl.hpp @@ -40,10 +40,13 @@ public: void start();
void send_queued(message_buffer_ptr_t _buffer);
- void join(const std::string &_multicast_address);
- void leave(const std::string &_multicast_address);
+ unsigned short get_port() const;
- void receive_cbk(packet_buffer_ptr_t _buffer, boost::system::error_code const &_error, std::size_t _bytes);
+ void join(const std::string &_address);
+ void leave(const std::string &_address);
+
+ void receive_cbk(packet_buffer_ptr_t _buffer,
+ boost::system::error_code const &_error, std::size_t _bytes);
private:
void connect();
diff --git a/implementation/endpoints/include/udp_server_endpoint_impl.hpp b/implementation/endpoints/include/udp_server_endpoint_impl.hpp index 4b8f3aa..da1a98a 100644 --- a/implementation/endpoints/include/udp_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/udp_server_endpoint_impl.hpp @@ -38,17 +38,20 @@ public: void restart();
void receive();
+ bool send_to(const boost::asio::ip::address &_address, uint16_t _port,
+ const byte_t *_data, uint32_t _size, bool _flush);
void send_queued(endpoint_type _target, message_buffer_ptr_t _buffer);
+
endpoint_type get_remote() const;
- endpoint_type get_cast() const;
+ bool get_multicast(service_t _service, event_t _event, endpoint_type &_target) const;
- void join(const std::string &_multicast_address);
- void leave(const std::string &_multicast_address);
+ void join(const std::string &_address);
+ void leave(const std::string &_address);
+ void add_multicast(service_t _service, instance_t _instance,
+ const std::string &_address, uint16_t _port);
+ void remove_multicast(service_t _service, instance_t _instance);
- 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;
public:
void receive_cbk(packet_buffer_ptr_t _buffer,
@@ -60,8 +63,7 @@ private: private:
socket_type socket_;
endpoint_type remote_;
- endpoint_type cast_;
-
+ std::map<service_t, std::map<instance_t, endpoint_type> > multicasts_;
message_buffer_t message_;
};
diff --git a/implementation/endpoints/src/client_endpoint_impl.cpp b/implementation/endpoints/src/client_endpoint_impl.cpp index b7de1be..ce16386 100644 --- a/implementation/endpoints/src/client_endpoint_impl.cpp +++ b/implementation/endpoints/src/client_endpoint_impl.cpp @@ -23,172 +23,177 @@ namespace vsomeip {
-template < typename Protocol, int MaxBufferSize >
-client_endpoint_impl< Protocol, MaxBufferSize >::client_endpoint_impl(
- std::shared_ptr< endpoint_host > _host,
- endpoint_type _remote,
- boost::asio::io_service &_io)
- : endpoint_impl< MaxBufferSize >(_host, _io),
- socket_(_io),
- connect_timer_(_io),
- flush_timer_(_io),
- remote_(_remote),
- packetizer_(std::make_shared< message_buffer_t >()),
- connect_timeout_(VSOMEIP_DEFAULT_CONNECT_TIMEOUT), // TODO: use config variable
- is_connected_(false) {
+template<typename Protocol, int MaxBufferSize>
+client_endpoint_impl<Protocol, MaxBufferSize>::client_endpoint_impl(
+ std::shared_ptr<endpoint_host> _host, endpoint_type _remote,
+ boost::asio::io_service &_io)
+ : endpoint_impl<MaxBufferSize>(_host, _io),
+ socket_(_io),
+ connect_timer_(_io),
+ flush_timer_(_io),
+ remote_(_remote),
+ packetizer_(std::make_shared<message_buffer_t>()),
+ connect_timeout_(VSOMEIP_DEFAULT_CONNECT_TIMEOUT), // TODO: use config variable
+ is_connected_(false) {
}
-template < typename Protocol, int MaxBufferSize >
-client_endpoint_impl< Protocol, MaxBufferSize >::~client_endpoint_impl() {
+template<typename Protocol, int MaxBufferSize>
+client_endpoint_impl<Protocol, MaxBufferSize>::~client_endpoint_impl() {
}
-template < typename Protocol, int MaxBufferSize >
-bool client_endpoint_impl< Protocol, MaxBufferSize >::is_client() const {
- return true;
+template<typename Protocol, int MaxBufferSize>
+bool client_endpoint_impl<Protocol, MaxBufferSize>::is_client() const {
+ return true;
}
-template < typename Protocol, int MaxBufferSize >
-bool client_endpoint_impl< Protocol, MaxBufferSize >::is_connected() const {
- return is_connected_;
+template<typename Protocol, int MaxBufferSize>
+bool client_endpoint_impl<Protocol, MaxBufferSize>::is_connected() const {
+ return is_connected_;
}
-template < typename Protocol, int MaxBufferSize >
-void client_endpoint_impl< Protocol, MaxBufferSize >::stop() {
- if (socket_.is_open()) {
- socket_.close();
- }
+template<typename Protocol, int MaxBufferSize>
+void client_endpoint_impl<Protocol, MaxBufferSize>::stop() {
+ if (socket_.is_open()) {
+ socket_.close();
+ }
}
-template < typename Protocol, int MaxBufferSize >
-void client_endpoint_impl< Protocol, MaxBufferSize >::restart() {
- receive();
+template<typename Protocol, int MaxBufferSize>
+void client_endpoint_impl<Protocol, MaxBufferSize>::restart() {
+ receive();
}
-template < typename Protocol, int MaxBufferSize >
-bool client_endpoint_impl< Protocol, MaxBufferSize >::send(
- const uint8_t *_data, uint32_t _size, bool _flush) {
- std::unique_lock< std::mutex > its_lock(mutex_);
+template<typename Protocol, int MaxBufferSize>
+bool client_endpoint_impl<Protocol, MaxBufferSize>::send_to(
+ const boost::asio::ip::address &_address, uint16_t _port,
+ const byte_t *_data, uint32_t _size, bool _flush) {
+ VSOMEIP_ERROR
+ << "Clients endpoints must not be used to send to explicitely specified targets";
+ return false;
+}
+
+template<typename Protocol, int MaxBufferSize>
+bool client_endpoint_impl<Protocol, MaxBufferSize>::send(const uint8_t *_data,
+ uint32_t _size,
+ bool _flush) {
+ std::unique_lock < std::mutex > its_lock(mutex_);
#if 0
- std::stringstream msg;
- msg << "cei<" << this << ">::send: ";
- for (uint32_t i = 0; i < _size; i++)
- msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ std::stringstream msg;
+ msg << "cei<" << this << ">::send: ";
+ for (uint32_t i = 0; i < _size; i++)
+ msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
- if (packetizer_->size() + _size > MaxBufferSize) {
- send_queued(packetizer_);
- packetizer_ = std::make_shared< message_buffer_t >();
- }
-
- packetizer_->insert(packetizer_->end(), _data, _data + _size);
-
- if (_flush) {
- flush_timer_.cancel();
- send_queued(packetizer_);
- packetizer_ = std::make_shared< message_buffer_t >();
- } else {
- flush_timer_.expires_from_now(
- std::chrono::milliseconds(VSOMEIP_DEFAULT_FLUSH_TIMEOUT)); // TODO: use config variable
- flush_timer_.async_wait(
- std::bind(
- &client_endpoint_impl<Protocol, MaxBufferSize>::flush_cbk,
- this->shared_from_this(),
- std::placeholders::_1
- )
- );
- }
-
- return true;
+ if (packetizer_->size() + _size > MaxBufferSize) {
+ send_queued(packetizer_);
+ packetizer_ = std::make_shared<message_buffer_t>();
+ }
+
+ packetizer_->insert(packetizer_->end(), _data, _data + _size);
+
+ if (_flush) {
+ flush_timer_.cancel();
+ send_queued(packetizer_);
+ packetizer_ = std::make_shared<message_buffer_t>();
+ } else {
+ flush_timer_.expires_from_now(
+ std::chrono::milliseconds(VSOMEIP_DEFAULT_FLUSH_TIMEOUT)); // TODO: use config variable
+ flush_timer_.async_wait(
+ std::bind(&client_endpoint_impl<Protocol, MaxBufferSize>::flush_cbk,
+ this->shared_from_this(), std::placeholders::_1));
+ }
+
+ return true;
}
-template < typename Protocol, int MaxBufferSize >
-bool client_endpoint_impl< Protocol, MaxBufferSize >::flush() {
- bool is_successful(true);
+template<typename Protocol, int MaxBufferSize>
+bool client_endpoint_impl<Protocol, MaxBufferSize>::flush() {
+ bool is_successful(true);
- if (!packetizer_->empty()) {
- send_queued(packetizer_);
- packetizer_ = std::make_shared< message_buffer_t >();
- } else {
- is_successful = false;
- }
+ if (!packetizer_->empty()) {
+ send_queued(packetizer_);
+ packetizer_ = std::make_shared<message_buffer_t>();
+ } else {
+ is_successful = false;
+ }
- return is_successful;
+ return is_successful;
}
-template < typename Protocol, int MaxBufferSize >
-void client_endpoint_impl< Protocol, MaxBufferSize >::connect_cbk(
- boost::system::error_code const &_error) {
- if (_error) {
- socket_.close();
-
- connect_timer_.expires_from_now(
- std::chrono::milliseconds(connect_timeout_));
- connect_timer_.async_wait(
- std::bind(
- &client_endpoint_impl<Protocol, MaxBufferSize>::wait_connect_cbk,
- this->shared_from_this(),
- std::placeholders::_1
- )
- );
-
- // next time we wait longer
- connect_timeout_ <<= 1;
-
- if (is_connected_) {
- is_connected_ = false;
- this->host_->on_disconnect(this->shared_from_this());
- }
- } else {
- connect_timer_.cancel();
- connect_timeout_ = VSOMEIP_DEFAULT_CONNECT_TIMEOUT; // TODO: use config variable
-
- if (!is_connected_) {
- is_connected_ = true;
- this->host_->on_connect(this->shared_from_this());
- }
-
- receive();
- }
+template<typename Protocol, int MaxBufferSize>
+void client_endpoint_impl<Protocol, MaxBufferSize>::connect_cbk(
+ boost::system::error_code const &_error) {
+ if (_error) {
+ socket_.close();
+
+ connect_timer_.expires_from_now(
+ std::chrono::milliseconds(connect_timeout_));
+ connect_timer_.async_wait(
+ std::bind(
+ &client_endpoint_impl<Protocol, MaxBufferSize>::wait_connect_cbk,
+ this->shared_from_this(), std::placeholders::_1));
+
+ // next time we wait longer
+ connect_timeout_ <<= 1;
+
+ if (is_connected_) {
+ is_connected_ = false;
+ this->host_->on_disconnect(this->shared_from_this());
+ }
+ } else {
+ connect_timer_.cancel();
+ connect_timeout_ = VSOMEIP_DEFAULT_CONNECT_TIMEOUT; // TODO: use config variable
+
+ if (!is_connected_) {
+ is_connected_ = true;
+ this->host_->on_connect(this->shared_from_this());
+ }
+
+ receive();
+ }
}
-template < typename Protocol, int MaxBufferSize >
-void client_endpoint_impl< Protocol, MaxBufferSize >::wait_connect_cbk(
- boost::system::error_code const &_error) {
- if (!_error) {
- connect();
- }
+template<typename Protocol, int MaxBufferSize>
+void client_endpoint_impl<Protocol, MaxBufferSize>::wait_connect_cbk(
+ boost::system::error_code const &_error) {
+ if (!_error) {
+ connect();
+ }
}
-template < typename Protocol, int MaxBufferSize >
-void client_endpoint_impl< Protocol, MaxBufferSize >::send_cbk(
- message_buffer_ptr_t _buffer,
- boost::system::error_code const &_error, std::size_t _bytes) {
+template<typename Protocol, int MaxBufferSize>
+void client_endpoint_impl<Protocol, MaxBufferSize>::send_cbk(
+ message_buffer_ptr_t _buffer, boost::system::error_code const &_error,
+ std::size_t _bytes) {
#if 0
- std::stringstream msg;
- msg << "cei<" << this << ">::scb (" << _error.message() << "): ";
- for (std::size_t i = 0; i < _data->size(); ++i)
- msg << std::hex << std::setw(2) << std::setfill('0') << (int)(*_buffer)[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ std::stringstream msg;
+ msg << "cei<" << this << ">::scb (" << _error.message() << "): ";
+ for (std::size_t i = 0; i < _data->size(); ++i)
+ msg << std::hex << std::setw(2) << std::setfill('0') << (int)(*_buffer)[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
- if (_error == boost::asio::error::broken_pipe) {
- is_connected_ = false;
- socket_.close();
- connect();
- }
+ if (_error == boost::asio::error::broken_pipe) {
+ is_connected_ = false;
+ socket_.close();
+ connect();
+ }
}
-template < typename Protocol, int MaxBufferSize >
-void client_endpoint_impl< Protocol, MaxBufferSize >::flush_cbk(
- boost::system::error_code const &_error) {
- if (!_error) {
- (void)flush();
- }
+template<typename Protocol, int MaxBufferSize>
+void client_endpoint_impl<Protocol, MaxBufferSize>::flush_cbk(
+ boost::system::error_code const &_error) {
+ if (!_error) {
+ (void) flush();
+ }
}
// Instantiate template
-template class client_endpoint_impl< boost::asio::local::stream_protocol, VSOMEIP_MAX_LOCAL_MESSAGE_SIZE >;
-template class client_endpoint_impl< boost::asio::ip::tcp, VSOMEIP_MAX_TCP_MESSAGE_SIZE >;
-template class client_endpoint_impl< boost::asio::ip::udp, VSOMEIP_MAX_UDP_MESSAGE_SIZE >;
-
-} // namespace vsomeip
+template class client_endpoint_impl<boost::asio::local::stream_protocol,
+ VSOMEIP_MAX_LOCAL_MESSAGE_SIZE> ;
+template class client_endpoint_impl<boost::asio::ip::tcp,
+ VSOMEIP_MAX_TCP_MESSAGE_SIZE> ;
+template class client_endpoint_impl<boost::asio::ip::udp,
+ VSOMEIP_MAX_UDP_MESSAGE_SIZE> ;
+
+} // namespace vsomeip
diff --git a/implementation/endpoints/src/endpoint_impl.cpp b/implementation/endpoints/src/endpoint_impl.cpp index 9972bba..e36ac95 100644 --- a/implementation/endpoints/src/endpoint_impl.cpp +++ b/implementation/endpoints/src/endpoint_impl.cpp @@ -10,7 +10,6 @@ #include "../include/endpoint_host.hpp"
#include "../include/endpoint_impl.hpp"
-#include "../../message/include/byteorder.hpp"
namespace vsomeip {
@@ -115,13 +114,20 @@ bool endpoint_impl< MaxBufferSize >::resync_on_magic_cookie(message_buffer_t &_b }
template < int MaxBufferSize >
-bool endpoint_impl< MaxBufferSize >::get_address(ipv4_address_t &_address) const {
- return false;
+void endpoint_impl< MaxBufferSize >::join(const std::string &) {
}
template < int MaxBufferSize >
-bool endpoint_impl< MaxBufferSize >::get_address(ipv6_address_t &_address) const {
- return false;
+void endpoint_impl< MaxBufferSize >::leave(const std::string &) {
+}
+
+template < int MaxBufferSize >
+void endpoint_impl< MaxBufferSize >::add_multicast(
+ service_t, event_t, const std::string &, uint16_t) {
+}
+
+template < int MaxBufferSize >
+void endpoint_impl< MaxBufferSize >::remove_multicast(service_t, event_t) {
}
template < int MaxBufferSize >
@@ -130,7 +136,7 @@ unsigned short endpoint_impl< MaxBufferSize >::get_port() const { }
template < int MaxBufferSize >
-bool endpoint_impl< MaxBufferSize >::is_udp() const {
+bool endpoint_impl< MaxBufferSize >::is_reliable() const {
return false;
}
diff --git a/implementation/endpoints/src/local_client_endpoint_impl.cpp b/implementation/endpoints/src/local_client_endpoint_impl.cpp index c1aba2f..747d5ec 100644 --- a/implementation/endpoints/src/local_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/local_client_endpoint_impl.cpp @@ -111,12 +111,6 @@ void local_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) { void local_client_endpoint_impl::send_magic_cookie() {
}
-void local_client_endpoint_impl::join(const std::string &) {
-}
-
-void local_client_endpoint_impl::leave(const std::string &) {
-}
-
void local_client_endpoint_impl::send_tag_cbk(
boost::system::error_code const &_error, std::size_t _bytes) {
}
diff --git a/implementation/endpoints/src/local_server_endpoint_impl.cpp b/implementation/endpoints/src/local_server_endpoint_impl.cpp index a6fb06e..5f2357f 100644 --- a/implementation/endpoints/src/local_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/local_server_endpoint_impl.cpp @@ -46,6 +46,11 @@ void local_server_endpoint_impl::stop() { }
+bool local_server_endpoint_impl::send_to(const boost::asio::ip::address &_address, uint16_t _port,
+ const byte_t *_data, uint32_t _size, bool _flush) {
+ return false;
+}
+
void local_server_endpoint_impl::send_queued(endpoint_type _target, message_buffer_ptr_t _buffer) {
auto connection_iterator = connections_.find(_target);
if (connection_iterator != connections_.end())
@@ -64,8 +69,9 @@ local_server_endpoint_impl::endpoint_type local_server_endpoint_impl::get_remote return current_->get_socket().remote_endpoint();
}
-local_server_endpoint_impl::endpoint_type local_server_endpoint_impl::get_cast() const {
- return get_remote(); // TODO: change inheritance to separate local from ip endpoints
+bool local_server_endpoint_impl::get_multicast(
+ service_t, event_t, local_server_endpoint_impl::endpoint_type &) const {
+ return false;
}
void local_server_endpoint_impl::remove_connection(local_server_endpoint_impl::connection *_connection) {
@@ -80,12 +86,6 @@ void local_server_endpoint_impl::remove_connection(local_server_endpoint_impl::c }
}
-void local_server_endpoint_impl::join(const std::string &) {
-}
-
-void local_server_endpoint_impl::leave(const std::string &) {
-}
-
void local_server_endpoint_impl::accept_cbk(
connection::ptr _connection, boost::system::error_code const &_error) {
diff --git a/implementation/endpoints/src/server_endpoint_impl.cpp b/implementation/endpoints/src/server_endpoint_impl.cpp index 6ad224a..65c5dab 100644 --- a/implementation/endpoints/src/server_endpoint_impl.cpp +++ b/implementation/endpoints/src/server_endpoint_impl.cpp @@ -17,148 +17,164 @@ #include "../include/server_endpoint_impl.hpp"
#include "../../configuration/include/internal.hpp"
+#include "../../utility/include/byteorder.hpp"
#include "../../utility/include/utility.hpp"
namespace vsomeip {
-template < typename Protocol, int MaxBufferSize >
-server_endpoint_impl< Protocol, MaxBufferSize >::server_endpoint_impl(
- std::shared_ptr< endpoint_host > _host, endpoint_type _local, boost::asio::io_service &_io)
- : endpoint_impl< MaxBufferSize >(_host, _io),
- flush_timer_(_io) {
+template<typename Protocol, int MaxBufferSize>
+server_endpoint_impl<Protocol, MaxBufferSize>::server_endpoint_impl(
+ std::shared_ptr<endpoint_host> _host, endpoint_type _local,
+ boost::asio::io_service &_io)
+ : endpoint_impl<MaxBufferSize>(_host, _io),
+ flush_timer_(_io) {
}
-template < typename Protocol, int MaxBufferSize >
-bool server_endpoint_impl< Protocol, MaxBufferSize >::is_client() const {
- return false;
+template<typename Protocol, int MaxBufferSize>
+bool server_endpoint_impl<Protocol, MaxBufferSize>::is_client() const {
+ return false;
}
-template < typename Protocol, int MaxBufferSize >
-bool server_endpoint_impl< Protocol, MaxBufferSize >::is_connected() const {
- return true;
+template<typename Protocol, int MaxBufferSize>
+bool server_endpoint_impl<Protocol, MaxBufferSize>::is_connected() const {
+ return true;
}
-template < typename Protocol, int MaxBufferSize >
-bool server_endpoint_impl< Protocol, MaxBufferSize >::send(
- const uint8_t *_data, uint32_t _size, bool _flush) {
+template<typename Protocol, int MaxBufferSize>
+bool server_endpoint_impl<Protocol, MaxBufferSize>::send(
+ const uint8_t *_data, uint32_t _size, bool _flush) {
#if 0
- std::stringstream msg;
- msg << "sei::send ";
- for (uint32_t i = 0; i < _size; i++)
- msg << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ std::stringstream msg;
+ msg << "sei::send ";
+ for (uint32_t i = 0; i < _size; i++)
+ msg << std::setw(2) << std::setfill('0') << (int)_data[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
+ endpoint_type its_target;
+ bool is_valid_target(false);
+
+ if (VSOMEIP_SESSION_POS_MAX < _size) {
+ std::unique_lock < std::mutex > its_lock(mutex_);
+
+ service_t its_service;
+ std::memcpy(&its_service, &_data[VSOMEIP_SERVICE_POS_MIN],
+ sizeof(service_t));
+
+ client_t its_client;
+ std::memcpy(&its_client, &_data[VSOMEIP_CLIENT_POS_MIN], sizeof(client_t));
+ session_t its_session;
+ std::memcpy(&its_session, &_data[VSOMEIP_SESSION_POS_MIN],
+ sizeof(session_t));
+
+ auto found_client = clients_.find(its_client);
+ if (found_client != clients_.end()) {
+ auto found_session = found_client->second.find(its_session);
+ if (found_session != found_client->second.end()) {
+ its_target = found_session->second;
+ is_valid_target = true;
+ }
+ } else {
+ event_t its_event = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_METHOD_POS_MIN],
+ _data[VSOMEIP_METHOD_POS_MAX]);
+ is_valid_target = get_multicast(its_service, its_event, its_target);
+ }
+
+ if (is_valid_target) {
+ is_valid_target = send_intern(its_target, _data, _size, _flush);
+ }
+ }
+ return is_valid_target;
+}
- endpoint_type its_target;
- bool is_valid_target(false);
-
- if (VSOMEIP_SESSION_POS_MAX < _size) {
- std::unique_lock< std::mutex > its_lock(mutex_);
-
- service_t its_service;
- std::memcpy(&its_service, &_data[VSOMEIP_SERVICE_POS_MIN], sizeof(service_t));
-
- client_t its_client;
- std::memcpy(&its_client, &_data[VSOMEIP_CLIENT_POS_MIN], sizeof(client_t));
- session_t its_session;
- std::memcpy(&its_session, &_data[VSOMEIP_SESSION_POS_MIN], sizeof(session_t));
-
- auto found_client = clients_.find(its_client);
- if (found_client != clients_.end()) {
- auto found_session = found_client->second.find(its_session);
- if (found_session != found_client->second.end()) {
- its_target = found_session->second;
- is_valid_target = true;
- }
- } else if (its_service == 0xFFFF) {
- its_target = get_cast();
- is_valid_target = true;
- }
-
- if (is_valid_target) {
- // find queue and packetizer (buffer)
- std::shared_ptr< std::vector< byte_t > > target_packetizer;
-
- auto found_packetizer = packetizer_.find(its_target);
- if (found_packetizer != packetizer_.end()) {
- target_packetizer = found_packetizer->second;
- } else {
- target_packetizer = std::make_shared< message_buffer_t >();
- packetizer_.insert(std::make_pair(its_target, target_packetizer));
- }
-
- if (target_packetizer->size() + _size > MaxBufferSize) {
- send_queued(its_target, target_packetizer);
- packetizer_[its_target] = std::make_shared< message_buffer_t >();
- }
-
- target_packetizer->insert(target_packetizer->end(), _data, _data + _size);
-
- if (_flush) {
- flush_timer_.cancel();
- send_queued(its_target, target_packetizer);
- packetizer_[its_target] = std::make_shared< message_buffer_t >();
- } else {
- std::chrono::milliseconds flush_timeout(VSOMEIP_DEFAULT_FLUSH_TIMEOUT);
- flush_timer_.expires_from_now(flush_timeout); // TODO: use configured value
- flush_timer_.async_wait(
- std::bind(
- &server_endpoint_impl<Protocol, MaxBufferSize>::flush_cbk,
- this->shared_from_this(),
- its_target,
- std::placeholders::_1
- )
- );
- }
- }
- }
-
- return is_valid_target;
+template<typename Protocol, int MaxBufferSize>
+bool server_endpoint_impl<Protocol, MaxBufferSize>::send_intern(endpoint_type _target,
+ const byte_t *_data, uint32_t _size, bool _flush) {
+
+ std::shared_ptr < std::vector<byte_t> > target_packetizer;
+ auto found_packetizer = packetizer_.find(_target);
+ if (found_packetizer != packetizer_.end()) {
+ target_packetizer = found_packetizer->second;
+ } else {
+ target_packetizer = std::make_shared<message_buffer_t>();
+ packetizer_.insert(
+ std::make_pair(_target, target_packetizer));
+ }
+
+ if (target_packetizer->size() + _size > MaxBufferSize) {
+ send_queued(_target, target_packetizer);
+ packetizer_[_target] = std::make_shared<message_buffer_t>();
+ }
+
+ target_packetizer->insert(
+ target_packetizer->end(), _data, _data + _size);
+
+ if (_flush) {
+ flush_timer_.cancel();
+ send_queued(_target, target_packetizer);
+ packetizer_[_target] = std::make_shared<message_buffer_t>();
+ } else {
+ std::chrono::milliseconds flush_timeout(VSOMEIP_DEFAULT_FLUSH_TIMEOUT);
+ flush_timer_.expires_from_now(flush_timeout); // TODO: use configured value
+ flush_timer_.async_wait(
+ std::bind(
+ &server_endpoint_impl<Protocol, MaxBufferSize>::flush_cbk,
+ this->shared_from_this(), _target,
+ std::placeholders::_1));
+ }
+ return true;
}
-template < typename Protocol, int MaxBufferSize >
-bool server_endpoint_impl< Protocol, MaxBufferSize >::flush(endpoint_type _target) {
- bool is_flushed = false;
- std::unique_lock< std::mutex > its_lock(mutex_);
- auto i = packetizer_.find(_target);
- if (i != packetizer_.end() && !i->second->empty()) {
- send_queued(_target, i->second);
- i->second = std::make_shared< message_buffer_t >();
- is_flushed = true;
- }
-
- return is_flushed;
+template<typename Protocol, int MaxBufferSize>
+bool server_endpoint_impl<Protocol, MaxBufferSize>::flush(
+ endpoint_type _target) {
+ bool is_flushed = false;
+ std::unique_lock < std::mutex > its_lock(mutex_);
+ auto i = packetizer_.find(_target);
+ if (i != packetizer_.end() && !i->second->empty()) {
+ send_queued(_target, i->second);
+ i->second = std::make_shared<message_buffer_t>();
+ is_flushed = true;
+ }
+
+ return is_flushed;
}
-template < typename Protocol, int MaxBufferSize >
-void server_endpoint_impl< Protocol, MaxBufferSize >::connect_cbk(
- boost::system::error_code const &_error) {
+template<typename Protocol, int MaxBufferSize>
+void server_endpoint_impl<Protocol, MaxBufferSize>::connect_cbk(
+ boost::system::error_code const &_error) {
}
-template < typename Protocol, int MaxBufferSize >
-void server_endpoint_impl< Protocol, MaxBufferSize >::send_cbk(
- message_buffer_ptr_t _buffer,
- boost::system::error_code const &_error, std::size_t _bytes) {
+template<typename Protocol, int MaxBufferSize>
+void server_endpoint_impl<Protocol, MaxBufferSize>::send_cbk(
+ message_buffer_ptr_t _buffer, boost::system::error_code const &_error,
+ std::size_t _bytes) {
#if 0
- std::stringstream msg;
- msg << "sei::scb (" << _error.message() << "): ";
- for (std::size_t i = 0; i < _buffer->size(); ++i)
- msg << std::hex << std::setw(2) << std::setfill('0') << (int)(*_buffer)[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+std::stringstream msg;
+msg << "sei::scb (" << _error.message() << "): ";
+for (std::size_t i = 0; i < _buffer->size(); ++i)
+msg << std::hex << std::setw(2) << std::setfill('0') << (int)(*_buffer)[i] << " ";
+VSOMEIP_DEBUG << msg.str();
#endif
}
-template < typename Protocol, int MaxBufferSize >
-void server_endpoint_impl< Protocol, MaxBufferSize >::flush_cbk(
- endpoint_type _target, const boost::system::error_code &_error_code) {
- if (!_error_code) {
- (void)flush(_target);
- }
+template<typename Protocol, int MaxBufferSize>
+void server_endpoint_impl<Protocol, MaxBufferSize>::flush_cbk(
+ endpoint_type _target, const boost::system::error_code &_error_code) {
+if (!_error_code) {
+ (void) flush(_target);
+}
}
// Instantiate template
-template class server_endpoint_impl< boost::asio::local::stream_protocol, VSOMEIP_MAX_LOCAL_MESSAGE_SIZE >;
-template class server_endpoint_impl< boost::asio::ip::tcp, VSOMEIP_MAX_TCP_MESSAGE_SIZE >;
-template class server_endpoint_impl< boost::asio::ip::udp, VSOMEIP_MAX_UDP_MESSAGE_SIZE >;
+#ifndef __WINDOWS__
+template class server_endpoint_impl<boost::asio::local::stream_protocol,
+VSOMEIP_MAX_LOCAL_MESSAGE_SIZE> ;
+#else
+// TODO: put instantiation for windows here!
+#endif
+template class server_endpoint_impl<boost::asio::ip::tcp,
+VSOMEIP_MAX_TCP_MESSAGE_SIZE> ;
+template class server_endpoint_impl<boost::asio::ip::udp,
+VSOMEIP_MAX_UDP_MESSAGE_SIZE> ;
-} // namespace vsomeip
+} // namespace vsomeip
diff --git a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp index 4786d44..2f44baf 100644 --- a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp @@ -82,6 +82,14 @@ void tcp_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) { );
}
+unsigned short tcp_client_endpoint_impl::get_port() const {
+ return socket_.local_endpoint().port();
+}
+
+bool tcp_client_endpoint_impl::is_reliable() const {
+ return true;
+}
+
bool tcp_client_endpoint_impl::is_magic_cookie() const {
return (0 == std::memcmp(SERVICE_COOKIE, &message_[0], sizeof(SERVICE_COOKIE)));
}
@@ -99,12 +107,6 @@ void tcp_client_endpoint_impl::send_magic_cookie(message_buffer_ptr_t &_buffer) }
}
-void tcp_client_endpoint_impl::join(const std::string &) {
-}
-
-void tcp_client_endpoint_impl::leave(const std::string &) {
-}
-
void tcp_client_endpoint_impl::receive_cbk(
packet_buffer_ptr_t _buffer,
boost::system::error_code const &_error, std::size_t _bytes) {
diff --git a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp index 9d2879a..616f273 100644 --- a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp @@ -20,213 +20,194 @@ namespace ip = boost::asio::ip; namespace vsomeip {
tcp_server_endpoint_impl::tcp_server_endpoint_impl(
- std::shared_ptr< endpoint_host > _host, endpoint_type _local, boost::asio::io_service &_io)
- : tcp_server_endpoint_base_impl(_host, _local, _io),
- acceptor_(_io, _local), current_(0) {
- is_supporting_magic_cookies_ = true;
+ std::shared_ptr<endpoint_host> _host, endpoint_type _local,
+ boost::asio::io_service &_io)
+ : tcp_server_endpoint_base_impl(_host, _local, _io),
+ acceptor_(_io, _local),
+ current_(0) {
+ is_supporting_magic_cookies_ = true;
}
tcp_server_endpoint_impl::~tcp_server_endpoint_impl() {
}
void tcp_server_endpoint_impl::start() {
- connection::ptr new_connection = connection::create(this);
+ connection::ptr new_connection = connection::create(this);
- acceptor_.async_accept(
- new_connection->get_socket(),
- std::bind(
- &tcp_server_endpoint_impl::accept_cbk,
- std::dynamic_pointer_cast< tcp_server_endpoint_impl >(shared_from_this()),
- new_connection,
- std::placeholders::_1
- )
- );
+ acceptor_.async_accept(
+ new_connection->get_socket(),
+ std::bind(
+ &tcp_server_endpoint_impl::accept_cbk,
+ std::dynamic_pointer_cast < tcp_server_endpoint_impl
+ > (shared_from_this()),
+ new_connection, std::placeholders::_1));
}
void tcp_server_endpoint_impl::stop() {
- for (auto& i : connections_)
- i.second->stop();
- acceptor_.close();
+ for (auto& i : connections_)
+ i.second->stop();
+ acceptor_.close();
}
-void tcp_server_endpoint_impl::send_queued(endpoint_type _target, message_buffer_ptr_t _buffer) {
- auto connection_iterator = connections_.find(_target);
- if (connection_iterator != connections_.end())
- connection_iterator->second->send_queued(_buffer);
+bool tcp_server_endpoint_impl::send_to(
+ const boost::asio::ip::address &_address, uint16_t _port,
+ const byte_t *_data, uint32_t _size, bool _flush) {
+ endpoint_type its_target(_address, _port);
+ return send_intern(its_target, _data, _size, _flush);
}
-tcp_server_endpoint_impl::endpoint_type tcp_server_endpoint_impl::get_remote() const {
- return current_->get_socket().remote_endpoint();
+void tcp_server_endpoint_impl::send_queued(endpoint_type _target,
+ message_buffer_ptr_t _buffer) {
+ auto connection_iterator = connections_.find(_target);
+ if (connection_iterator != connections_.end())
+ connection_iterator->second->send_queued(_buffer);
}
-tcp_server_endpoint_impl::endpoint_type tcp_server_endpoint_impl::get_cast() const {
- return get_remote();
+tcp_server_endpoint_impl::endpoint_type tcp_server_endpoint_impl::get_remote() const {
+ return current_->get_socket().remote_endpoint();
}
-void tcp_server_endpoint_impl::accept_cbk(
- connection::ptr _connection, boost::system::error_code const &_error) {
-
- if (!_error) {
- socket_type &new_connection_socket = _connection->get_socket();
- endpoint_type remote = new_connection_socket.remote_endpoint();
-
- connections_[remote] = _connection;
- _connection->start();
- }
-
- start();
+bool tcp_server_endpoint_impl::get_multicast(
+ service_t, event_t, tcp_server_endpoint_impl::endpoint_type &) const {
+ return false;
}
-void tcp_server_endpoint_impl::join(const std::string &) {
-}
+void tcp_server_endpoint_impl::accept_cbk(
+ connection::ptr _connection, boost::system::error_code const &_error) {
-void tcp_server_endpoint_impl::leave(const std::string &) {
-}
+ if (!_error) {
+ socket_type &new_connection_socket = _connection->get_socket();
+ endpoint_type remote = new_connection_socket.remote_endpoint();
-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;
-}
+ connections_[remote] = _connection;
+ _connection->start();
+ }
-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_v6()) {
- _address = its_address.to_v6().to_bytes();
- } else {
- return false;
- }
- return true;
+ start();
}
unsigned short tcp_server_endpoint_impl::get_port() const {
- return acceptor_.local_endpoint().port();
+ return acceptor_.local_endpoint().port();
}
-bool tcp_server_endpoint_impl::is_udp() const {
- return false;
+bool tcp_server_endpoint_impl::is_reliable() const {
+ return true;
}
///////////////////////////////////////////////////////////////////////////////
// class tcp_service_impl::connection
///////////////////////////////////////////////////////////////////////////////
-tcp_server_endpoint_impl::connection::connection(tcp_server_endpoint_impl *_server)
- : socket_(_server->service_), server_(_server) {
+tcp_server_endpoint_impl::connection::connection(
+ tcp_server_endpoint_impl *_server)
+ : socket_(_server->service_),
+ server_(_server) {
}
-tcp_server_endpoint_impl::connection::ptr
-tcp_server_endpoint_impl::connection::create(tcp_server_endpoint_impl *_server) {
- return ptr(new connection(_server));
+tcp_server_endpoint_impl::connection::ptr tcp_server_endpoint_impl::connection::create(
+ tcp_server_endpoint_impl *_server) {
+ return ptr(new connection(_server));
}
tcp_server_endpoint_impl::socket_type & tcp_server_endpoint_impl::connection::get_socket() {
- return socket_;
+ return socket_;
}
void tcp_server_endpoint_impl::connection::start() {
- packet_buffer_ptr_t its_buffer
- = std::make_shared< packet_buffer_t >();
- socket_.async_receive(
- boost::asio::buffer(*its_buffer),
- std::bind(
- &tcp_server_endpoint_impl::connection::receive_cbk,
- shared_from_this(),
- its_buffer,
- std::placeholders::_1,
- std::placeholders::_2
- )
- );
+ packet_buffer_ptr_t its_buffer = std::make_shared<packet_buffer_t>();
+ socket_.async_receive(
+ boost::asio::buffer(*its_buffer),
+ std::bind(&tcp_server_endpoint_impl::connection::receive_cbk,
+ shared_from_this(), its_buffer, std::placeholders::_1,
+ std::placeholders::_2));
}
void tcp_server_endpoint_impl::connection::stop() {
- socket_.close();
+ socket_.close();
}
-void tcp_server_endpoint_impl::connection::send_queued(message_buffer_ptr_t _buffer) {
- if (server_->has_enabled_magic_cookies_)
- send_magic_cookie(_buffer);
+void tcp_server_endpoint_impl::connection::send_queued(
+ message_buffer_ptr_t _buffer) {
+ if (server_->has_enabled_magic_cookies_)
+ send_magic_cookie(_buffer);
- boost::asio::async_write(
- socket_,
- boost::asio::buffer(*_buffer),
- std::bind(
- &tcp_server_endpoint_base_impl::send_cbk,
- server_->shared_from_this(),
- _buffer,
- std::placeholders::_1,
- std::placeholders::_2
- )
- );
+ boost::asio::async_write(
+ socket_,
+ boost::asio::buffer(*_buffer),
+ std::bind(&tcp_server_endpoint_base_impl::send_cbk,
+ server_->shared_from_this(), _buffer, std::placeholders::_1,
+ std::placeholders::_2));
}
-void tcp_server_endpoint_impl::connection::send_magic_cookie(message_buffer_ptr_t &_buffer) {
- if (VSOMEIP_MAX_TCP_MESSAGE_SIZE - _buffer->size() >=
- VSOMEIP_SOMEIP_HEADER_SIZE + VSOMEIP_SOMEIP_MAGIC_COOKIE_SIZE) {
- _buffer->insert(
- _buffer->begin(),
- SERVICE_COOKIE,
- SERVICE_COOKIE + sizeof(SERVICE_COOKIE)
- );
- }
+void tcp_server_endpoint_impl::connection::send_magic_cookie(
+ message_buffer_ptr_t &_buffer) {
+ if (VSOMEIP_MAX_TCP_MESSAGE_SIZE - _buffer->size() >=
+ VSOMEIP_SOMEIP_HEADER_SIZE + VSOMEIP_SOMEIP_MAGIC_COOKIE_SIZE) {
+ _buffer->insert(_buffer->begin(), SERVICE_COOKIE,
+ SERVICE_COOKIE + sizeof(SERVICE_COOKIE));
+ }
}
bool tcp_server_endpoint_impl::connection::is_magic_cookie() const {
- return (0 == std::memcmp(CLIENT_COOKIE, &message_[0], sizeof(CLIENT_COOKIE)));
+ return (0 == std::memcmp(CLIENT_COOKIE, &message_[0], sizeof(CLIENT_COOKIE)));
}
void tcp_server_endpoint_impl::connection::receive_cbk(
- packet_buffer_ptr_t _buffer,
- boost::system::error_code const &_error, std::size_t _bytes) {
+ packet_buffer_ptr_t _buffer, boost::system::error_code const &_error,
+ std::size_t _bytes) {
#if 0
- std::stringstream msg;
- for (std::size_t i = 0; i < _bytes; ++i)
- msg << std::hex << std::setw(2) << std::setfill('0') << (int)(*_buffer))[i] << " ";
- VSOMEIP_DEBUG << msg.str();
+ std::stringstream msg;
+ for (std::size_t i = 0; i < _bytes; ++i)
+ msg << std::hex << std::setw(2) << std::setfill('0') << (int)(*_buffer))[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
- if (!_error && 0 < _bytes) {
- message_.insert(message_.end(), _buffer->begin(), _buffer->begin() + _bytes);
-
- bool has_full_message;
- do {
- uint32_t current_message_size = utility::get_message_size(message_);
- has_full_message = (current_message_size > 0 && current_message_size <= message_.size());
- if (has_full_message) {
- if (is_magic_cookie()) {
- server_->has_enabled_magic_cookies_ = true;
- } else {
- if (utility::is_request(message_[VSOMEIP_MESSAGE_TYPE_POS])) {
- client_t its_client;
- std::memcpy(&its_client, &message_[VSOMEIP_CLIENT_POS_MIN], sizeof(client_t));
- session_t its_session;
- std::memcpy(&its_session, &message_[VSOMEIP_SESSION_POS_MIN], sizeof(session_t));
- server_->clients_[its_client][its_session] = socket_.remote_endpoint();
- }
- server_->host_->on_message(&message_[0], current_message_size, server_);
- }
- message_.erase(message_.begin(), message_.begin() + current_message_size);
- } else if (server_->has_enabled_magic_cookies_ && message_.size() > 0){
- has_full_message = server_->resync_on_magic_cookie(message_);
- } else if (message_.size() > VSOMEIP_MAX_TCP_MESSAGE_SIZE) {
- VSOMEIP_ERROR << "Message exceeds maximum message size. Resetting receiver.";
- message_.clear();
- }
- } while (has_full_message);
-
- start();
- }
+ if (!_error && 0 < _bytes) {
+ message_.insert(message_.end(), _buffer->begin(),
+ _buffer->begin() + _bytes);
+
+ bool has_full_message;
+ do {
+ uint32_t current_message_size = utility::get_message_size(message_);
+ has_full_message = (current_message_size > 0
+ && current_message_size <= message_.size());
+ if (has_full_message) {
+ if (is_magic_cookie()) {
+ server_->has_enabled_magic_cookies_ = true;
+ } else {
+ if (utility::is_request(message_[VSOMEIP_MESSAGE_TYPE_POS])) {
+ client_t its_client;
+ std::memcpy(&its_client, &message_[VSOMEIP_CLIENT_POS_MIN],
+ sizeof(client_t));
+ session_t its_session;
+ std::memcpy(&its_session, &message_[VSOMEIP_SESSION_POS_MIN],
+ sizeof(session_t));
+ server_->clients_[its_client][its_session] =
+ socket_.remote_endpoint();
+ }
+ server_->host_->on_message(&message_[0], current_message_size,
+ server_);
+ }
+ message_.erase(message_.begin(),
+ message_.begin() + current_message_size);
+ } else if (server_->has_enabled_magic_cookies_ && message_.size() > 0) {
+ has_full_message = server_->resync_on_magic_cookie(message_);
+ } else if (message_.size() > VSOMEIP_MAX_TCP_MESSAGE_SIZE) {
+ VSOMEIP_ERROR
+ << "Message exceeds maximum message size. Resetting receiver.";
+ message_.clear();
+ }
+ } while (has_full_message);
+
+ start();
+ }
}
// Dummies
void tcp_server_endpoint_impl::receive() {
- // intentionally left empty
+ // intentionally left empty
}
void tcp_server_endpoint_impl::restart() {
- // intentionally left empty
+ // intentionally left empty
}
-} // namespace vsomeip
+} // namespace vsomeip
diff --git a/implementation/endpoints/src/udp_client_endpoint_impl.cpp b/implementation/endpoints/src/udp_client_endpoint_impl.cpp index c57ac82..585b056 100644 --- a/implementation/endpoints/src/udp_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/udp_client_endpoint_impl.cpp @@ -79,30 +79,33 @@ void udp_client_endpoint_impl::receive() { );
}
-void udp_client_endpoint_impl::join(const std::string &_multicast_address) {
+unsigned short udp_client_endpoint_impl::get_port() const {
+ return socket_.local_endpoint().port();
+}
+
+void udp_client_endpoint_impl::join(const std::string &_address) {
+
if (remote_.address().is_v4()) {
try {
socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
socket_.set_option(boost::asio::ip::multicast::join_group(
- boost::asio::ip::address::from_string(_multicast_address)));
+ boost::asio::ip::address::from_string(_address)));
}
catch (...) {
-
}
} else {
// TODO: support multicast for IPv6
}
}
-void udp_client_endpoint_impl::leave(const std::string &_multicast_address) {
+void udp_client_endpoint_impl::leave(const std::string &_address) {
if (remote_.address().is_v4()) {
try {
socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
socket_.set_option(boost::asio::ip::multicast::leave_group(
- boost::asio::ip::address::from_string(_multicast_address)));
+ boost::asio::ip::address::from_string(_address)));
}
catch (...) {
-
}
} else {
// TODO: support multicast for IPv6
@@ -112,11 +115,10 @@ void udp_client_endpoint_impl::leave(const std::string &_multicast_address) { void udp_client_endpoint_impl::receive_cbk(
packet_buffer_ptr_t _buffer,
boost::system::error_code const &_error, std::size_t _bytes) {
-
if (!_error && 0 < _bytes) {
#if 0
std::stringstream msg;
- msg << "cei::rcb (" << _error.message() << "): ";
+ msg << "ucei::rcb(" << _error.message() << "): ";
for (std::size_t i = 0; i < _bytes; ++i)
msg << std::hex << std::setw(2) << std::setfill('0') << (int)(*_buffer)[i] << " ";
VSOMEIP_DEBUG << msg.str();
@@ -133,11 +135,9 @@ void udp_client_endpoint_impl::receive_cbk( this->message_.erase(this->message_.begin(), this->message_.begin() + current_message_size);
}
} while (has_full_message);
-
- restart();
- } else {
- receive();
}
+
+ receive();
}
} // namespace vsomeip
diff --git a/implementation/endpoints/src/udp_server_endpoint_impl.cpp b/implementation/endpoints/src/udp_server_endpoint_impl.cpp index 53df320..b63c3a5 100644 --- a/implementation/endpoints/src/udp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/udp_server_endpoint_impl.cpp @@ -14,7 +14,7 @@ #include "../include/endpoint_host.hpp"
#include "../include/udp_server_endpoint_impl.hpp"
-#include "../../message/include/byteorder.hpp"
+#include "../../utility/include/byteorder.hpp"
#include "../../utility/include/utility.hpp"
namespace ip = boost::asio::ip;
@@ -24,8 +24,7 @@ namespace vsomeip { udp_server_endpoint_impl::udp_server_endpoint_impl(
std::shared_ptr< endpoint_host > _host, endpoint_type _local, boost::asio::io_service &_io)
: server_endpoint_impl< ip::udp, VSOMEIP_MAX_UDP_MESSAGE_SIZE >(_host, _local, _io),
- socket_(_io, _local),
- cast_(_local) {
+ socket_(_io, _local) {
boost::asio::socket_base::broadcast option(true);
socket_.set_option(option);
}
@@ -38,6 +37,8 @@ void udp_server_endpoint_impl::start() { }
void udp_server_endpoint_impl::stop() {
+ if (socket_.is_open())
+ socket_.close();
}
void udp_server_endpoint_impl::receive() {
@@ -61,6 +62,13 @@ void udp_server_endpoint_impl::restart() { receive();
}
+bool udp_server_endpoint_impl::send_to(
+ const boost::asio::ip::address &_address, uint16_t _port,
+ const byte_t *_data, uint32_t _size, bool _flush) {
+ endpoint_type its_target(_address, _port);
+ return send_intern(its_target, _data, _size, _flush);
+}
+
void udp_server_endpoint_impl::send_queued(endpoint_type _target, message_buffer_ptr_t _buffer) {
#if 0
std::stringstream msg;
@@ -86,18 +94,27 @@ udp_server_endpoint_impl::endpoint_type udp_server_endpoint_impl::get_remote() c return remote_;
}
-udp_server_endpoint_impl::endpoint_type udp_server_endpoint_impl::get_cast() const {
- return cast_;
+bool udp_server_endpoint_impl::get_multicast(service_t _service, event_t _event,
+ udp_server_endpoint_impl::endpoint_type &_target) const {
+ bool is_valid(false);
+ auto find_service = multicasts_.find(_service);
+ if (find_service != multicasts_.end()) {
+ auto find_event = find_service->second.find(_event);
+ if (find_event != find_service->second.end()) {
+ _target = find_event->second;
+ is_valid = true;
+ }
+ }
+ return is_valid;
}
-void udp_server_endpoint_impl::join(const std::string &_multicast_address) {
+void udp_server_endpoint_impl::join(const std::string &_address) {
if (local_.address().is_v4()) {
try {
- cast_.address(boost::asio::ip::address::from_string(_multicast_address));
socket_.set_option(boost::asio::ip::udp::socket::reuse_address(true));
socket_.set_option(boost::asio::ip::multicast::enable_loopback(false));
socket_.set_option(boost::asio::ip::multicast::join_group(
- boost::asio::ip::address::from_string(_multicast_address).to_v4()));
+ boost::asio::ip::address::from_string(_address).to_v4()));
}
catch (const std::exception &e) {
VSOMEIP_ERROR << e.what();
@@ -107,12 +124,11 @@ void udp_server_endpoint_impl::join(const std::string &_multicast_address) { }
}
-void udp_server_endpoint_impl::leave(const std::string &_multicast_address) {
+void udp_server_endpoint_impl::leave(const std::string &_address) {
if (local_.address().is_v4()) {
try {
socket_.set_option(boost::asio::ip::multicast::leave_group(
- boost::asio::ip::address::from_string(_multicast_address)));
- cast_.address(cast_.address().to_v4().broadcast());
+ boost::asio::ip::address::from_string(_address)));
}
catch (...) {
@@ -122,34 +138,26 @@ void udp_server_endpoint_impl::leave(const std::string &_multicast_address) { }
}
-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;
+void udp_server_endpoint_impl::add_multicast(service_t _service, instance_t _instance,
+ const std::string &_address, uint16_t _port) {
+ endpoint_type its_endpoint(boost::asio::ip::address::from_string(_address), _port);
+ multicasts_[_service][_instance] = its_endpoint;
}
-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_v6()) {
- _address = its_address.to_v6().to_bytes();
- } else {
- return false;
+void udp_server_endpoint_impl::remove_multicast(service_t _service, instance_t _instance) {
+ auto found_service = multicasts_.find(_service);
+ if (found_service != multicasts_.end()) {
+ auto found_instance = found_service->second.find(_instance);
+ if (found_instance != found_service->second.end()) {
+ found_service->second.erase(_instance);
+ }
}
- return true;
}
unsigned short udp_server_endpoint_impl::get_port() const {
return socket_.local_endpoint().port();
}
-bool udp_server_endpoint_impl::is_udp() const {
- return false;
-}
-
// TODO: find a better way to structure the receive functions
void udp_server_endpoint_impl::receive_cbk(
packet_buffer_ptr_t _buffer,
diff --git a/implementation/message/include/event_impl.hpp b/implementation/message/include/event_impl.hpp deleted file mode 100644 index 689e7af..0000000 --- a/implementation/message/include/event_impl.hpp +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2014 BMW Group -// Author: Lutz Bichler (lutz.bichler@bmw.de) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef VSOMEIP_EVENT_IMPL_HPP -#define VSOMEIP_EVENT_IMPL_HPP - -#include <memory> -#include <mutex> - -#include <boost/asio/io_service.hpp> -#include <boost/asio/system_timer.hpp> - -#include <vsomeip/event.hpp> - -namespace vsomeip { - -class message; - -class event_impl: public event { -public: - event_impl(boost::asio::io_service &_io); - virtual ~event_impl(); - - service_t get_service() const; - void set_service(service_t _service); - - instance_t get_instance() const; - void set_instance(instance_t _instance); - - event_t get_event() const; - void set_event(event_t _event); - - std::shared_ptr< payload > get_payload() const; - void set_payload(std::shared_ptr< payload > _payload); - - // SIP_RPC_357 - void set_update_cycle(std::chrono::milliseconds &_cycle); - - // SIP_RPC_358 - void set_update_on_change(bool _is_on); - - // SIP_RPC_359 (epsilon change) is not supported! - -private: - std::mutex mutex_; - std::shared_ptr< message > update_; - - boost::asio::system_timer cycle_timer_; - std::chrono::milliseconds cycle_; - - bool is_updating_on_change_; -}; - -} // namespace vsomeip - -#endif // VSOMEIP_EVENT_IMPL_HPP diff --git a/implementation/message/src/deserializer.cpp b/implementation/message/src/deserializer.cpp index 05abcf7..28d45c4 100644 --- a/implementation/message/src/deserializer.cpp +++ b/implementation/message/src/deserializer.cpp @@ -13,9 +13,9 @@ #include <vsomeip/logger.hpp>
#endif
-#include "../include/byteorder.hpp"
#include "../include/message_impl.hpp"
#include "../include/deserializer.hpp"
+#include "../../utility/include/byteorder.hpp"
namespace vsomeip {
diff --git a/implementation/message/src/event_impl.cpp b/implementation/message/src/event_impl.cpp deleted file mode 100644 index ed6cee3..0000000 --- a/implementation/message/src/event_impl.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (C) 2014 BMW Group -// Author: Lutz Bichler (lutz.bichler@bmw.de) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#include <vsomeip/message.hpp> -#include <vsomeip/runtime.hpp> - -#include "../include/event_impl.hpp" - -namespace vsomeip { - -event_impl::event_impl(boost::asio::io_service &_io) - : update_(runtime::get()->create_notification()), - cycle_timer_(_io), - is_updating_on_change_(false) { -} - -event_impl::~event_impl() { -} - -service_t event_impl::get_service() const { - return update_->get_service(); -} - -void event_impl::set_service(service_t _service) { - update_->set_service(_service); -} - -instance_t event_impl::get_instance() const { - return update_->get_instance(); -} - -void event_impl::set_instance(instance_t _instance) { - update_->set_instance(_instance); -} - -event_t event_impl::get_event() const { - return update_->get_method(); -} - -void event_impl::set_event(event_t _event) { - update_->set_method(_event); // TODO: maybe we should check for the leading 0-bit -} - -std::shared_ptr< payload > event_impl::get_payload() const { - return update_->get_payload(); -} - -void event_impl::set_payload(std::shared_ptr< payload > _payload) { - std::unique_lock< std::mutex > its_lock(mutex_); - -} - -void event_impl::set_update_on_change(bool _is_active) { - is_updating_on_change_ = _is_active; -} - -void event_impl::set_update_cycle(std::chrono::milliseconds &_cycle) { - cycle_ = _cycle; - cycle_timer_.cancel(); - - if (std::chrono::milliseconds::zero() != _cycle) { - cycle_timer_.expires_from_now(cycle_); -/* - - std::function< void (boost::system::error_code const &) > its_handler - = [this, its_handler] (boost::system::error_code const &_error) { - // TODO: Tell the RM[I|P] to do the update - cycle_timer_.expires_from_now(cycle_); - cycle_timer_.async_wait(its_handler); - }; - - cycle_timer_.async_wait(its_handler); */ - } -} - -} // namespace vsomeip diff --git a/implementation/message/src/message_base_impl.cpp b/implementation/message/src/message_base_impl.cpp index 5bef55f..5504c2e 100644 --- a/implementation/message/src/message_base_impl.cpp +++ b/implementation/message/src/message_base_impl.cpp @@ -4,8 +4,8 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
-#include "../include/byteorder.hpp"
#include "../include/message_impl.hpp"
+#include "../../utility/include/byteorder.hpp"
namespace vsomeip {
diff --git a/implementation/message/src/message_impl.cpp b/implementation/message/src/message_impl.cpp index d179358..4be896a 100644 --- a/implementation/message/src/message_impl.cpp +++ b/implementation/message/src/message_impl.cpp @@ -8,8 +8,8 @@ #include <vsomeip/payload.hpp>
#include <vsomeip/runtime.hpp>
-#include "../include/byteorder.hpp"
#include "../include/message_impl.hpp"
+#include "../../utility/include/byteorder.hpp"
namespace vsomeip {
diff --git a/implementation/message/src/serializer.cpp b/implementation/message/src/serializer.cpp index 990bba5..416e26b 100644 --- a/implementation/message/src/serializer.cpp +++ b/implementation/message/src/serializer.cpp @@ -15,8 +15,8 @@ #include <vsomeip/serializable.hpp>
-#include "../include/byteorder.hpp"
#include "../include/serializer.hpp"
+#include "../../utility/include/byteorder.hpp"
namespace vsomeip {
diff --git a/implementation/routing/include/event.hpp b/implementation/routing/include/event.hpp new file mode 100644 index 0000000..2299279 --- /dev/null +++ b/implementation/routing/include/event.hpp @@ -0,0 +1,71 @@ +// Copyright (C) 2014 BMW Group +// Author: Lutz Bichler (lutz.bichler@bmw.de) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_EVENT_IMPL_HPP +#define VSOMEIP_EVENT_IMPL_HPP + +#include <map> +#include <memory> +#include <mutex> + +#include <boost/asio/io_service.hpp> +#include <boost/asio/ip/address.hpp> +#include <boost/asio/system_timer.hpp> + +namespace vsomeip { + +class endpoint; +class message; +class payload; +class routing_manager; + +class event : public std::enable_shared_from_this<event> { + public: + event(routing_manager *_routing); + + service_t get_service() const; + void set_service(service_t _service); + + instance_t get_instance() const; + void set_instance(instance_t _instance); + + event_t get_event() const; + void set_event(event_t _event); + + std::shared_ptr<payload> get_payload() const; + void set_payload(std::shared_ptr<payload> _payload); + + bool is_field() const; + void set_field(bool _is_field); + + // SIP_RPC_357 + void set_update_cycle(std::chrono::milliseconds &_cycle); + + // SIP_RPC_358 + void set_update_on_change(bool _is_on); + + // SIP_RPC_359 (epsilon change) is not supported! + + private: + void update_cbk(boost::system::error_code const &_error); + void notify(); + + private: + routing_manager *routing_; + std::mutex mutex_; + std::shared_ptr<message> message_; + + bool is_field_; + + boost::asio::system_timer cycle_timer_; + std::chrono::milliseconds cycle_; + + bool is_updating_on_change_; +}; + +} // namespace vsomeip + +#endif // VSOMEIP_EVENT_IMPL_HPP diff --git a/implementation/routing/include/eventgroupinfo.hpp b/implementation/routing/include/eventgroupinfo.hpp index 06c92e0..5305e90 100644 --- a/implementation/routing/include/eventgroupinfo.hpp +++ b/implementation/routing/include/eventgroupinfo.hpp @@ -10,37 +10,40 @@ #include <memory> #include <set> +#include <boost/asio/ip/address.hpp> + #include <vsomeip/primitive_types.hpp> namespace vsomeip { -class endpoint; +class event; class eventgroupinfo { public: - eventgroupinfo(major_version_t _major, ttl_t _ttl); + eventgroupinfo(); ~eventgroupinfo(); - servicegroup * get_group() const; - void set_group(servicegroup *_group); - major_version_t get_major() const; + void set_major(major_version_t _major); ttl_t get_ttl() const; void set_ttl(ttl_t _ttl); - std::shared_ptr<endpoint> & get_multicast(); - void set_multicast(std::shared_ptr<endpoint> &_multicast); + bool get_multicast(boost::asio::ip::address &_address, uint16_t &_port); + void set_multicast(const boost::asio::ip::address &_address, uint16_t _port); - void add_client(client_t _client); - void remove_client(client_t _client); + const std::set<std::shared_ptr<event> > get_events() const; + void add_event(std::shared_ptr<event> _event); private: major_version_t major_; ttl_t ttl_; - std::shared_ptr<endpoint> multicast_; - std::set< client_t > subscribed_; + bool is_multicast_; + boost::asio::ip::address address_; + uint16_t port_; + + std::set<std::shared_ptr<event> > events_; }; } // namespace vsomeip diff --git a/implementation/routing/include/routing_manager_impl.hpp b/implementation/routing/include/routing_manager_impl.hpp index 6d5e7fc..ac41eec 100644 --- a/implementation/routing/include/routing_manager_impl.hpp +++ b/implementation/routing/include/routing_manager_impl.hpp @@ -36,166 +36,185 @@ namespace sd { class service_discovery; -} // namespace sd - -class routing_manager_impl: public routing_manager, - public endpoint_host, - public sd::service_discovery_host, - public std::enable_shared_from_this<routing_manager_impl> { -public: - routing_manager_impl(routing_manager_host *_host); - ~routing_manager_impl(); - - boost::asio::io_service & get_io(); - std::shared_ptr<configuration> get_configuration() const; - - void init(); - void start(); - void stop(); - - void offer_service(client_t _client, service_t _service, - instance_t _instance, major_version_t _major, - minor_version_t _minor, ttl_t _ttl); - - void stop_offer_service(client_t _client, service_t _service, - instance_t _instance); - - void publish_eventgroup(client_t _client, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, - major_version_t _major, ttl_t _ttl); - - void stop_publish_eventgroup(client_t _client, service_t _service, - instance_t _instance, eventgroup_t _eventgroup); - - void request_service(client_t _client, service_t _service, - instance_t _instance, major_version_t _major, - minor_version_t _minor, ttl_t _ttl); - - void release_service(client_t _client, service_t _service, - instance_t _instance); - - void subscribe(client_t _client, service_t _service, instance_t _instance, - eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl); - - void unsubscribe(client_t _client, service_t _service, instance_t _instance, - eventgroup_t _eventgroup); - - bool send(client_t _client, std::shared_ptr<message> _message, bool _flush, - bool _reliable); - - bool send(client_t _client, const byte_t *_data, uint32_t _size, - instance_t _instance, bool _flush, bool _reliable); - - void set(client_t _client, service_t _service, instance_t _instance, - event_t _event, const std::shared_ptr<payload> &_value); - - bool is_available(service_t _service, instance_t _instance) const; - - // interface to stub - std::shared_ptr<endpoint> create_local(client_t _client); - std::shared_ptr<endpoint> find_local(client_t _client); - std::shared_ptr<endpoint> find_or_create_local(client_t _client); - void remove_local(client_t _client); - std::shared_ptr<endpoint> find_local(service_t _service, instance_t _instance); - - // interface "endpoint_host" - void on_connect(std::shared_ptr<endpoint> _endpoint); - void on_disconnect(std::shared_ptr<endpoint> _endpoint); - void on_message(const byte_t *_data, length_t _length, endpoint *_receiver); - - // interface "service_discovery_host" - typedef std::map<std::string, - std::shared_ptr<servicegroup> > servicegroups_t; - const servicegroups_t & get_servicegroups() const; - service_map_t get_offered_services(const std::string &_name) const; - void create_service_discovery_endpoint(const std::string &_address, - uint16_t _port, const std::string &_protocol); - -private: - bool deliver_message(const byte_t *_data, length_t _length, - instance_t _instance); - - client_t find_local_client(service_t _service, instance_t _instance); - instance_t find_instance(service_t _service, endpoint *_endpoint); - - 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 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_; - routing_manager_host *host_; - - std::shared_ptr<configuration> configuration_; - - std::shared_ptr<deserializer> deserializer_; - std::shared_ptr<serializer> serializer_; - - std::shared_ptr<routing_manager_stub> stub_; - 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_; - - // Server endpoints for local services - std::map<uint16_t, std::map<bool, std::shared_ptr<endpoint> > > server_endpoints_; - std::map<service_t, std::map<endpoint *, instance_t> > service_instances_; - - // Client endpoints for remote services - std::map<boost::asio::ip::address, - std::map<uint16_t, std::map<bool, std::shared_ptr<endpoint> > > > client_endpoints_; - std::map<service_t, - std::map<instance_t, std::map<bool, std::shared_ptr<endpoint> > > > 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_; - - // Eventgroups - std::map<service_t, - std::map<instance_t, - std::map<eventgroup_t, std::set<std::shared_ptr<endpoint> > > > > eventgroups_; - std::map<service_t, std::map<instance_t, std::map<event_t, eventgroup_t> > > events_; - std::map<eventgroup_t, std::set<client_t> > eventgroup_clients_; - - // Mutexes - std::recursive_mutex endpoint_mutex_; - std::mutex serialize_mutex_; +} // namespace sd + +class routing_manager_impl : public routing_manager, public endpoint_host, + public sd::service_discovery_host, public std::enable_shared_from_this< + routing_manager_impl> { + public: + routing_manager_impl(routing_manager_host *_host); + ~routing_manager_impl(); + + boost::asio::io_service & get_io(); + std::shared_ptr<configuration> get_configuration() const; + + void init(); + void start(); + void stop(); + + void offer_service(client_t _client, service_t _service, instance_t _instance, + major_version_t _major, minor_version_t _minor, + ttl_t _ttl); + + void stop_offer_service(client_t _client, service_t _service, + instance_t _instance); + + void publish_eventgroup(client_t _client, service_t _service, + instance_t _instance, eventgroup_t _eventgroup, + major_version_t _major, ttl_t _ttl); + + void stop_publish_eventgroup(client_t _client, service_t _service, + instance_t _instance, eventgroup_t _eventgroup); + + void request_service(client_t _client, service_t _service, + instance_t _instance, major_version_t _major, + minor_version_t _minor, ttl_t _ttl); + + void release_service(client_t _client, service_t _service, + instance_t _instance); + + void subscribe(client_t _client, service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl); + + void unsubscribe(client_t _client, service_t _service, instance_t _instance, + eventgroup_t _eventgroup); + + bool send(client_t _client, std::shared_ptr<message> _message, bool _flush, + bool _reliable); + + bool send(client_t _client, const byte_t *_data, uint32_t _size, + instance_t _instance, bool _flush, bool _reliable); + + void set(client_t _client, service_t _service, instance_t _instance, + event_t _event, const std::shared_ptr<payload> &_payload); + + bool is_available(service_t _service, instance_t _instance) const; + + // interface to stub + std::shared_ptr<endpoint> create_local(client_t _client); + std::shared_ptr<endpoint> find_local(client_t _client); + std::shared_ptr<endpoint> find_or_create_local(client_t _client); + void remove_local(client_t _client); + std::shared_ptr<endpoint> find_local(service_t _service, + instance_t _instance); + + // interface "endpoint_host" + std::shared_ptr<endpoint> find_remote_client(service_t _service, + instance_t _instance, + bool _reliable); + void on_connect(std::shared_ptr<endpoint> _endpoint); + void on_disconnect(std::shared_ptr<endpoint> _endpoint); + void on_message(const byte_t *_data, length_t _length, endpoint *_receiver); + + // interface "service_discovery_host" + typedef std::map<std::string, std::shared_ptr<servicegroup> > servicegroups_t; + const servicegroups_t & get_servicegroups() const; + std::shared_ptr<eventgroupinfo> find_eventgroup( + service_t _service, instance_t _instance, eventgroup_t _eventgroup) const; + services_t get_offered_services(const std::string &_name) const; + void create_service_discovery_endpoint(const std::string &_address, + uint16_t _port, bool _reliable); + bool send_subscribe(const boost::asio::ip::address &_address, uint16_t _port, + bool _reliable, const byte_t *_data, uint32_t _size); + 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); + + void init_event_routing_info(); + void add_subscription(service_t _service, instance_t _instance, + eventgroup_t _eventgroup, + const boost::asio::ip::address &_address, + uint16_t _reliable_port, uint16_t _unreliable_port); + void del_subscription(service_t _service, instance_t _instance, + eventgroup_t _eventgroup, + const boost::asio::ip::address &_address, + uint16_t _reliable_port, uint16_t _unreliable_port); + + private: + bool deliver_message(const byte_t *_data, length_t _length, + instance_t _instance); + + client_t find_local_client(service_t _service, instance_t _instance); + instance_t find_instance(service_t _service, endpoint *_endpoint); + + std::shared_ptr<serviceinfo> find_service(service_t _service, + instance_t _instance) const; + 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> 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); + + std::set<std::shared_ptr<event> > find_events(service_t _service, + instance_t _instance, + eventgroup_t _eventgroup); + std::shared_ptr<event> find_event(service_t _service, instance_t _instance, + event_t _event) const; + + private: + boost::asio::io_service &io_; + routing_manager_host *host_; + + std::shared_ptr<configuration> configuration_; + + std::shared_ptr<deserializer> deserializer_; + std::shared_ptr<serializer> serializer_; + + std::shared_ptr<routing_manager_stub> stub_; + 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_; + + // Server endpoints for local services + std::map<uint16_t, std::map<bool, std::shared_ptr<endpoint> > > server_endpoints_; + std::map<service_t, std::map<endpoint *, instance_t> > service_instances_; + + // Client endpoints for remote services + std::map<boost::asio::ip::address, + std::map<uint16_t, std::map<bool, std::shared_ptr<endpoint> > > > client_endpoints_; + std::map<service_t, + std::map<instance_t, std::map<bool, std::shared_ptr<endpoint> > > > 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_; + + // Eventgroups + std::map<service_t, + std::map<instance_t, + std::map<eventgroup_t, std::shared_ptr<eventgroupinfo> > > > eventgroups_; + std::map<service_t, + std::map<instance_t, std::map<event_t, std::shared_ptr<event> > > > events_; + + std::map<eventgroup_t, std::set<client_t> > eventgroup_clients_; + + // Mutexes + std::recursive_mutex endpoint_mutex_; + std::mutex serialize_mutex_; }; -} // namespace vsomeip +} // namespace vsomeip #endif // VSOMEIP_ROUTING_MANAGER_IMPL_HPP diff --git a/implementation/routing/include/servicegroup.hpp b/implementation/routing/include/servicegroup.hpp index 0ea997b..a59be62 100644 --- a/implementation/routing/include/servicegroup.hpp +++ b/implementation/routing/include/servicegroup.hpp @@ -11,7 +11,7 @@ #include <set> #include <string> -#include "routing_types.hpp" +#include "types.hpp" namespace vsomeip { @@ -27,11 +27,11 @@ public: bool add_service(service_t _service, instance_t _instance, std::shared_ptr< serviceinfo > _info); bool remove_service(service_t _service, instance_t _instance); - service_map_t get_services() const; + services_t get_services() const; private: std::string name_; - service_map_t services_; + services_t services_; }; } // namespace vsomeip diff --git a/implementation/routing/include/serviceinfo.hpp b/implementation/routing/include/serviceinfo.hpp index b38df5a..09b5486 100644 --- a/implementation/routing/include/serviceinfo.hpp +++ b/implementation/routing/include/serviceinfo.hpp @@ -9,6 +9,7 @@ #include <memory> #include <set> +#include <string> #include <vsomeip/primitive_types.hpp> @@ -19,37 +20,50 @@ class servicegroup; class serviceinfo { public: - serviceinfo(major_version_t _major, minor_version_t _minor, ttl_t _ttl); - ~serviceinfo(); + serviceinfo(major_version_t _major, minor_version_t _minor, ttl_t _ttl); + ~serviceinfo(); - servicegroup * get_group() const; - void set_group(servicegroup *_group); + servicegroup * get_group() const; + void set_group(servicegroup *_group); - major_version_t get_major() const; - minor_version_t get_minor() const; + major_version_t get_major() const; + minor_version_t get_minor() const; - ttl_t get_ttl() const; - void set_ttl(ttl_t _ttl); + ttl_t get_ttl() const; + void set_ttl(ttl_t _ttl); - std::shared_ptr< endpoint > & get_endpoint(bool _reliable); - void set_endpoint(std::shared_ptr< endpoint > &_endpoint, bool _reliable); + std::shared_ptr<endpoint> get_endpoint(bool _reliable) const; + void set_endpoint(std::shared_ptr<endpoint> _endpoint, bool _reliable); - void add_client(client_t _client); - void remove_client(client_t _client); + const std::string & get_multicast_address() const; + void set_multicast_address(const std::string &_multicast); + + uint16_t get_multicast_port() const; + void set_multicast_port(uint16_t _port); + + eventgroup_t get_multicast_group() const; + void set_multicast_group(eventgroup_t _multicast_group); + + void add_client(client_t _client); + void remove_client(client_t _client); private: - servicegroup *group_; + servicegroup *group_; + + major_version_t major_; + minor_version_t minor_; + ttl_t ttl_; - major_version_t major_; - minor_version_t minor_; - ttl_t ttl_; + std::shared_ptr<endpoint> reliable_; + std::shared_ptr<endpoint> unreliable_; - std::shared_ptr< endpoint > reliable_; - std::shared_ptr< endpoint > unreliable_; + std::string multicast_address_; + uint16_t multicast_port_; + eventgroup_t multicast_group_; - std::set< client_t > requesters_; + std::set<client_t> requesters_; }; -} // namespace vsomeip +} // namespace vsomeip #endif // VSOMEIP_SERVICEINFO_HPP diff --git a/implementation/routing/include/routing_types.hpp b/implementation/routing/include/types.hpp index 67f0886..ad28c01 100644 --- a/implementation/routing/include/routing_types.hpp +++ b/implementation/routing/include/types.hpp @@ -18,14 +18,14 @@ class serviceinfo; typedef std::map<service_t, std::map<instance_t, - std::shared_ptr<serviceinfo> > > service_map_t; + std::shared_ptr<serviceinfo> > > services_t; class eventgroupinfo; typedef std::map<service_t, std::map<instance_t, std::map<eventgroup_t, - std::shared_ptr<eventgroupinfo> > > > eventgroup_map_t; + std::shared_ptr<eventgroupinfo> > > > eventgroups_t; } // namespace vsomeip diff --git a/implementation/routing/src/event.cpp b/implementation/routing/src/event.cpp new file mode 100644 index 0000000..ebfc5fd --- /dev/null +++ b/implementation/routing/src/event.cpp @@ -0,0 +1,105 @@ +// Copyright (C) 2014 BMW Group +// Author: Lutz Bichler (lutz.bichler@bmw.de) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <iomanip> + +#include <vsomeip/defines.hpp> +#include <vsomeip/logger.hpp> +#include <vsomeip/message.hpp> +#include <vsomeip/runtime.hpp> + +#include "../include/event.hpp" +#include "../include/routing_manager.hpp" +#include "../../configuration/include/internal.hpp" + +namespace vsomeip { + +event::event(routing_manager *_routing) + : routing_(_routing), + message_(runtime::get()->create_notification()), + cycle_timer_(_routing->get_io()), + is_updating_on_change_(true) { +} + +service_t event::get_service() const { + return message_->get_service(); +} + +void event::set_service(service_t _service) { + message_->set_service(_service); +} + +instance_t event::get_instance() const { + return message_->get_instance(); +} + +void event::set_instance(instance_t _instance) { + message_->set_instance(_instance); +} + +event_t event::get_event() const { + return message_->get_method(); +} + +void event::set_event(event_t _event) { + message_->set_method(_event); // TODO: maybe we should check for the leading 0-bit +} + +bool event::is_field() const { + return is_field_; +} + +void event::set_field(bool _is_field) { + is_field_ = _is_field; +} + +std::shared_ptr<payload> event::get_payload() const { + return message_->get_payload(); +} + +void event::set_payload(std::shared_ptr<payload> _payload) { + bool is_change = _payload != message_->get_payload(); + if (true) { + message_->set_payload(_payload); + if (is_updating_on_change_) { + notify(); + } + } +} + +void event::set_update_on_change(bool _is_active) { + is_updating_on_change_ = _is_active; +} + +void event::set_update_cycle(std::chrono::milliseconds &_cycle) { + cycle_ = _cycle; + cycle_timer_.cancel(); + + if (std::chrono::milliseconds::zero() != _cycle) { + cycle_timer_.expires_from_now(cycle_); + std::function<void(boost::system::error_code const &)> its_handler = + std::bind(&event::update_cbk, shared_from_this(), + std::placeholders::_1); + cycle_timer_.async_wait(its_handler); + } +} + +void event::update_cbk(boost::system::error_code const &_error) { + if (!_error) { + cycle_timer_.expires_from_now(cycle_); + notify(); + std::function<void(boost::system::error_code const &)> its_handler = + std::bind(&event::update_cbk, shared_from_this(), + std::placeholders::_1); + cycle_timer_.async_wait(its_handler); + } +} + +void event::notify() { + routing_->send(VSOMEIP_ROUTING_CLIENT, message_, true, true); +} + +} // namespace vsomeip diff --git a/implementation/routing/src/eventgroupinfo.cpp b/implementation/routing/src/eventgroupinfo.cpp new file mode 100644 index 0000000..bb9de5a --- /dev/null +++ b/implementation/routing/src/eventgroupinfo.cpp @@ -0,0 +1,60 @@ +// Copyright (C) 2014 BMW Group +// Author: Lutz Bichler (lutz.bichler@bmw.de) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include <vsomeip/constants.hpp> + +#include "../include/eventgroupinfo.hpp" + +namespace vsomeip { + +eventgroupinfo::eventgroupinfo() + : major_(DEFAULT_MAJOR), + ttl_(DEFAULT_TTL), + is_multicast_(false) { +} + +eventgroupinfo::~eventgroupinfo() { +} + +major_version_t eventgroupinfo::get_major() const { + return major_; +} + +void eventgroupinfo::set_major(major_version_t _major) { + major_ = _major; +} + +ttl_t eventgroupinfo::get_ttl() const { + return ttl_; +} + +void eventgroupinfo::set_ttl(ttl_t _ttl) { + ttl_ = _ttl; +} + +bool eventgroupinfo::get_multicast(boost::asio::ip::address &_address, uint16_t &_port) { + if (is_multicast_) { + _address = address_; + _port = port_; + } + return is_multicast_; +} + +void eventgroupinfo::set_multicast(const boost::asio::ip::address &_address, uint16_t _port) { + address_ = _address; + port_ = _port; + is_multicast_ = true; +} + +const std::set<std::shared_ptr<event> > eventgroupinfo::get_events() const { + return events_; +} + +void eventgroupinfo::add_event(std::shared_ptr<event> _event) { + events_.insert(_event); +} + +} // namespace vsomeip diff --git a/implementation/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp index 0ae230b..f9263a7 100644 --- a/implementation/routing/src/routing_manager_impl.cpp +++ b/implementation/routing/src/routing_manager_impl.cpp @@ -13,6 +13,8 @@ #include <vsomeip/logger.hpp> #include <vsomeip/message.hpp> +#include "../include/event.hpp" +#include "../include/eventgroupinfo.hpp" #include "../include/routing_manager_host.hpp" #include "../include/routing_manager_impl.hpp" #include "../include/routing_manager_stub.hpp" @@ -24,810 +26,979 @@ #include "../../endpoints/include/tcp_server_endpoint_impl.hpp" #include "../../endpoints/include/udp_client_endpoint_impl.hpp" #include "../../endpoints/include/udp_server_endpoint_impl.hpp" -#include "../../message/include/byteorder.hpp" #include "../../message/include/deserializer.hpp" -#include "../../message/include/event_impl.hpp" #include "../../message/include/serializer.hpp" #include "../../service_discovery/include/defines.hpp" #include "../../service_discovery/include/runtime.hpp" #include "../../service_discovery/include/service_discovery_impl.hpp" +#include "../../utility/include/byteorder.hpp" #include "../../utility/include/utility.hpp" namespace vsomeip { -routing_manager_impl::routing_manager_impl(routing_manager_host *_host) : - host_(_host), io_(_host->get_io()), deserializer_( - std::make_shared<deserializer>()), serializer_( - std::make_shared<serializer>()), configuration_( - host_->get_configuration()) { +routing_manager_impl::routing_manager_impl(routing_manager_host *_host) + : host_(_host), + io_(_host->get_io()), + deserializer_(std::make_shared<deserializer>()), + serializer_(std::make_shared<serializer>()), + configuration_(host_->get_configuration()) { } routing_manager_impl::~routing_manager_impl() { } boost::asio::io_service & routing_manager_impl::get_io() { - return io_; + return io_; } void routing_manager_impl::init() { - uint32_t its_max_message_size = VSOMEIP_MAX_LOCAL_MESSAGE_SIZE; - if (VSOMEIP_MAX_TCP_MESSAGE_SIZE > its_max_message_size) - its_max_message_size = VSOMEIP_MAX_TCP_MESSAGE_SIZE; - if (VSOMEIP_MAX_UDP_MESSAGE_SIZE > its_max_message_size) - its_max_message_size = VSOMEIP_MAX_UDP_MESSAGE_SIZE; - - serializer_->create_data(its_max_message_size); - - // TODO: Only instantiate the stub if needed - stub_ = std::make_shared < routing_manager_stub > (this); - stub_->init(); - - if (configuration_->is_service_discovery_enabled()) { - VSOMEIP_INFO << "Service Discovery enabled."; - sd::runtime **its_runtime = - static_cast<sd::runtime **>(utility::load_library( - VSOMEIP_SD_LIBRARY, - VSOMEIP_SD_RUNTIME_SYMBOL_STRING)); - - if (0 != its_runtime && 0 != (*its_runtime)) { - VSOMEIP_INFO << "Service Discovery module loaded."; - discovery_ = (*its_runtime)->create_service_discovery(this); - discovery_->init(); - } - } else { - init_routing_info(); - } + uint32_t its_max_message_size = VSOMEIP_MAX_LOCAL_MESSAGE_SIZE; + if (VSOMEIP_MAX_TCP_MESSAGE_SIZE > its_max_message_size) + its_max_message_size = VSOMEIP_MAX_TCP_MESSAGE_SIZE; + if (VSOMEIP_MAX_UDP_MESSAGE_SIZE > its_max_message_size) + its_max_message_size = VSOMEIP_MAX_UDP_MESSAGE_SIZE; + + serializer_->create_data(its_max_message_size); + + // TODO: Only instantiate the stub if needed + stub_ = std::make_shared < routing_manager_stub > (this); + stub_->init(); + + if (configuration_->is_service_discovery_enabled()) { + VSOMEIP_INFO << "Service Discovery enabled."; + sd::runtime **its_runtime = + static_cast<sd::runtime **>(utility::load_library( + VSOMEIP_SD_LIBRARY, + VSOMEIP_SD_RUNTIME_SYMBOL_STRING)); + + if (0 != its_runtime && 0 != (*its_runtime)) { + VSOMEIP_INFO << "Service Discovery module loaded."; + discovery_ = (*its_runtime)->create_service_discovery(this); + discovery_->init(); + } + + init_event_routing_info(); + } else { + init_routing_info(); + } } void routing_manager_impl::start() { - stub_->start(); - if (discovery_) - discovery_->start(); + stub_->start(); + if (discovery_) + discovery_->start(); - host_->on_event(event_type_e::REGISTERED); + host_->on_event(event_type_e::REGISTERED); } void routing_manager_impl::stop() { - host_->on_event(event_type_e::DEREGISTERED); + host_->on_event(event_type_e::DEREGISTERED); - if (discovery_) - discovery_->stop(); - stub_->stop(); + if (discovery_) + discovery_->stop(); + stub_->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) { - local_services_[_service][_instance] = _client; - - // Remote route (incoming only) - 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 { - (void) create_service(_service, _instance, _major, _minor, _ttl); - } - - host_->on_availability(_service, _instance, true); + instance_t _instance, + major_version_t _major, + minor_version_t _minor, ttl_t _ttl) { + local_services_[_service][_instance] = _client; + + // Remote route (incoming only) + std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance)); + if (its_info) { + if (its_info->get_major() == _major && its_info->get_minor() == _minor) { + its_info->set_ttl(_ttl); + } else { + host_->on_error(error_code_e::SERVICE_PROPERTY_MISMATCH); + } + } else { + VSOMEIP_INFO << "CREATING SERVICE [" << std::hex << _service << "." + << _instance << "]"; + (void) create_service(_service, _instance, _major, _minor, _ttl); + } + + host_->on_availability(_service, _instance, true); } void routing_manager_impl::stop_offer_service(client_t its_client, - service_t _service, instance_t _instance) { - 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 { - // TODO: allow to withdraw a service on one endpoint only - del_routing_info(_service, _instance, false); - del_routing_info(_service, _instance, true); - } + service_t _service, + instance_t _instance) { + 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 { + // TODO: allow to withdraw a service on one endpoint only + del_routing_info(_service, _instance, false); + del_routing_info(_service, _instance, true); + } } void routing_manager_impl::publish_eventgroup(client_t its_client, - service_t _service, instance_t _instance, eventgroup_t _eventgroup, - major_version_t _major, ttl_t _ttl) { + service_t _service, + instance_t _instance, + eventgroup_t _eventgroup, + major_version_t _major, + ttl_t _ttl) { } void routing_manager_impl::stop_publish_eventgroup(client_t its_client, - service_t _service, instance_t _instance, eventgroup_t _eventgroup) { + service_t _service, + instance_t _instance, + eventgroup_t _eventgroup) { } 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) { - - 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())) { - host_->on_error(error_code_e::SERVICE_PROPERTY_MISMATCH); - } else { - its_info->add_client(_client); - } - } else { - if (discovery_) - discovery_->request_service(_service, _instance, _major, _minor, - _ttl); - } + instance_t _instance, + major_version_t _major, + minor_version_t _minor, ttl_t _ttl) { + + 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())) { + host_->on_error(error_code_e::SERVICE_PROPERTY_MISMATCH); + } else { + its_info->add_client(_client); + } + } else { + if (discovery_) + discovery_->request_service(_service, _instance, _major, _minor, _ttl); + } } void routing_manager_impl::release_service(client_t _client, service_t _service, - instance_t _instance) { - std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance)); - if (its_info) { - its_info->remove_client(_client); - } else { - if (discovery_) - discovery_->release_service(_service, _instance); - } + instance_t _instance) { + std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance)); + if (its_info) { + its_info->remove_client(_client); + } else { + if (discovery_) + discovery_->release_service(_service, _instance); + } } void routing_manager_impl::subscribe(client_t _client, service_t _service, - instance_t _instance, eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl) { - if (discovery_) { - eventgroup_clients_[_eventgroup].insert(_client); - discovery_->subscribe(_service, _instance, _eventgroup, _major, _ttl); - } else { - VSOMEIP_ERROR << "SOME/IP eventgroups require SD to be enabled!"; - } + instance_t _instance, + eventgroup_t _eventgroup, + major_version_t _major, ttl_t _ttl) { + if (discovery_) { + eventgroup_clients_[_eventgroup].insert(_client); + discovery_->subscribe(_service, _instance, _eventgroup, _major, _ttl); + } else { + VSOMEIP_ERROR << "SOME/IP eventgroups require SD to be enabled!"; + } } void routing_manager_impl::unsubscribe(client_t _client, service_t _service, - instance_t _instance, eventgroup_t _eventgroup) { - if (discovery_) { - auto found_eventgroup = eventgroup_clients_.find(_eventgroup); - if (found_eventgroup != eventgroup_clients_.end()) { - found_eventgroup->second.erase(_client); - if (0 == found_eventgroup->second.size()) { - eventgroup_clients_.erase(_eventgroup); - } - } - discovery_->unsubscribe(_service, _instance, _eventgroup); - } else { - VSOMEIP_ERROR << "SOME/IP eventgroups require SD to be enabled!"; - } + instance_t _instance, + eventgroup_t _eventgroup) { + if (discovery_) { + auto found_eventgroup = eventgroup_clients_.find(_eventgroup); + if (found_eventgroup != eventgroup_clients_.end()) { + found_eventgroup->second.erase(_client); + if (0 == found_eventgroup->second.size()) { + eventgroup_clients_.erase(_eventgroup); + } + } + discovery_->unsubscribe(_service, _instance, _eventgroup); + } else { + VSOMEIP_ERROR << "SOME/IP eventgroups require SD to be enabled!"; + } } bool routing_manager_impl::send(client_t its_client, - std::shared_ptr<message> _message, bool _reliable, bool _flush) { - bool is_sent(false); - std::unique_lock < std::mutex > its_lock(serialize_mutex_); + std::shared_ptr<message> _message, + bool _reliable, bool _flush) { + bool is_sent(false); + std::unique_lock < std::mutex > its_lock(serialize_mutex_); - if (utility::is_request(_message->get_message_type())) { - _message->set_client(its_client); - } + if (utility::is_request(_message->get_message_type())) { + _message->set_client(its_client); + } - if (serializer_->serialize(_message.get())) { - is_sent = send(its_client, serializer_->get_data(), - serializer_->get_size(), _message->get_instance(), _reliable, - _flush); - serializer_->reset(); - } - return is_sent; + if (serializer_->serialize(_message.get())) { + is_sent = send(its_client, serializer_->get_data(), serializer_->get_size(), + _message->get_instance(), _reliable, _flush); + serializer_->reset(); + } + return is_sent; } bool routing_manager_impl::send(client_t _client, const byte_t *_data, - length_t _size, instance_t _instance, bool _flush, bool _reliable) { - bool is_sent(false); - - std::shared_ptr<endpoint> its_target; - bool is_request = utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS]); - - client_t its_client = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_CLIENT_POS_MIN], - _data[VSOMEIP_CLIENT_POS_MAX]); - service_t its_service = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]); - - if (_size > VSOMEIP_MESSAGE_TYPE_POS) { - if (is_request) { - its_target = find_local(its_service, _instance); - } else { - its_target = find_local(its_client); - } - - if (its_target) { - std::vector<byte_t> its_command( - VSOMEIP_COMMAND_HEADER_SIZE + _size + sizeof(instance_t) - + sizeof(bool) + sizeof(bool)); - its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SEND; - std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client, - sizeof(client_t)); - std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &_size, - sizeof(_size)); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], _data, - _size); - std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + _size], - &_instance, sizeof(instance_t)); - std::memcpy( - &its_command[VSOMEIP_COMMAND_PAYLOAD_POS + _size - + sizeof(instance_t)], &_reliable, sizeof(bool)); - std::memcpy( - &its_command[VSOMEIP_COMMAND_PAYLOAD_POS + _size - + sizeof(instance_t) + sizeof(bool)], &_flush, - sizeof(bool)); - is_sent = its_target->send(&its_command[0], its_command.size(), - _flush); - } else { - // Check whether hosting application should get the message - // If not, check routes to external - if ((its_client == host_->get_client() && !is_request) - || (find_local_client(its_service, _instance) - == host_->get_client() && is_request)) { - // TODO: find out how to handle session id here - is_sent = deliver_message(_data, _size, _instance); - } else { - if (is_request) { - its_target = find_remote_client(its_service, _instance, - _reliable); - if (its_target) { - is_sent = its_target->send(_data, _size, _flush); - } else { - VSOMEIP_ERROR - << "Routing error. Client from remote service could not be found!"; - } - } else { - std::shared_ptr<serviceinfo> its_info( - find_service(its_service, _instance)); - if (its_info) { - its_target = its_info->get_endpoint(_reliable); - if (its_target) { - is_sent = its_target->send(_data, _size, _flush); - } else { - VSOMEIP_ERROR - << "Routing error. Service endpoint could not be found!"; - } - } else { - VSOMEIP_ERROR - << "Routing error. Service could not be found!"; - } - } - } - } - } - - return is_sent; + length_t _size, instance_t _instance, + bool _flush, bool _reliable) { + bool is_sent(false); + + std::shared_ptr<endpoint> its_target; + bool is_request = utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS]); + bool is_notification = utility::is_notification(_data); + + client_t its_client = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_CLIENT_POS_MIN], + _data[VSOMEIP_CLIENT_POS_MAX]); + service_t its_service = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_SERVICE_POS_MIN], + _data[VSOMEIP_SERVICE_POS_MAX]); + + if (_size > VSOMEIP_MESSAGE_TYPE_POS) { + if (is_request) { + its_target = find_local(its_service, _instance); + } else { + its_target = find_local(its_client); + } + + if (its_target) { + std::vector<byte_t> its_command( + VSOMEIP_COMMAND_HEADER_SIZE + _size + sizeof(instance_t) + + sizeof(bool) + sizeof(bool)); + its_command[VSOMEIP_COMMAND_TYPE_POS] = VSOMEIP_SEND; + std::memcpy(&its_command[VSOMEIP_COMMAND_CLIENT_POS], &_client, + sizeof(client_t)); + std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &_size, + sizeof(_size)); + std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS], _data, _size); + std::memcpy(&its_command[VSOMEIP_COMMAND_PAYLOAD_POS + _size], &_instance, + sizeof(instance_t)); + std::memcpy( + &its_command[VSOMEIP_COMMAND_PAYLOAD_POS + _size + sizeof(instance_t)], + &_reliable, sizeof(bool)); + std::memcpy( + &its_command[VSOMEIP_COMMAND_PAYLOAD_POS + _size + sizeof(instance_t) + + sizeof(bool)], + &_flush, sizeof(bool)); + is_sent = its_target->send(&its_command[0], its_command.size(), _flush); + } else { + // Check whether hosting application should get the message + // If not, check routes to external + if ((its_client == host_->get_client() && !is_request) + || (find_local_client(its_service, _instance) == host_->get_client() + && is_request)) { + // TODO: find out how to handle session id here + is_sent = deliver_message(_data, _size, _instance); + } else { + if (is_request) { + its_target = find_remote_client(its_service, _instance, _reliable); + if (its_target) { + is_sent = its_target->send(_data, _size, _flush); + } else { + VSOMEIP_ERROR + << "Routing error. Client from remote service could not be found!"; + } + } else { + std::shared_ptr<serviceinfo> its_info( + find_service(its_service, _instance)); + if (its_info) { + its_target = its_info->get_endpoint(_reliable); + if (its_target) { + is_sent = its_target->send(_data, _size, _flush); + } else { + VSOMEIP_ERROR + << "Routing error. Service endpoint could not be found!"; + } + } else { + VSOMEIP_ERROR << "Routing error. Service could not be found!"; + } + } + } + } + } + + return is_sent; } void routing_manager_impl::set(client_t its_client, service_t _service, - instance_t _instance, event_t _event, - const std::shared_ptr<payload> &_value) { + instance_t _instance, event_t _event, + const std::shared_ptr<payload> &_payload) { + std::shared_ptr<event> its_event = find_event(_service, _instance, _event); + if (its_event) { + its_event->set_payload(_payload); + } else { + VSOMEIP_ERROR << "Event [" << std::hex << std::setw(4) << std::setfill('0') + << _service << "." << std::setw(4) << std::setfill('0') << _instance + << "." << std::setw(4) << std::setfill('0') << _event + << "] is unknown!"; + } +} + +bool routing_manager_impl::send_subscribe( + const boost::asio::ip::address &_address, uint16_t _port, bool _reliable, + const byte_t *_data, uint32_t _size) { + std::shared_ptr<endpoint> its_endpoint = find_server_endpoint(_port, + _reliable); + if (its_endpoint) + return its_endpoint->send_to(_address, _port, _data, _size); + + return false; } void routing_manager_impl::on_message(const byte_t *_data, length_t _size, - endpoint *_receiver) { + endpoint *_receiver) { #if 0 - std::stringstream msg; - msg << "rmi::on_message: "; - for (uint32_t i = 0; i < _size; ++i) - msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; - VSOMEIP_DEBUG << msg.str(); + std::stringstream msg; + msg << "rmi::on_message: "; + for (uint32_t i = 0; i < _size; ++i) + msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; + VSOMEIP_DEBUG << msg.str(); #endif - if (_size >= VSOMEIP_SOMEIP_HEADER_SIZE) { - service_t its_service = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]); - if (its_service == VSOMEIP_SD_SERVICE) { - if (discovery_) - discovery_->on_message(_data, _size); - } else { - instance_t its_instance = find_instance(its_service, _receiver); - if (its_instance != ANY_INSTANCE) { - client_t its_client(VSOMEIP_ROUTING_CLIENT); - if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) { - its_client = find_local_client(its_service, its_instance); - } else { - its_client = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_CLIENT_POS_MIN], - _data[VSOMEIP_CLIENT_POS_MAX]); - } - - if (its_client == host_->get_client()) { - deliver_message(_data, _size, its_instance); - } else if (its_client != VSOMEIP_ROUTING_CLIENT) { - send(its_client, _data, _size, its_instance, true, false); - } else { - VSOMEIP_ERROR << "Could not determine target application!"; - } - } else { - VSOMEIP_ERROR << "Could not determine service instance for [" - << its_service << "]"; - } - } - } else { - //send_error(); // TODO: send error "malformed message" - } + if (_size >= VSOMEIP_SOMEIP_HEADER_SIZE) { + service_t its_service = VSOMEIP_BYTES_TO_WORD( + _data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]); + if (its_service == VSOMEIP_SD_SERVICE) { + if (discovery_) + discovery_->on_message(_data, _size); + } else { + instance_t its_instance = find_instance(its_service, _receiver); + if (its_instance != ANY_INSTANCE) { + client_t its_client(VSOMEIP_ROUTING_CLIENT); + if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) { + its_client = find_local_client(its_service, its_instance); + } else { + its_client = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_CLIENT_POS_MIN], + _data[VSOMEIP_CLIENT_POS_MAX]); + } + + if (its_client == host_->get_client()) { + deliver_message(_data, _size, its_instance); + } else if (its_client != VSOMEIP_ROUTING_CLIENT) { + send(its_client, _data, _size, its_instance, true, false); + } else { + VSOMEIP_ERROR << "Could not determine target application!"; + } + } else { + VSOMEIP_ERROR << "Could not determine service instance for [" + << its_service << "]"; + } + } + } else { + //send_error(); // TODO: send error "malformed message" + } } void routing_manager_impl::on_connect(std::shared_ptr<endpoint> _endpoint) { - for (auto &its_service : remote_services_) { - for (auto &its_instance : its_service.second) { - auto found_endpoint = its_instance.second.find(false); - if (found_endpoint != its_instance.second.end()) { - host_->on_availability(its_service.first, its_instance.first, - true); - } else { - found_endpoint = its_instance.second.find(true); - if (found_endpoint != its_instance.second.end()) { - host_->on_availability(its_service.first, - its_instance.first, true); - } - } - } - } + for (auto &its_service : remote_services_) { + for (auto &its_instance : its_service.second) { + auto found_endpoint = its_instance.second.find(false); + if (found_endpoint != its_instance.second.end()) { + host_->on_availability(its_service.first, its_instance.first, true); + } else { + found_endpoint = its_instance.second.find(true); + if (found_endpoint != its_instance.second.end()) { + host_->on_availability(its_service.first, its_instance.first, true); + } + } + } + } } void routing_manager_impl::on_disconnect(std::shared_ptr<endpoint> _endpoint) { - for (auto &its_service : remote_services_) { - for (auto &its_instance : its_service.second) { - auto found_endpoint = its_instance.second.find(false); - if (found_endpoint != its_instance.second.end()) { - host_->on_availability(its_service.first, its_instance.first, - false); - } else { - found_endpoint = its_instance.second.find(true); - if (found_endpoint != its_instance.second.end()) { - host_->on_availability(its_service.first, - its_instance.first, false); - } - } - } - } + for (auto &its_service : remote_services_) { + for (auto &its_instance : its_service.second) { + auto found_endpoint = its_instance.second.find(false); + if (found_endpoint != its_instance.second.end()) { + host_->on_availability(its_service.first, its_instance.first, false); + } else { + found_endpoint = its_instance.second.find(true); + if (found_endpoint != its_instance.second.end()) { + host_->on_availability(its_service.first, its_instance.first, false); + } + } + } + } } bool routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, - instance_t _instance) { - bool is_sent(false); - deserializer_->set_data(_data, _size); - std::shared_ptr<message> its_message(deserializer_->deserialize_message()); - if (its_message) { - its_message->set_instance(_instance); - host_->on_message(its_message); - is_sent = true; - } else { - // TODO: send error "Malformed Message" - //send_error(); - } - return is_sent; + instance_t _instance) { + bool is_sent(false); + deserializer_->set_data(_data, _size); + std::shared_ptr<message> its_message(deserializer_->deserialize_message()); + if (its_message) { + its_message->set_instance(_instance); + host_->on_message(its_message); + is_sent = true; + } else { + // TODO: send error "Malformed Message" + //send_error(); + } + return is_sent; } 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; + 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_; + return servicegroups_; +} + +std::shared_ptr<eventgroupinfo> routing_manager_impl::find_eventgroup( + service_t _service, instance_t _instance, eventgroup_t _eventgroup) const { + std::shared_ptr<eventgroupinfo> its_info(nullptr); + auto found_service = eventgroups_.find(_service); + if (found_service != eventgroups_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + auto found_eventgroup = found_instance->second.find(_eventgroup); + if (found_eventgroup != found_instance->second.end()) { + its_info = found_eventgroup->second; + std::shared_ptr<serviceinfo> its_service_info = find_service(_service, + _instance); + if (its_service_info) { + if (_eventgroup == its_service_info->get_multicast_group()) { + boost::asio::ip::address its_multicast_address = + boost::asio::ip::address::from_string( + its_service_info->get_multicast_address()); + uint16_t its_multicast_port = + its_service_info->get_multicast_port(); + its_info->set_multicast(its_multicast_address, its_multicast_port); + } + its_info->set_major(its_service_info->get_major()); + its_info->set_ttl(its_service_info->get_ttl()); + } + } + } + } + return its_info; } std::shared_ptr<configuration> routing_manager_impl::get_configuration() const { - return host_->get_configuration(); + return host_->get_configuration(); } void routing_manager_impl::create_service_discovery_endpoint( - const std::string &_address, uint16_t _port, - const std::string &_protocol) { - bool is_reliable = (_protocol != "udp"); + const std::string &_address, uint16_t _port, bool _reliable) { + std::shared_ptr<endpoint> its_service_endpoint = find_server_endpoint( + _port, _reliable); + if (!its_service_endpoint) { + its_service_endpoint = create_server_endpoint(_port, _reliable); - std::shared_ptr<endpoint> its_service_endpoint = find_server_endpoint(_port, - is_reliable); - 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)); + its_info->set_endpoint(its_service_endpoint, _reliable); - 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; - // routing info - services_[VSOMEIP_SD_SERVICE][VSOMEIP_SD_INSTANCE] = its_info; - - its_service_endpoint->join(_address); - its_service_endpoint->start(); - } + its_service_endpoint->add_multicast(VSOMEIP_SD_SERVICE, VSOMEIP_SD_METHOD, + _address, _port); + its_service_endpoint->join(_address); + its_service_endpoint->start(); + } } -service_map_t routing_manager_impl::get_offered_services( - const std::string &_name) const { - service_map_t its_offers; - - auto find_servicegroup = servicegroups_.find(_name); - if (find_servicegroup != servicegroups_.end()) { - return find_servicegroup->second->get_services(); - } +services_t routing_manager_impl::get_offered_services( + const std::string &_name) const { + services_t its_offers; + auto find_servicegroup = servicegroups_.find(_name); + if (find_servicegroup != servicegroups_.end()) { + return find_servicegroup->second->get_services(); + } - return its_offers; + return its_offers; } /////////////////////////////////////////////////////////////////////////////// // PRIVATE /////////////////////////////////////////////////////////////////////////////// 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; - } - } - return its_info; + service_t _service, instance_t _instance) const { + 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; + } + } + return its_info; } 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_) { - 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); - - if (ILLEGAL_PORT != its_reliable_port) { - std::shared_ptr<endpoint> its_reliable_endpoint( - find_or_create_server_endpoint(its_reliable_port, true)); - its_info->set_endpoint(its_reliable_endpoint, true); - - // TODO: put this in a method and check whether an assignment already exists! - service_instances_[_service][its_reliable_endpoint.get()] = - _instance; - } - - if (ILLEGAL_PORT != its_unreliable_port) { - std::shared_ptr<endpoint> its_unreliable_endpoint( - find_or_create_server_endpoint(its_unreliable_port, false)); - its_info->set_endpoint(its_unreliable_endpoint, false); - - service_instances_[_service][its_unreliable_endpoint.get()] = - _instance; - } - - if (ILLEGAL_PORT != its_reliable_port - || ILLEGAL_PORT != its_unreliable_port) { - std::string its_servicegroup = configuration_->get_group(_service, - _instance); - auto found_servicegroup = servicegroups_.find(its_servicegroup); - if (found_servicegroup == servicegroups_.end()) { - servicegroups_[its_servicegroup] = std::make_shared - < servicegroup > (its_servicegroup); - } - servicegroups_[its_servicegroup]->add_service(_service, _instance, - its_info); - services_[_service][_instance] = its_info; - } else { - host_->on_error(error_code_e::PORT_CONFIGURATION_MISSING); - } - } else { - host_->on_error(error_code_e::CONFIGURATION_MISSING); - } - - return its_info; + 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_) { + 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); + + its_info->set_multicast_address( + configuration_->get_multicast_address(_service, _instance)); + its_info->set_multicast_port( + configuration_->get_multicast_port(_service, _instance)); + its_info->set_multicast_group( + configuration_->get_multicast_group(_service, _instance)); + + VSOMEIP_DEBUG << "MULTICAST [" + << std::hex << _service << "." << _instance << "] --> " + << its_info->get_multicast_group(); + + std::shared_ptr<endpoint> its_reliable_endpoint; + std::shared_ptr<endpoint> its_unreliable_endpoint; + + if (ILLEGAL_PORT != its_reliable_port) { + its_reliable_endpoint = find_or_create_server_endpoint(its_reliable_port, + true); + its_info->set_endpoint(its_reliable_endpoint, true); + + // TODO: put this in a method and check whether an assignment already exists! + service_instances_[_service][its_reliable_endpoint.get()] = _instance; + } + + if (ILLEGAL_PORT != its_unreliable_port) { + its_unreliable_endpoint = find_or_create_server_endpoint( + its_unreliable_port, false); + its_info->set_endpoint(its_unreliable_endpoint, false); + + service_instances_[_service][its_unreliable_endpoint.get()] = _instance; + } + + if (ILLEGAL_PORT != its_reliable_port + || ILLEGAL_PORT != its_unreliable_port) { + std::string its_servicegroup = configuration_->get_group(_service, + _instance); + auto found_servicegroup = servicegroups_.find(its_servicegroup); + if (found_servicegroup == servicegroups_.end()) { + servicegroups_[its_servicegroup] = std::make_shared < servicegroup + > (its_servicegroup); + } + + servicegroups_[its_servicegroup]->add_service(_service, _instance, + its_info); + services_[_service][_instance] = its_info; + } else { + host_->on_error(error_code_e::PORT_CONFIGURATION_MISSING); + } + } else { + host_->on_error(error_code_e::CONFIGURATION_MISSING); + } + + return its_info; } std::shared_ptr<endpoint> routing_manager_impl::create_client_endpoint( - const boost::asio::ip::address &_address, uint16_t _port, - bool _reliable) { - std::shared_ptr<endpoint> its_endpoint; - try { - if (_reliable) { - its_endpoint = std::make_shared < tcp_client_endpoint_impl - > (shared_from_this(), boost::asio::ip::tcp::endpoint( - _address, _port), io_); - - 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( - _address, _port), io_); - } - - client_endpoints_[_address][_port][_reliable] = its_endpoint; - its_endpoint->start(); - } catch (std::exception &e) { - host_->on_error(error_code_e::CLIENT_ENDPOINT_CREATION_FAILED); - } - - return its_endpoint; + const boost::asio::ip::address &_address, uint16_t _port, bool _reliable) { + std::shared_ptr<endpoint> its_endpoint; + try { + if (_reliable) { + its_endpoint = std::make_shared < tcp_client_endpoint_impl + > (shared_from_this(), boost::asio::ip::tcp::endpoint(_address, + _port), io_); + + 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(_address, + _port), io_); + } + + client_endpoints_[_address][_port][_reliable] = its_endpoint; + its_endpoint->start(); + } catch (std::exception &e) { + host_->on_error(error_code_e::CLIENT_ENDPOINT_CREATION_FAILED); + } + + return its_endpoint; } std::shared_ptr<endpoint> routing_manager_impl::find_client_endpoint( - 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()) { - auto found_port = found_address->second.find(_port); - if (found_port != found_address->second.end()) { - auto found_endpoint = found_port->second.find(_reliable); - if (found_endpoint != found_port->second.end()) { - its_endpoint = found_endpoint->second; - } - } - } - return its_endpoint; + 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()) { + auto found_port = found_address->second.find(_port); + if (found_port != found_address->second.end()) { + auto found_endpoint = found_port->second.find(_reliable); + if (found_endpoint != found_port->second.end()) { + its_endpoint = found_endpoint->second; + } + } + } + return its_endpoint; } std::shared_ptr<endpoint> routing_manager_impl::find_or_create_client_endpoint( - const boost::asio::ip::address &_address, uint16_t _port, - bool _reliable) { - std::shared_ptr<endpoint> its_endpoint = find_client_endpoint(_address, - _port, _reliable); - if (0 == its_endpoint) { - its_endpoint = create_client_endpoint(_address, _port, _reliable); - } - return its_endpoint; + const boost::asio::ip::address &_address, uint16_t _port, bool _reliable) { + std::unique_lock < std::recursive_mutex > its_lock(endpoint_mutex_); + std::shared_ptr<endpoint> its_endpoint = find_client_endpoint(_address, _port, + _reliable); + if (0 == its_endpoint) { + its_endpoint = create_client_endpoint(_address, _port, _reliable); + } + return its_endpoint; } std::shared_ptr<endpoint> routing_manager_impl::create_server_endpoint( - uint16_t _port, bool _reliable) { - std::shared_ptr<endpoint> its_endpoint; - - try { - boost::asio::ip::address its_unicast = configuration_->get_unicast(); - if (_reliable) { - its_endpoint = std::make_shared < tcp_server_endpoint_impl - > (shared_from_this(), boost::asio::ip::tcp::endpoint( - its_unicast, _port), io_); - if (configuration_->has_enabled_magic_cookies( - its_unicast.to_string(), _port)) { - its_endpoint->enable_magic_cookies(); - } - } else { - if (its_unicast.is_v4()) { - its_unicast = boost::asio::ip::address_v4::any(); - } else { - // TODO: how is "ANY" specified in IPv6? - } - its_endpoint = std::make_shared < udp_server_endpoint_impl - > (shared_from_this(), boost::asio::ip::udp::endpoint( - its_unicast, _port), io_); - } - - server_endpoints_[_port][_reliable] = its_endpoint; - its_endpoint->start(); - } catch (std::exception &e) { - host_->on_error(error_code_e::SERVER_ENDPOINT_CREATION_FAILED); - } - - return its_endpoint; + uint16_t _port, bool _reliable) { + std::shared_ptr<endpoint> its_endpoint; + + try { + boost::asio::ip::address its_unicast = configuration_->get_unicast(); + if (_reliable) { + its_endpoint = std::make_shared < tcp_server_endpoint_impl + > (shared_from_this(), boost::asio::ip::tcp::endpoint(its_unicast, + _port), io_); + if (configuration_->has_enabled_magic_cookies(its_unicast.to_string(), + _port)) { + its_endpoint->enable_magic_cookies(); + } + } else { + if (its_unicast.is_v4()) { + its_unicast = boost::asio::ip::address_v4::any(); + } else { + // TODO: how is "ANY" specified in IPv6? + } + its_endpoint = std::make_shared < udp_server_endpoint_impl + > (shared_from_this(), boost::asio::ip::udp::endpoint(its_unicast, + _port), io_); + } + + server_endpoints_[_port][_reliable] = its_endpoint; + its_endpoint->start(); + } catch (std::exception &e) { + host_->on_error(error_code_e::SERVER_ENDPOINT_CREATION_FAILED); + } + + return its_endpoint; } std::shared_ptr<endpoint> routing_manager_impl::find_server_endpoint( - uint16_t _port, bool _reliable) { - std::shared_ptr<endpoint> its_endpoint; - auto found_port = server_endpoints_.find(_port); - if (found_port != server_endpoints_.end()) { - auto found_endpoint = found_port->second.find(_reliable); - if (found_endpoint != found_port->second.end()) { - its_endpoint = found_endpoint->second; - } - } - return its_endpoint; + uint16_t _port, bool _reliable) { + std::shared_ptr<endpoint> its_endpoint; + auto found_port = server_endpoints_.find(_port); + if (found_port != server_endpoints_.end()) { + auto found_endpoint = found_port->second.find(_reliable); + if (found_endpoint != found_port->second.end()) { + its_endpoint = found_endpoint->second; + } + } + return its_endpoint; } std::shared_ptr<endpoint> routing_manager_impl::find_or_create_server_endpoint( - uint16_t _port, bool _reliable) { - std::shared_ptr<endpoint> its_endpoint = find_server_endpoint(_port, - _reliable); - if (0 == its_endpoint) { - its_endpoint = create_server_endpoint(_port, _reliable); - } - return its_endpoint; + uint16_t _port, bool _reliable) { + std::unique_lock < std::recursive_mutex > its_lock(endpoint_mutex_); + std::shared_ptr<endpoint> its_endpoint = find_server_endpoint(_port, + _reliable); + if (0 == its_endpoint) { + its_endpoint = create_server_endpoint(_port, _reliable); + } + return its_endpoint; } std::shared_ptr<endpoint> routing_manager_impl::find_local(client_t _client) { - std::unique_lock < std::recursive_mutex > its_lock(endpoint_mutex_); - std::shared_ptr<endpoint> its_endpoint; - auto found_endpoint = local_clients_.find(_client); - if (found_endpoint != local_clients_.end()) { - its_endpoint = found_endpoint->second; - } - return its_endpoint; + std::unique_lock < std::recursive_mutex > its_lock(endpoint_mutex_); + std::shared_ptr<endpoint> its_endpoint; + auto found_endpoint = local_clients_.find(_client); + if (found_endpoint != local_clients_.end()) { + its_endpoint = found_endpoint->second; + } + return its_endpoint; } std::shared_ptr<endpoint> routing_manager_impl::create_local(client_t _client) { - std::unique_lock < std::recursive_mutex > its_lock(endpoint_mutex_); + std::unique_lock < std::recursive_mutex > its_lock(endpoint_mutex_); - std::stringstream its_path; - its_path << base_path << std::hex << _client; + std::stringstream its_path; + its_path << base_path << std::hex << _client; - std::shared_ptr<endpoint> its_endpoint = - std::make_shared < local_client_endpoint_impl - > (shared_from_this(), boost::asio::local::stream_protocol::endpoint( - its_path.str()), io_); - local_clients_[_client] = its_endpoint; - its_endpoint->start(); - return its_endpoint; + std::shared_ptr<endpoint> its_endpoint = std::make_shared + < local_client_endpoint_impl + > (shared_from_this(), boost::asio::local::stream_protocol::endpoint( + its_path.str()), io_); + local_clients_[_client] = its_endpoint; + its_endpoint->start(); + return its_endpoint; } std::shared_ptr<endpoint> routing_manager_impl::find_or_create_local( - client_t _client) { - std::shared_ptr<endpoint> its_endpoint(find_local(_client)); - if (!its_endpoint) { - its_endpoint = create_local(_client); - } - return its_endpoint; + client_t _client) { + std::shared_ptr<endpoint> its_endpoint(find_local(_client)); + if (!its_endpoint) { + its_endpoint = create_local(_client); + } + return its_endpoint; } void routing_manager_impl::remove_local(client_t _client) { - std::unique_lock < std::recursive_mutex > its_lock(endpoint_mutex_); - std::shared_ptr<endpoint> its_endpoint = find_local(_client); - its_endpoint->stop(); - local_clients_.erase(_client); + std::unique_lock < std::recursive_mutex > its_lock(endpoint_mutex_); + std::shared_ptr<endpoint> its_endpoint = find_local(_client); + its_endpoint->stop(); + local_clients_.erase(_client); } -std::shared_ptr<endpoint> routing_manager_impl::find_local(service_t _service, - instance_t _instance) { - return find_local(find_local_client(_service, _instance)); +std::shared_ptr<endpoint> routing_manager_impl::find_local( + service_t _service, instance_t _instance) { + return find_local(find_local_client(_service, _instance)); } client_t routing_manager_impl::find_local_client(service_t _service, - instance_t _instance) { - client_t its_client(0); - auto found_service = local_services_.find(_service); - if (found_service != local_services_.end()) { - auto found_instance = found_service->second.find(_instance); - if (found_instance != found_service->second.end()) { - its_client = found_instance->second; - } - } - return its_client; + instance_t _instance) { + client_t its_client(0); + auto found_service = local_services_.find(_service); + if (found_service != local_services_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + its_client = found_instance->second; + } + } + return its_client; } instance_t routing_manager_impl::find_instance(service_t _service, - endpoint * _endpoint) { - instance_t its_instance(0xFFFF); - auto found_service = service_instances_.find(_service); - if (found_service != service_instances_.end()) { - auto found_endpoint = found_service->second.find(_endpoint); - if (found_endpoint != found_service->second.end()) { - its_instance = found_endpoint->second; - } - } - return its_instance; + endpoint * _endpoint) { + instance_t its_instance(0xFFFF); + auto found_service = service_instances_.find(_service); + if (found_service != service_instances_.end()) { + auto found_endpoint = found_service->second.find(_endpoint); + if (found_endpoint != found_service->second.end()) { + its_instance = found_endpoint->second; + } + } + return its_instance; } std::shared_ptr<endpoint> routing_manager_impl::find_remote_client( - service_t _service, instance_t _instance, bool _reliable) { - std::shared_ptr<endpoint> its_endpoint; - auto found_service = remote_services_.find(_service); - if (found_service != remote_services_.end()) { - auto found_instance = found_service->second.find(_instance); - if (found_instance != found_service->second.end()) { - auto found_reliability = found_instance->second.find(_reliable); - if (found_reliability != found_instance->second.end()) { - its_endpoint = found_reliability->second; - } - } - } - 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); - - if (its_endpoint->is_connected()) - host_->on_availability(_service, _instance, true); + service_t _service, instance_t _instance, bool _reliable) { + std::shared_ptr<endpoint> its_endpoint; + auto found_service = remote_services_.find(_service); + if (found_service != remote_services_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + auto found_reliability = found_instance->second.find(_reliable); + if (found_reliability != found_instance->second.end()) { + its_endpoint = found_reliability->second; + } + } + } + return its_endpoint; +} + +std::shared_ptr<event> routing_manager_impl::find_event(service_t _service, + instance_t _instance, + event_t _event) const { + std::shared_ptr<event> its_event; + auto find_service = events_.find(_service); + if (find_service != events_.end()) { + auto find_instance = find_service->second.find(_instance); + if (find_instance != find_service->second.end()) { + auto find_event = find_instance->second.find(_event); + if (find_event != find_instance->second.end()) { + its_event = find_event->second; + } + } + } + return its_event; +} + +std::set<std::shared_ptr<event> > routing_manager_impl::find_events( + service_t _service, instance_t _instance, eventgroup_t _eventgroup) { + std::set < std::shared_ptr<event> > its_events; + auto found_service = eventgroups_.find(_service); + if (found_service != eventgroups_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + auto found_eventgroup = found_instance->second.find(_eventgroup); + if (found_eventgroup != found_instance->second.end()) { + return found_eventgroup->second->get_events(); + } + } + } + return its_events; +} + +void routing_manager_impl::add_routing_info( + service_t _service, instance_t _instance, major_version_t _major, + minor_version_t _minor, ttl_t _ttl, + const boost::asio::ip::address &_address, uint16_t _port, bool _reliable) { + std::shared_ptr<serviceinfo> its_info(find_service(_service, _instance)); + if (!its_info) { + its_info = create_service(_service, _instance, _major, _minor, _ttl); + services_[_service][_instance] = its_info; + } + + std::shared_ptr<endpoint> its_endpoint( + find_or_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; + stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance); + + if (its_endpoint->is_connected()) + 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; - - // TODO: only tell the application if the service is completely gone - host_->on_availability(_service, _instance, false); - stub_->on_stop_offer_service(VSOMEIP_ROUTING_CLIENT, _service, - _instance); - - 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); - } - } + 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; + + // TODO: only tell the application if the service is completely gone + host_->on_availability(_service, _instance, false); + stub_->on_stop_offer_service(VSOMEIP_ROUTING_CLIENT, _service, _instance); + + 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::string its_address = configuration_->get_address(i.first, - i.second); - uint16_t its_reliable = configuration_->get_reliable_port(i.first, - i.second); - uint16_t its_unreliable = configuration_->get_unreliable_port(i.first, - i.second); - - if (VSOMEIP_INVALID_PORT != its_reliable) { - add_routing_info(i.first, i.second, - DEFAULT_MAJOR, DEFAULT_MINOR, DEFAULT_TTL, - boost::asio::ip::address::from_string(its_address), - its_reliable, true); - } - - if (VSOMEIP_INVALID_PORT != its_unreliable) { - add_routing_info(i.first, i.second, - DEFAULT_MAJOR, DEFAULT_MINOR, DEFAULT_TTL, - boost::asio::ip::address::from_string(its_address), - its_unreliable, false); - } - } -} - -} // namespace vsomeip + VSOMEIP_INFO + << "Service Discovery disabled. Using static routing information."; + for (auto i : configuration_->get_remote_services()) { + std::string its_address = configuration_->get_unicast(i.first, i.second); + uint16_t its_reliable = configuration_->get_reliable_port(i.first, + i.second); + uint16_t its_unreliable = configuration_->get_unreliable_port(i.first, + i.second); + + if (VSOMEIP_INVALID_PORT != its_reliable) { + add_routing_info(i.first, i.second, DEFAULT_MAJOR, DEFAULT_MINOR, + DEFAULT_TTL, + boost::asio::ip::address::from_string(its_address), + its_reliable, true); + } + + if (VSOMEIP_INVALID_PORT != its_unreliable) { + add_routing_info(i.first, i.second, DEFAULT_MAJOR, DEFAULT_MINOR, + DEFAULT_TTL, + boost::asio::ip::address::from_string(its_address), + its_unreliable, false); + } + } +} + +void routing_manager_impl::init_event_routing_info() { + // TODO: the following should be done before(!) initializing + // the configuration object to allow the configuration to + // directly write to the target structure! + std::map<service_t, std::map<instance_t, std::set<event_t> > > its_events = + configuration_->get_events(); + for (auto i : its_events) { + for (auto j : i.second) { + for (auto k : j.second) { + std::shared_ptr<event> its_event(std::make_shared < event > (this)); + its_event->set_service(i.first); + its_event->set_instance(j.first); + its_event->set_event(k); + configuration_->set_event(its_event); + events_[i.first][j.first][k] = its_event; + } + } + } + + std::map<service_t, + std::map<instance_t, std::map<eventgroup_t, std::set<event_t> > > > its_eventgroups = + configuration_->get_eventgroups(); + for (auto i : its_eventgroups) { + for (auto j : i.second) { + for (auto k : j.second) { + eventgroups_[i.first][j.first][k.first] = std::make_shared< + eventgroupinfo>(); + for (auto l : k.second) { + std::shared_ptr<event> its_event = find_event(i.first, j.first, l); + if (its_event) { + eventgroups_[i.first][j.first][k.first]->add_event(its_event); + } + } + } + } + } + +#if 1 + for (auto i : eventgroups_) { + for (auto j : i.second) { + for (auto k : j.second) { + VSOMEIP_DEBUG << "Eventgroup [" << std::hex << std::setw(4) + << std::setfill('0') << i.first << "." << j.first << "." << k.first + << "] (MC: "; + for (auto l : k.second->get_events()) { + VSOMEIP_DEBUG << " Event " << std::hex << std::setw(4) + << std::setfill('0') << l->get_event(); + } + } + } + } +#endif +} + +void routing_manager_impl::add_subscription( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + const boost::asio::ip::address &_address, uint16_t _reliable_port, + uint16_t _unreliable_port) { + + VSOMEIP_INFO << "ADDING A SUBSCRIPTION FOR EVENT [" << std::hex + << std::setw(4) << std::setfill('0') << _service << "." << _instance + << "." << _eventgroup << "] for " << _address.to_string() << ":" + << std::dec << _unreliable_port; + +} + +void routing_manager_impl::del_subscription( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + const boost::asio::ip::address &_address, uint16_t _reliable_port, + uint16_t _unreliable_port) { + +} + +} // namespace vsomeip diff --git a/implementation/routing/src/routing_manager_proxy.cpp b/implementation/routing/src/routing_manager_proxy.cpp index e1fdafb..dc6de94 100644 --- a/implementation/routing/src/routing_manager_proxy.cpp +++ b/implementation/routing/src/routing_manager_proxy.cpp @@ -11,16 +11,16 @@ #include <vsomeip/constants.hpp> #include <vsomeip/logger.hpp> +#include "../include/event.hpp" #include "../include/routing_manager_host.hpp" #include "../include/routing_manager_proxy.hpp" #include "../../configuration/include/internal.hpp" #include "../../endpoints/include/local_client_endpoint_impl.hpp" #include "../../endpoints/include/local_server_endpoint_impl.hpp" -#include "../../message/include/byteorder.hpp" #include "../../message/include/deserializer.hpp" -#include "../../message/include/event_impl.hpp" #include "../../message/include/serializer.hpp" #include "../../service_discovery/include/runtime.hpp" +#include "../../utility/include/byteorder.hpp" #include "../../utility/include/utility.hpp" namespace vsomeip { diff --git a/implementation/routing/src/servicegroup.cpp b/implementation/routing/src/servicegroup.cpp index ffdcbac..8818c1b 100644 --- a/implementation/routing/src/servicegroup.cpp +++ b/implementation/routing/src/servicegroup.cpp @@ -57,7 +57,7 @@ bool servicegroup::remove_service(service_t _service, instance_t _instance) { return its_result; } -service_map_t servicegroup::get_services() const { +services_t servicegroup::get_services() const { return services_; } diff --git a/implementation/routing/src/serviceinfo.cpp b/implementation/routing/src/serviceinfo.cpp index a991466..5fa932a 100644 --- a/implementation/routing/src/serviceinfo.cpp +++ b/implementation/routing/src/serviceinfo.cpp @@ -8,62 +8,88 @@ namespace vsomeip { -serviceinfo::serviceinfo(major_version_t _major, minor_version_t _minor, ttl_t _ttl) - : group_(0), major_(_major), minor_(_minor), ttl_(_ttl) { +serviceinfo::serviceinfo(major_version_t _major, minor_version_t _minor, + ttl_t _ttl) + : group_(0), + major_(_major), + minor_(_minor), + ttl_(_ttl), + reliable_(nullptr), + unreliable_(nullptr), + multicast_group_(0xFFFF) { } serviceinfo::~serviceinfo() { } servicegroup * serviceinfo::get_group() const { - return group_; + return group_; } void serviceinfo::set_group(servicegroup *_group) { - group_ = _group; + group_ = _group; } major_version_t serviceinfo::get_major() const { - return major_; + return major_; } minor_version_t serviceinfo::get_minor() const { - return minor_; + return minor_; } ttl_t serviceinfo::get_ttl() const { - return ttl_; + return ttl_; } void serviceinfo::set_ttl(ttl_t _ttl) { - ttl_ = _ttl; + ttl_ = _ttl; } -std::shared_ptr< endpoint > & serviceinfo::get_endpoint(bool _reliable) { - if (_reliable) - return reliable_; +std::shared_ptr<endpoint> serviceinfo::get_endpoint(bool _reliable) const { + return (_reliable ? reliable_ : unreliable_); +} - return unreliable_; +void serviceinfo::set_endpoint(std::shared_ptr<endpoint> _endpoint, + bool _reliable) { + if (_reliable) { + reliable_ = _endpoint; + } else { + unreliable_ = _endpoint; + } } -void serviceinfo::set_endpoint(std::shared_ptr< endpoint > &_endpoint, bool _reliable) { - if (_reliable) { - reliable_ = _endpoint; - } else { - unreliable_ = _endpoint; - } +const std::string & serviceinfo::get_multicast_address() const { + return multicast_address_; } -void serviceinfo::add_client(client_t _client) { - requesters_.insert(_client); +void serviceinfo::set_multicast_address(const std::string &_multicast_address) { + multicast_address_ = _multicast_address; } -void serviceinfo::remove_client(client_t _client) { - requesters_.erase(_client); +uint16_t serviceinfo::get_multicast_port() const { + return multicast_port_; +} + +void serviceinfo::set_multicast_port(uint16_t _multicast_port) { + multicast_port_ = _multicast_port; +} + +eventgroup_t serviceinfo::get_multicast_group() const { + return multicast_group_; } +void serviceinfo::set_multicast_group(eventgroup_t _multicast_group) { + multicast_group_ = _multicast_group; +} -} // namespace vsomeip +void serviceinfo::add_client(client_t _client) { + requesters_.insert(_client); +} +void serviceinfo::remove_client(client_t _client) { + requesters_.erase(_client); +} +} // namespace vsomeip diff --git a/implementation/runtime/src/application_impl.cpp b/implementation/runtime/src/application_impl.cpp index 00d388a..8d9eb73 100644 --- a/implementation/runtime/src/application_impl.cpp +++ b/implementation/runtime/src/application_impl.cpp @@ -194,9 +194,10 @@ void application_impl::send(std::shared_ptr<message> _message, bool _flush, } } -void application_impl::set(service_t _service, instance_t _instance, event_t, +void application_impl::set(service_t _service, instance_t _instance, event_t _event, const std::shared_ptr<payload> &_payload) { - + if (routing_) + routing_->set(client_, _service, _instance, _event, _payload); } void application_impl::register_event_handler(event_handler_t _handler) { diff --git a/implementation/service_discovery/include/constants.hpp b/implementation/service_discovery/include/constants.hpp index 832e87b..598823e 100644 --- a/implementation/service_discovery/include/constants.hpp +++ b/implementation/service_discovery/include/constants.hpp @@ -28,8 +28,8 @@ const uint8_t reserved_byte = 0x0; const uint16_t reserved_word = 0x0; const uint32_t reserved_long = 0x0; -const uint8_t udp = 0x06; -const uint8_t tcp = 0x11; +const uint8_t tcp = 0x06; +const uint8_t udp = 0x11; } // namespace protocol } // namespace sd diff --git a/implementation/service_discovery/include/request.hpp b/implementation/service_discovery/include/request.hpp new file mode 100644 index 0000000..28d1fa8 --- /dev/null +++ b/implementation/service_discovery/include/request.hpp @@ -0,0 +1,42 @@ +// Copyright (C) 2014 BMW Group +// Author: Lutz Bichler (lutz.bichler@bmw.de) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_SD_REQUEST_HPP +#define VSOMEIP_SD_REQUEST_HPP + +#include <memory> + +#include <vsomeip/primitive_types.hpp> + +namespace vsomeip { + +class endpoint; + +namespace sd { + +class request { +public: + request(major_version_t _major, minor_version_t _minor, ttl_t _ttl); + + major_version_t get_major() const; + void set_major(major_version_t _major); + + minor_version_t get_minor() const; + void set_minor(minor_version_t _minor); + + ttl_t get_ttl() const; + void set_ttl(ttl_t _ttl); + +private: + major_version_t major_; + minor_version_t minor_; + ttl_t ttl_; +}; + +} // namespace sd +} // namespace vsomeip + +#endif // VSOMEIP_SD_SUBSCRIPTION_HPP diff --git a/implementation/service_discovery/include/service_discovery.hpp b/implementation/service_discovery/include/service_discovery.hpp index d2fab83..47455a0 100644 --- a/implementation/service_discovery/include/service_discovery.hpp +++ b/implementation/service_discovery/include/service_discovery.hpp @@ -19,9 +19,7 @@ namespace sd { class service_discovery { public: - virtual ~service_discovery() { - } - ; + virtual ~service_discovery() {}; virtual std::shared_ptr<configuration> get_configuration() const = 0; virtual boost::asio::io_service & get_io() = 0; diff --git a/implementation/service_discovery/include/service_discovery_host.hpp b/implementation/service_discovery/include/service_discovery_host.hpp index 4679e0e..dbd5a16 100644 --- a/implementation/service_discovery/include/service_discovery_host.hpp +++ b/implementation/service_discovery/include/service_discovery_host.hpp @@ -13,40 +13,65 @@ #include <boost/asio/ip/address.hpp> #include <boost/asio/io_service.hpp> -#include "../../routing/include/routing_types.hpp" +#include "../../routing/include/types.hpp" namespace vsomeip { class configuration; +class endpoint; namespace sd { class service_discovery_host { -public: - virtual ~service_discovery_host() {}; - - virtual boost::asio::io_service & get_io() = 0; - virtual std::shared_ptr<configuration> get_configuration() const = 0; - - virtual void create_service_discovery_endpoint(const std::string &_address, - uint16_t _port, const std::string &_protocol) = 0; - - virtual service_map_t get_offered_services( - const std::string &_name) const = 0; - - virtual bool 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; + public: + virtual ~service_discovery_host() {}; + + virtual boost::asio::io_service & get_io() = 0; + virtual std::shared_ptr<configuration> get_configuration() const = 0; + + virtual void create_service_discovery_endpoint(const std::string &_address, + uint16_t _port, + bool _reliable) = 0; + + virtual services_t get_offered_services(const std::string &_name) const = 0; + virtual std::shared_ptr<eventgroupinfo> find_eventgroup( + service_t _service, instance_t _instance, + eventgroup_t _eventgroup) const = 0; + + virtual bool send(client_t _client, std::shared_ptr<message> _message, + bool _flush, bool _reliable) = 0; + + virtual bool send_subscribe(const boost::asio::ip::address &_address, + uint16_t _port, bool _reliable, + const byte_t *_data, uint32_t _size) = 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; + + virtual void add_subscription(service_t _service, instance_t _instance, + eventgroup_t _eventgroup, + const boost::asio::ip::address &_address, + uint16_t _reliable_port, + uint16_t _unreliable_port) = 0; + + virtual void del_subscription(service_t _service, instance_t _instance, + eventgroup_t _eventgroup, + const boost::asio::ip::address &_address, + uint16_t _reliable_port, + uint16_t _unreliable_port) = 0; + + virtual std::shared_ptr<endpoint> find_remote_client(service_t _service, + instance_t _instance, + bool _reliable) = 0; }; -} // namespace sd -} // namespace vsomeip +} // namespace sd +} // namespace vsomeip #endif // VSOMEIP_SERVICE_DISCOVERY_HOST_HPP diff --git a/implementation/service_discovery/include/service_discovery_impl.hpp b/implementation/service_discovery/include/service_discovery_impl.hpp index d1cb3e1..1393bdb 100644 --- a/implementation/service_discovery/include/service_discovery_impl.hpp +++ b/implementation/service_discovery/include/service_discovery_impl.hpp @@ -9,78 +9,123 @@ #include <map> #include <memory> +#include <mutex> #include <set> +#include <boost/asio/ip/address.hpp> + #include "service_discovery.hpp" -#include "../../routing/include/routing_types.hpp" +#include "../../routing/include/types.hpp" namespace vsomeip { class endpoint; +class serializer; namespace sd { +class entry_impl; class eventgroupentry_impl; class option_impl; +class request; class serviceentry_impl; class service_discovery_fsm; class service_discovery_host; - -class service_discovery_impl: public service_discovery, - public std::enable_shared_from_this<service_discovery_impl> { -public: - service_discovery_impl(service_discovery_host *_host); - virtual ~service_discovery_impl(); - - std::shared_ptr<configuration> get_configuration() const; - boost::asio::io_service & get_io(); - - void init(); - void start(); - void stop(); - - 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); - - void subscribe(service_t _service, instance_t _instance, - eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl); - void unsubscribe(service_t _service, instance_t _instance, - eventgroup_t _eventgroup); - - void send(const std::string &_name, bool _is_announcing); - - 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_; - - std::shared_ptr<deserializer> deserializer_; - - std::shared_ptr<service_discovery_fsm> default_; - std::map<std::string, std::shared_ptr<service_discovery_fsm> > additional_; - - service_map_t requested_; - eventgroup_map_t subscribed_; - - // Sessions - // TODO: handle session id per unicast peer and multicast +class subscription; + +class service_discovery_impl : public service_discovery, + public std::enable_shared_from_this<service_discovery_impl> { + public: + service_discovery_impl(service_discovery_host *_host); + virtual ~service_discovery_impl(); + + std::shared_ptr<configuration> get_configuration() const; + boost::asio::io_service & get_io(); + + void init(); + void start(); + void stop(); + + 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); + + void subscribe(service_t _service, instance_t _instance, + eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl); + void unsubscribe(service_t _service, instance_t _instance, + eventgroup_t _eventgroup); + + void send(const std::string &_name, bool _is_announcing); + + void on_message(const byte_t *_data, length_t _length); + + private: + void insert_option(std::shared_ptr<message_impl> &_message, + std::shared_ptr<entry_impl> _entry, + const boost::asio::ip::address &_address, uint16_t _port, + bool _is_reliable); + void insert_service_entries(std::shared_ptr<message_impl> &_message, + services_t &_services, bool _is_offer); + void insert_subscription(std::shared_ptr<message_impl> &_message, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, + std::shared_ptr<subscription> &_subscription, + bool _is_subscription); + void insert_subscription_ack(std::shared_ptr<message_impl> &_message, + service_t _service, instance_t _instance, + eventgroup_t _eventgroup, + std::shared_ptr<eventgroupinfo> &_info, + bool _is_subscription); + + 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); + + void handle_service_availability(service_t _service, instance_t _instance, + major_version_t _major, + minor_version_t _minor, ttl_t _ttl, + const boost::asio::ip::address &_address, + uint16_t _port, bool _reliable); + void handle_eventgroup_subscription( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + major_version_t _major, ttl_t _ttl, + const boost::asio::ip::address &_reliable_address, + uint16_t _reliable_port, uint16_t _unreliable_port); + void handle_eventgroup_subscription_ack( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + major_version_t _major, ttl_t _ttl, + const boost::asio::ip::address &_address, uint16_t _port); + + private: + boost::asio::io_service &io_; + service_discovery_host *host_; + + boost::asio::ip::address unicast_; + uint16_t port_; + bool reliable_; + + std::shared_ptr<serializer> serializer_; + std::shared_ptr<deserializer> deserializer_; + + std::shared_ptr<service_discovery_fsm> default_; + std::map<std::string, std::shared_ptr<service_discovery_fsm> > additional_; + + std::map<service_t, std::map<instance_t, std::shared_ptr<request> > > requested_; + std::map<service_t, + std::map<instance_t, + std::map<eventgroup_t, std::shared_ptr<subscription> > > > subscribed_; + + std::mutex serialize_mutex_; + + // Sessions + std::map<boost::asio::ip::address, session_t> sessions_; }; -} // namespace sd -} // namespace vsomeip +} // namespace sd +} // namespace vsomeip #endif // VSOMEIP_SERVICE_DISCOVERY_IMPL diff --git a/implementation/service_discovery/include/subscription.hpp b/implementation/service_discovery/include/subscription.hpp new file mode 100644 index 0000000..098bccf --- /dev/null +++ b/implementation/service_discovery/include/subscription.hpp @@ -0,0 +1,49 @@ +// Copyright (C) 2014 BMW Group +// Author: Lutz Bichler (lutz.bichler@bmw.de) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef VSOMEIP_SD_SUBSCRIPTION_HPP +#define VSOMEIP_SD_SUBSCRIPTION_HPP + +#include <memory> + +#include <vsomeip/primitive_types.hpp> + +namespace vsomeip { + +class endpoint; + +namespace sd { + +class subscription { +public: + subscription(major_version_t _major, ttl_t _ttl, + std::shared_ptr<endpoint> _reliable, + std::shared_ptr<endpoint> _unreliable); + ~subscription(); + + major_version_t get_major() const; + ttl_t get_ttl() const; + void set_ttl(ttl_t _ttl); + std::shared_ptr<endpoint> get_endpoint(bool _reliable) const; + void set_endpoint(std::shared_ptr<endpoint> _endpoint, bool _reliable); + + bool is_acknowleged() const; + void set_acknowledged(bool _is_acknowledged); + +private: + major_version_t major_; + ttl_t ttl_; + + std::shared_ptr<endpoint> reliable_; + std::shared_ptr<endpoint> unreliable_; + + bool is_acknowledged_; +}; + +} // namespace sd +} // namespace vsomeip + +#endif // VSOMEIP_SD_SUBSCRIPTION_HPP diff --git a/implementation/service_discovery/src/request.cpp b/implementation/service_discovery/src/request.cpp new file mode 100644 index 0000000..2637a3f --- /dev/null +++ b/implementation/service_discovery/src/request.cpp @@ -0,0 +1,44 @@ +// Copyright (C) 2014 BMW Group +// Author: Lutz Bichler (lutz.bichler@bmw.de) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/request.hpp" + +namespace vsomeip { +namespace sd { + +request::request(major_version_t _major, minor_version_t _minor, ttl_t _ttl) + : major_(_major), + minor_(_minor), + ttl_(_ttl) { + +} + +major_version_t request::get_major() const { + return major_; +} + +void request::set_major(major_version_t _major) { + major_ = _major; +} + +minor_version_t request::get_minor() const { + return minor_; +} + +void request::set_minor(minor_version_t _minor) { + minor_ = _minor; +} + +ttl_t request::get_ttl() const { + return ttl_; +} + +void request::set_ttl(ttl_t _ttl) { + ttl_ = _ttl; +} + +} // 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 4c44699..1f99c8a 100644 --- a/implementation/service_discovery/src/service_discovery_impl.cpp +++ b/implementation/service_discovery/src/service_discovery_impl.cpp @@ -15,335 +15,610 @@ #include "../include/ipv4_option_impl.hpp" #include "../include/ipv6_option_impl.hpp" #include "../include/message_impl.hpp" +#include "../include/request.hpp" #include "../include/runtime.hpp" #include "../include/service_discovery_fsm.hpp" #include "../include/service_discovery_host.hpp" #include "../include/service_discovery_impl.hpp" #include "../include/serviceentry_impl.hpp" +#include "../include/subscription.hpp" #include "../../configuration/include/internal.hpp" +#include "../../endpoints/include/endpoint.hpp" #include "../../endpoints/include/tcp_server_endpoint_impl.hpp" #include "../../endpoints/include/udp_server_endpoint_impl.hpp" +#include "../../message/include/serializer.hpp" +#include "../../routing/include/eventgroupinfo.hpp" #include "../../routing/include/servicegroup.hpp" #include "../../routing/include/serviceinfo.hpp" namespace vsomeip { namespace sd { -service_discovery_impl::service_discovery_impl(service_discovery_host *_host) : - host_(_host), io_(_host->get_io()), default_( - std::make_shared < service_discovery_fsm > ("default", this)), deserializer_( - std::make_shared<deserializer>()) { +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)), + serializer_(std::make_shared<serializer>()), + deserializer_(std::make_shared<deserializer>()) { } service_discovery_impl::~service_discovery_impl() { } std::shared_ptr<configuration> service_discovery_impl::get_configuration() const { - return host_->get_configuration(); + return host_->get_configuration(); } boost::asio::io_service & service_discovery_impl::get_io() { - return io_; + return io_; } void service_discovery_impl::init() { - std::shared_ptr<configuration> its_configuration = - host_->get_configuration(); - if (its_configuration) { - std::set < std::string > its_servicegroups = - its_configuration->get_servicegroups(); - for (auto its_group : its_servicegroups) { - if (its_group != "default" - && its_configuration->is_local_servicegroup(its_group)) { - additional_[its_group] = std::make_shared - < service_discovery_fsm > (its_group, this); - } - } - } else { - VSOMEIP_ERROR << "SD: no configuration found!"; - } - - host_->create_service_discovery_endpoint( - its_configuration->get_service_discovery_multicast(), - its_configuration->get_service_discovery_port(), - its_configuration->get_service_discovery_protocol()); + std::shared_ptr<configuration> its_configuration = host_->get_configuration(); + if (its_configuration) { + unicast_ = its_configuration->get_unicast(); + + std::set < std::string > its_servicegroups = its_configuration + ->get_servicegroups(); + for (auto its_group : its_servicegroups) { + if (its_group != "default" + && its_configuration->is_local_servicegroup(its_group)) { + additional_[its_group] = std::make_shared < service_discovery_fsm + > (its_group, this); + } + } + + port_ = its_configuration->get_service_discovery_port(); + reliable_ = (its_configuration->get_service_discovery_protocol() == "tcp"); + + serializer_->create_data(reliable_ ? + VSOMEIP_MAX_TCP_MESSAGE_SIZE : + VSOMEIP_MAX_UDP_MESSAGE_SIZE); + + host_->create_service_discovery_endpoint( + its_configuration->get_service_discovery_multicast(), port_, reliable_); + + } else { + VSOMEIP_ERROR << "SD: no configuration found!"; + } } void service_discovery_impl::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()); - } + 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::request_service(service_t _service, - instance_t _instance, major_version_t _major, minor_version_t _minor, - ttl_t _ttl) { - auto find_service = requested_.find(_service); - if (find_service != requested_.end()) { - auto find_instance = find_service->second.find(_instance); - if (find_instance != find_service->second.end()) { - // TODO: check version and report errors - } else { - find_service->second[_instance] - = std::make_shared< serviceinfo>(_major, _minor, _ttl); - } - } else { - requested_[_service][_instance] - = std::make_shared<serviceinfo>(_major, _minor, _ttl); - } + instance_t _instance, + major_version_t _major, + minor_version_t _minor, + ttl_t _ttl) { + auto find_service = requested_.find(_service); + if (find_service != requested_.end()) { + auto find_instance = find_service->second.find(_instance); + if (find_instance != find_service->second.end()) { + // TODO: check version and report errors + } else { + find_service->second[_instance] + = std::make_shared<request>(_major, _minor, _ttl); + } + } else { + requested_[_service][_instance] + = std::make_shared<request>(_major, _minor, _ttl); + } } void service_discovery_impl::release_service(service_t _service, - instance_t _instance) { - auto find_service = requested_.find(_service); - if (find_service != requested_.end()) { - find_service->second.erase(_instance); - } + instance_t _instance) { + auto find_service = requested_.find(_service); + if (find_service != requested_.end()) { + find_service->second.erase(_instance); + } } void service_discovery_impl::subscribe(service_t _service, instance_t _instance, - eventgroup_t _eventgroup, major_version_t _major, ttl_t _ttl) { - auto found_service = subscribed_.find(_service); - if (found_service != subscribed_.end()) { - auto found_instance = found_service->second.find(_instance); - if (found_instance != found_service->second.end()) { - auto found_eventgroup = found_instance->second.find(_eventgroup); - if (found_eventgroup != found_instance->second.end()) { - - } else { - - } - } else { - // insert new subscription - } - } else { - // insert new subscription - } + eventgroup_t _eventgroup, + major_version_t _major, ttl_t _ttl) { + auto found_service = subscribed_.find(_service); + if (found_service != subscribed_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + auto found_eventgroup = found_instance->second.find(_eventgroup); + if (found_eventgroup != found_instance->second.end()) { + if (found_eventgroup->second->get_major() == _major) { + found_eventgroup->second->set_ttl(_ttl); + } else { + VSOMEIP_ERROR << "Subscriptions to different versions of the same " + "service instance are not supported!"; + } + return; + } + } + } + + std::shared_ptr<endpoint> its_reliable + = host_->find_remote_client(_service, _instance, true); + std::shared_ptr<endpoint> its_unreliable + = host_->find_remote_client(_service, _instance, false); + std::shared_ptr<subscription> its_subscription + = std::make_shared<subscription>(_major, _ttl, + its_reliable, its_unreliable); + subscribed_[_service][_instance][_eventgroup] = its_subscription; } void service_discovery_impl::unsubscribe(service_t _service, - instance_t _instance, eventgroup_t _eventgroup) { - + instance_t _instance, + eventgroup_t _eventgroup) { + auto found_service = subscribed_.find(_service); + if (found_service != subscribed_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + auto found_eventgroup = found_instance->second.find(_eventgroup); + if (found_eventgroup != found_instance->second.end()) { + found_eventgroup->second->set_ttl(0); // is read once and removed afterwards! + } + } + } } -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_option( + std::shared_ptr<message_impl> &_message, std::shared_ptr<entry_impl> _entry, + const boost::asio::ip::address &_address, uint16_t _port, bool _is_reliable) { + if (unicast_ == _address) { + if (unicast_.is_v4()) { + ipv4_address_t its_address = unicast_.to_v4().to_bytes(); + 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(_port); + its_option->set_udp(!_is_reliable); + _entry->assign_option(its_option, 1); + } + } else { + ipv6_address_t its_address = unicast_.to_v6().to_bytes(); + 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(_port); + its_option->set_udp(!_is_reliable); + _entry->assign_option(its_option, 1); + } + } + } else { + if (_address.is_v4()) { + ipv4_address_t its_address = _address.to_v4().to_bytes(); + std::shared_ptr<ipv4_option_impl> its_option + = _message->create_ipv4_option(true); + if (its_option) { + its_option->set_address(its_address); + its_option->set_port(_port); + _entry->assign_option(its_option, 1); + } + } else { + ipv6_address_t its_address = _address.to_v6().to_bytes(); + std::shared_ptr<ipv6_option_impl> its_option + = _message->create_ipv6_option(true); + if (its_option) { + its_option->set_address(its_address); + its_option->set_port(_port); + _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) { - for (auto its_service : _services) { - for (auto its_instance : its_service.second) { - auto its_info = its_instance.second; - std::shared_ptr<serviceentry_impl> its_entry = - _message->create_service_entry(); - if (its_entry) { - its_entry->set_type( - (_is_offer ? - entry_type_e::OFFER_SERVICE : - entry_type_e::FIND_SERVICE)); - its_entry->set_service(its_service.first); - its_entry->set_instance(its_instance.first); - its_entry->set_major_version(its_info->get_major()); - its_entry->set_minor_version(its_info->get_minor()); - its_entry->set_ttl(its_info->get_ttl()); - - std::shared_ptr<endpoint> its_endpoint = its_info->get_endpoint( - true); - if (its_endpoint) { - insert_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 { - VSOMEIP_ERROR << "Failed to create service entry."; - } - } - } + std::shared_ptr<message_impl> &_message, services_t &_services, + bool _is_offer) { + for (auto its_service : _services) { + for (auto its_instance : its_service.second) { + auto its_info = its_instance.second; + std::shared_ptr<serviceentry_impl> its_entry = _message + ->create_service_entry(); + if (its_entry) { + its_entry->set_type( + (_is_offer ? + entry_type_e::OFFER_SERVICE : entry_type_e::FIND_SERVICE)); + its_entry->set_service(its_service.first); + its_entry->set_instance(its_instance.first); + its_entry->set_major_version(its_info->get_major()); + its_entry->set_minor_version(its_info->get_minor()); + its_entry->set_ttl(its_info->get_ttl()); + + std::shared_ptr<endpoint> its_endpoint = its_info->get_endpoint(true); + if (its_endpoint) { + insert_option(_message, its_entry, unicast_, its_endpoint->get_port(), true); + if (0 == its_info->get_ttl()) { + host_->del_routing_info(its_service.first, its_instance.first, + true); + } + } + + its_endpoint = its_info->get_endpoint(false); + if (its_endpoint) { + insert_option(_message, its_entry, unicast_, its_endpoint->get_port(), false); + if (0 == its_info->get_ttl()) { + host_->del_routing_info(its_service.first, its_instance.first, + false); + } + } + } else { + VSOMEIP_ERROR << "Failed to create service entry."; + } + } + } +} + +void service_discovery_impl::insert_subscription( + std::shared_ptr<message_impl> &_message, service_t _service, + instance_t _instance, eventgroup_t _eventgroup, + std::shared_ptr<subscription> &_subscription, bool _is_subscription) { + std::shared_ptr<eventgroupentry_impl> its_entry = _message + ->create_eventgroup_entry(); + its_entry->set_type(entry_type_e::SUBSCRIBE_EVENTGROUP); + its_entry->set_service(_service); + its_entry->set_instance(_instance); + its_entry->set_eventgroup(_eventgroup); + its_entry->set_major_version(_subscription->get_major()); + its_entry->set_ttl(_subscription->get_ttl()); + std::shared_ptr<endpoint> its_endpoint = _subscription->get_endpoint(true); + if (its_endpoint) { + insert_option(_message, its_entry, unicast_, its_endpoint->get_port(), true); + } + its_endpoint = _subscription->get_endpoint(false); + if (its_endpoint) { + insert_option(_message, its_entry, unicast_, its_endpoint->get_port(), false); + } +} + +void service_discovery_impl::insert_subscription_ack( + std::shared_ptr<message_impl> &_message, service_t _service, + instance_t _instance, eventgroup_t _eventgroup, + std::shared_ptr<eventgroupinfo> &_info, bool _is_subscription) { + std::shared_ptr<eventgroupentry_impl> its_entry + = _message->create_eventgroup_entry(); + its_entry->set_type(entry_type_e::SUBSCRIBE_EVENTGROUP_ACK); + its_entry->set_service(_service); + its_entry->set_instance(_instance); + its_entry->set_eventgroup(_eventgroup); + its_entry->set_major_version(_info->get_major()); + its_entry->set_ttl(_info->get_ttl()); + + boost::asio::ip::address its_address; + uint16_t its_port; + if (_info->get_multicast(its_address, its_port)) { + insert_option(_message, its_entry, its_address, its_port, false); + } } void service_discovery_impl::send(const std::string &_name, - bool _is_announcing) { - std::shared_ptr<message_impl> its_message = - runtime::get()->create_message(); + bool _is_announcing) { + std::shared_ptr<message_impl> its_message = runtime::get()->create_message(); - // TODO: optimize building of SD message (common options, utilize the two runs) + // TODO: optimize building of SD message (common options, utilize the two runs) - // If we are the default group and not in main phase, include "FindOffer"-entries - if (_name == "default" && !_is_announcing) { - insert_service_entries(its_message, requested_, false); - } + // If we are the default group and not in main phase, include "FindOffer"-entries + if (_name == "default" && !_is_announcing) { + //insert_service_entries(its_message, requested_, false); + } - // Always include the "OfferService"-entries for the service group - service_map_t its_offers = host_->get_offered_services(_name); - insert_service_entries(its_message, its_offers, true); + // Always include the "OfferService"-entries for the service group + services_t its_offers = host_->get_offered_services(_name); + insert_service_entries(its_message, its_offers, true); - // Serialize and send - host_->send(VSOMEIP_SD_CLIENT, its_message, true, false); + // Serialize and send + if (its_message->get_entries().size() > 0) + host_->send(VSOMEIP_SD_CLIENT, its_message, true, false); } // 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(); + 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) { - 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); - } - } - } + deserializer_->set_data(_data, _length); + std::shared_ptr<message_impl> its_message( + deserializer_->deserialize_sd_message()); + if (its_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(); - - 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; - } - } - } + 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(); + + 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(); + + handle_service_availability(its_service, its_instance, its_major, + its_minor, its_ttl, its_address, + its_option_port, + !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(); + + handle_service_availability(its_service, its_instance, its_major, + its_minor, its_ttl, its_address, + its_option_port, + !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."; + 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(); + entry_type_e its_type = _entry->get_type(); + major_version_t its_major = _entry->get_major_version(); + ttl_t its_ttl = _entry->get_ttl(); + + boost::asio::ip::address its_reliable_address; + uint16_t its_reliable_port = VSOMEIP_INVALID_PORT; + boost::asio::ip::address its_unreliable_address; + uint16_t its_unreliable_port = VSOMEIP_INVALID_PORT; + + for (auto i : { 1, 2 }) { + for (auto its_index : _entry->get_options(i)) { + std::vector<byte_t> its_option_address; + std::shared_ptr<option_impl> its_option = _options[its_index]; + switch (its_option->get_type()) { + case option_type_e::IP4_ENDPOINT: { + if (entry_type_e::SUBSCRIBE_EVENTGROUP == _entry->get_type()) { + std::shared_ptr<ipv4_option_impl> its_ipv4_option = + std::dynamic_pointer_cast < ipv4_option_impl > (its_option); + + boost::asio::ip::address_v4 its_ipv4_address( + its_ipv4_option->get_address()); + + // TODO: add error handling (port already set) here + if (its_ipv4_option->is_udp()) { + its_unreliable_address = its_ipv4_address; + its_unreliable_port = its_ipv4_option->get_port(); + } else { + its_reliable_address = its_ipv4_address; + its_reliable_port = its_ipv4_option->get_port(); + } + } else { + VSOMEIP_ERROR << "Invalid eventgroup option (IPv4 Endpoint)"; + } + break; + } + case option_type_e::IP6_ENDPOINT: { + if (entry_type_e::SUBSCRIBE_EVENTGROUP == _entry->get_type()) { + std::shared_ptr<ipv6_option_impl> its_ipv6_option = + std::dynamic_pointer_cast < ipv6_option_impl > (its_option); + + boost::asio::ip::address_v6 its_ipv6_address( + its_ipv6_option->get_address()); + + // TODO: add error handling (port already set) here + if (its_ipv6_option->is_udp()) { + its_unreliable_address = its_ipv6_address; + its_unreliable_port = its_ipv6_option->get_port(); + } else { + its_unreliable_address = its_ipv6_address; + its_reliable_port = its_ipv6_option->get_port(); + } + } else { + VSOMEIP_ERROR << "Invalid eventgroup option (IPv6 Endpoint)"; + } + break; + } + case option_type_e::IP4_MULTICAST: + if (entry_type_e::SUBSCRIBE_EVENTGROUP_ACK == _entry->get_type()) { + std::shared_ptr<ipv4_option_impl> its_ipv4_option = + std::dynamic_pointer_cast < ipv4_option_impl > (its_option); + + boost::asio::ip::address_v4 its_ipv4_address( + its_ipv4_option->get_address()); + + its_unreliable_address = its_ipv4_address; + its_unreliable_port = its_ipv4_option->get_port(); + } else { + VSOMEIP_ERROR << "Invalid eventgroup option (IPv4 Multicast)"; + } + break; + case option_type_e::IP6_MULTICAST: + if (entry_type_e::SUBSCRIBE_EVENTGROUP_ACK == _entry->get_type()) { + std::shared_ptr<ipv6_option_impl> its_ipv6_option = + std::dynamic_pointer_cast < ipv6_option_impl > (its_option); + + boost::asio::ip::address_v6 its_ipv6_address( + its_ipv6_option->get_address()); + + its_unreliable_address = its_ipv6_address; + its_unreliable_port = its_ipv6_option->get_port(); + } else { + VSOMEIP_ERROR << "Invalid eventgroup option (IPv6 Multicast)"; + } + break; + default: + VSOMEIP_WARNING << "Unsupported eventgroup option"; + break; + } + } + } + + if (entry_type_e::SUBSCRIBE_EVENTGROUP == its_type) { + handle_eventgroup_subscription( + its_service, + its_instance, + its_eventgroup, + its_major, + its_ttl, + (its_reliable_port != VSOMEIP_INVALID_PORT ? + its_reliable_address : its_unreliable_address), + its_reliable_port, its_unreliable_port); + } else { + handle_eventgroup_subscription_ack(its_service, its_instance, + its_eventgroup, its_major, its_ttl, + its_unreliable_address, + its_unreliable_port); + } +} + +void service_discovery_impl::handle_service_availability( + service_t _service, instance_t _instance, major_version_t _major, + minor_version_t _minor, ttl_t _ttl, + const boost::asio::ip::address &_address, uint16_t _port, bool _reliable) { + + if (0 < _ttl) { + host_->add_routing_info(_service, _instance, _major, _minor, _ttl, _address, + _port, _reliable); + + auto found_service = subscribed_.find(_service); + if (found_service != subscribed_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + if (0 < found_instance->second.size()) { + std::shared_ptr<message_impl> its_message = runtime::get() + ->create_message(); + for (auto its_eventgroup : found_instance->second) { + std::shared_ptr<subscription> its_subscription(its_eventgroup.second); + if (!its_subscription->is_acknowleged()) { + its_subscription->set_endpoint( + host_->find_remote_client(_service, _instance, true), true); + its_subscription->set_endpoint( + host_->find_remote_client(_service, _instance, false), false); + + // TODO: consume major & ttl + insert_subscription(its_message, _service, _instance, + its_eventgroup.first, its_subscription, true); + } + } + serializer_->serialize(its_message.get()); + host_->send_subscribe(_address, port_, reliable_, + serializer_->get_data(), + serializer_->get_size()); + serializer_->reset(); + } + } + } + } else { + auto found_service = subscribed_.find(_service); + if (found_service != subscribed_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + for (auto &its_eventgroup : found_instance->second) { + its_eventgroup.second->set_acknowledged(false); + } + } + } + host_->del_routing_info(_service, _instance, _reliable); + } +} + +void service_discovery_impl::handle_eventgroup_subscription( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + major_version_t _major, ttl_t _ttl, + const boost::asio::ip::address &_address, uint16_t _reliable_port, + uint16_t _unreliable_port) { + std::shared_ptr<message_impl> its_message = runtime::get()->create_message(); + if (its_message) { + std::shared_ptr<eventgroupinfo> its_info + = host_->find_eventgroup(_service, _instance, _eventgroup); + + // Could not find eventgroup --> send Nack + if (!its_info || _major > its_info->get_major() + || _ttl > its_info->get_ttl()) { + } else { + host_->add_subscription(_service, _instance, _eventgroup, _address, + _reliable_port, _unreliable_port); + } + + insert_subscription_ack(its_message, _service, _instance, _eventgroup, + its_info, false); + + serializer_->serialize(its_message.get()); + host_->send_subscribe(_address, port_, reliable_, serializer_->get_data(), + serializer_->get_size()); + serializer_->reset(); + } +} + +void service_discovery_impl::handle_eventgroup_subscription_ack( + service_t _service, instance_t _instance, eventgroup_t _eventgroup, + major_version_t _major, ttl_t _ttl, + const boost::asio::ip::address &_address, uint16_t _port) { + auto found_service = subscribed_.find(_service); + if (found_service != subscribed_.end()) { + auto found_instance = found_service->second.find(_instance); + if (found_instance != found_service->second.end()) { + auto found_eventgroup = found_instance->second.find(_eventgroup); + if (found_eventgroup != found_instance->second.end()) { + found_eventgroup->second->set_acknowledged(true); + } + } + } } -} // namespace sd -} // namespace vsomeip +} // namespace sd +} // namespace vsomeip diff --git a/implementation/service_discovery/src/subscription.cpp b/implementation/service_discovery/src/subscription.cpp new file mode 100644 index 0000000..19d115c --- /dev/null +++ b/implementation/service_discovery/src/subscription.cpp @@ -0,0 +1,58 @@ +// Copyright (C) 2014 BMW Group +// Author: Lutz Bichler (lutz.bichler@bmw.de) +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "../include/subscription.hpp" + +namespace vsomeip { +namespace sd { + +subscription::subscription(major_version_t _major, ttl_t _ttl, + std::shared_ptr<endpoint> _reliable, + std::shared_ptr<endpoint> _unreliable) + : major_(_major), + ttl_(_ttl), + reliable_(_reliable), + unreliable_(_unreliable), + is_acknowledged_(false) { +} + +subscription::~subscription() { +} + +major_version_t subscription::get_major() const { + return major_; +} + +ttl_t subscription::get_ttl() const { + return ttl_; +} + +void subscription::set_ttl(ttl_t _ttl) { + ttl_ = _ttl; +} + +std::shared_ptr<endpoint> subscription::get_endpoint(bool _reliable) const { + return (_reliable ? reliable_ : unreliable_); +} + +void subscription::set_endpoint(std::shared_ptr<endpoint> _endpoint, + bool _reliable) { + if (_reliable) + reliable_ = _endpoint; + else + unreliable_ = _endpoint; +} + +bool subscription::is_acknowleged() const { + return is_acknowledged_; +} + +void subscription::set_acknowledged(bool _is_acknowledged) { + is_acknowledged_ = _is_acknowledged; +} + +} // namespace sd +} // namespace vsomeip diff --git a/implementation/message/include/byteorder.hpp b/implementation/utility/include/byteorder.hpp index ba04b61..ba04b61 100644 --- a/implementation/message/include/byteorder.hpp +++ b/implementation/utility/include/byteorder.hpp diff --git a/implementation/utility/include/utility.hpp b/implementation/utility/include/utility.hpp index 5fe2ed4..e9b4e9d 100644 --- a/implementation/utility/include/utility.hpp +++ b/implementation/utility/include/utility.hpp @@ -33,6 +33,8 @@ public: _type <= message_type_e::REQUEST_NO_RETURN_ACK)); } + static bool is_notification(const byte_t *_data); + static uint32_t get_message_size(std::vector< byte_t > &_data); static bool exists(const std::string &_path); diff --git a/implementation/utility/src/utility.cpp b/implementation/utility/src/utility.cpp index 339503a..e9164c0 100644 --- a/implementation/utility/src/utility.cpp +++ b/implementation/utility/src/utility.cpp @@ -10,38 +10,44 @@ #include <vsomeip/defines.hpp> #include <vsomeip/logger.hpp> +#include "../include/byteorder.hpp" #include "../include/utility.hpp" -#include "../../message/include/byteorder.hpp" namespace vsomeip { -uint32_t utility::get_message_size(std::vector< byte_t > &_data) { - uint32_t its_size(0); - if (VSOMEIP_SOMEIP_HEADER_SIZE <= _data.size()) { - its_size = VSOMEIP_SOMEIP_HEADER_SIZE + - VSOMEIP_BYTES_TO_LONG( - _data[4], _data[5], _data[6], _data[7]); - } - return its_size; +bool utility::is_notification(const byte_t *_data) { + return (0 == _data[VSOMEIP_CLIENT_POS_MIN] + && 0 == _data[VSOMEIP_CLIENT_POS_MAX] + && 0 == _data[VSOMEIP_SESSION_POS_MIN] + && 0 == _data[VSOMEIP_SESSION_POS_MAX]); } -void * utility::load_library(const std::string &_path, const std::string &_symbol) { - void * its_symbol = 0; +uint32_t utility::get_message_size(std::vector<byte_t> &_data) { + uint32_t its_size(0); + if (VSOMEIP_SOMEIP_HEADER_SIZE <= _data.size()) { + its_size = VSOMEIP_SOMEIP_HEADER_SIZE + + VSOMEIP_BYTES_TO_LONG(_data[4], _data[5], _data[6], _data[7]); + } + return its_size; +} - void *handle = dlopen(_path.c_str(), RTLD_LAZY | RTLD_GLOBAL); - if (0 != handle) { - its_symbol = dlsym(handle, _symbol.c_str()); - } else { - VSOMEIP_ERROR << "Loading failed: (" << dlerror() << ")"; - } +void * utility::load_library(const std::string &_path, + const std::string &_symbol) { + void * its_symbol = 0; - return its_symbol; -} + void *handle = dlopen(_path.c_str(), RTLD_LAZY | RTLD_GLOBAL); + if (0 != handle) { + its_symbol = dlsym(handle, _symbol.c_str()); + } else { + VSOMEIP_ERROR << "Loading failed: (" << dlerror() << ")"; + } + return its_symbol; +} bool utility::exists(const std::string &_path) { - struct stat its_stat; - return (stat(_path.c_str(), &its_stat) == 0); + struct stat its_stat; + return (stat(_path.c_str(), &its_stat) == 0); } -} // namespace vsomeip +} // namespace vsomeip diff --git a/interface/vsomeip/configuration.hpp b/interface/vsomeip/configuration.hpp index 999210e..16815ff 100644 --- a/interface/vsomeip/configuration.hpp +++ b/interface/vsomeip/configuration.hpp @@ -7,6 +7,8 @@ #ifndef VSOMEIP_CONFIGURATION_HPP #define VSOMEIP_CONFIGURATION_HPP +#include <map> +#include <memory> #include <set> #include <string> @@ -18,6 +20,8 @@ namespace vsomeip { +class event; + class configuration { public: static configuration * get(const std::string &_path = VSOMEIP_DEFAULT_CONFIGURATION_FILE_PATH); @@ -53,13 +57,20 @@ public: virtual int32_t get_cyclic_offer_delay(const std::string &_name) const = 0; virtual int32_t get_cyclic_request_delay(const std::string &_name) const = 0; - virtual std::string get_address(service_t _service, instance_t _instance) const = 0; + virtual std::string get_unicast(service_t _service, instance_t _instance) const = 0; + virtual std::string get_multicast_address(service_t _service, instance_t _instance) const = 0; + virtual uint16_t get_multicast_port(service_t _service, instance_t _instance) const = 0; + virtual uint16_t get_multicast_group(service_t _service, instance_t _instance) const = 0; virtual uint16_t get_reliable_port(service_t _service, instance_t _instance) const = 0; virtual bool has_enabled_magic_cookies(std::string _address, uint16_t _port) const = 0; virtual uint16_t get_unreliable_port(service_t _service, instance_t _instance) const = 0; virtual std::set< std::pair< service_t, instance_t > > get_remote_services() const = 0; + virtual std::map<service_t, std::map<instance_t, std::map<eventgroup_t, std::set<event_t> > > > get_eventgroups() const = 0; + virtual std::map<service_t, std::map<instance_t, std::set<event_t> > > get_events() const = 0; + virtual void set_event(std::shared_ptr<event> &_event) const = 0; + virtual client_t get_id(const std::string &_name) const = 0; }; diff --git a/interface/vsomeip/defines.hpp b/interface/vsomeip/defines.hpp index a1267a0..3fa199f 100644 --- a/interface/vsomeip/defines.hpp +++ b/interface/vsomeip/defines.hpp @@ -19,7 +19,7 @@ #define VSOMEIP_MAX_TCP_MESSAGE_SIZE 4095 #define VSOMEIP_MAX_UDP_MESSAGE_SIZE 1446 -#define VSOMEIP_PACKET_SIZE 100 +#define VSOMEIP_PACKET_SIZE VSOMEIP_MAX_UDP_MESSAGE_SIZE #define VSOMEIP_SOMEIP_HEADER_SIZE 8 #define VSOMEIP_SOMEIP_MAGIC_COOKIE_SIZE 8 diff --git a/interface/vsomeip/event.hpp b/interface/vsomeip/event.hpp deleted file mode 100644 index cd50064..0000000 --- a/interface/vsomeip/event.hpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright (C) 2014 BMW Group -// Author: Lutz Bichler (lutz.bichler@bmw.de) -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef VSOMEIP_EVENT_HPP -#define VSOMEIP_EVENT_HPP - -#include <chrono> -#include <memory> - -#include <vsomeip/primitive_types.hpp> - -namespace vsomeip { - -class payload; - -class event { -public: - virtual ~event() {}; - - virtual service_t get_service() const = 0; - virtual void set_service(service_t _service) = 0; - - virtual instance_t get_instance() const = 0; - virtual void set_instance(instance_t _instance) = 0; - - virtual event_t get_event() const = 0; - virtual void set_event(event_t _event) = 0; - - virtual std::shared_ptr< payload > get_payload() const = 0; - virtual void set_payload(std::shared_ptr< payload > _payload) = 0; - - virtual void set_update_on_change(bool _is_on) = 0; - virtual void set_update_cycle(std::chrono::milliseconds &_cycle) = 0; -}; - -} // namespace vsomeip - -#endif // VSOMEIP_EVENT_HPP - diff --git a/test/configuration-test.cpp b/test/configuration-test.cpp index 9deed47..ba82ad6 100644 --- a/test/configuration-test.cpp +++ b/test/configuration-test.cpp @@ -134,7 +134,7 @@ int main(int argc, char **argv) { check<uint16_t>(its_reliable, DESIRED_RELIABLE_2277_0022, "RELIABLE_TEST_2277_0022"); check<uint16_t>(its_unreliable, DESIRED_UNRELIABLE_2277_0022, "UNRELIABLE_TEST_2277_0022"); - std::string its_address_s = its_configuration->get_address(0x1234, 0x0022); + std::string its_address_s = its_configuration->get_unicast(0x1234, 0x0022); std::string its_group_name = its_configuration->get_group(0x1234, 0x0022); uint32_t its_min_initial_delay = its_configuration->get_min_initial_delay(its_group_name); uint32_t its_max_initial_delay = its_configuration->get_max_initial_delay(its_group_name); @@ -196,7 +196,7 @@ int main(int argc, char **argv) { check<uint32_t>(its_cyclic_offer_delay, DESIRED_CYCLIC_OFFER_DELAY_2277_0022, "CYCLIC_OFFER_DELAY_TEST_2266_0022"); check<uint32_t>(its_cyclic_request_delay, DESIRED_CYCLIC_REQUEST_DELAY_2277_0022, "CYCLIC_REQUEST_DELAY_TEST_2266_0022"); - its_address_s = its_configuration->get_address(0x4466, 0x0321); + its_address_s = its_configuration->get_unicast(0x4466, 0x0321); check<std::string>(its_address_s, DESIRED_ADDRESS_4466_0321, "ADDRESS_TEST_4466_0321"); // 5. Service discovery |