diff options
-rw-r--r-- | config/vsomeip-local.json | 8 | ||||
-rw-r--r-- | examples/request-sample.cpp | 15 | ||||
-rw-r--r-- | examples/subscribe-sample.cpp | 18 | ||||
-rw-r--r-- | implementation/endpoints/src/local_client_endpoint_impl.cpp | 4 | ||||
-rw-r--r-- | implementation/routing/include/routing_manager.hpp | 12 | ||||
-rw-r--r-- | implementation/routing/include/routing_manager_impl.hpp | 14 | ||||
-rw-r--r-- | implementation/routing/include/routing_manager_proxy.hpp | 13 | ||||
-rw-r--r-- | implementation/routing/include/routing_manager_stub.hpp | 8 | ||||
-rw-r--r-- | implementation/routing/include/routing_manager_stub_host.hpp | 55 | ||||
-rw-r--r-- | implementation/routing/src/routing_manager_impl.cpp | 233 | ||||
-rw-r--r-- | implementation/routing/src/routing_manager_proxy.cpp | 99 | ||||
-rw-r--r-- | implementation/routing/src/routing_manager_stub.cpp | 85 | ||||
-rw-r--r-- | implementation/runtime/src/application_impl.cpp | 2 | ||||
-rw-r--r-- | interface/vsomeip/defines.hpp | 16 |
14 files changed, 372 insertions, 210 deletions
diff --git a/config/vsomeip-local.json b/config/vsomeip-local.json index 92afc5d..f1be1fb 100644 --- a/config/vsomeip-local.json +++ b/config/vsomeip-local.json @@ -1,5 +1,5 @@ { - "unicast" : "192.168.56.104", + "unicast" : "10.0.2.15", "logging" : { "level" : "debug", @@ -12,6 +12,10 @@ { "name" : "service-sample", "id" : "0x1277" + }, + { + "name" : "client-sample", + "id" : "0x1344" } ], "servicegroups" : @@ -59,7 +63,7 @@ "is_field" : "true" } ], - "eventgroups" :ex + "eventgroups" : [ { "eventgroup" : "0x4455", diff --git a/examples/request-sample.cpp b/examples/request-sample.cpp index 95b5e8d..3125291 100644 --- a/examples/request-sample.cpp +++ b/examples/request-sample.cpp @@ -24,7 +24,8 @@ public: be_quiet_(_be_quiet), cycle_(_cycle), sender_(std::bind(&client_sample::run, this)), - running_(true) { + running_(true), + is_available_(false) { } void init() { @@ -83,10 +84,10 @@ public: << (_is_available ? "available." : "NOT available."); if (SAMPLE_SERVICE_ID == _service && SAMPLE_INSTANCE_ID == _instance) { - static bool is_available = false; - if (is_available && !_is_available) is_available = false; - else if (_is_available && !is_available) { - is_available = true; + if (is_available_ && !_is_available) { + is_available_ = false; + } else if (_is_available && !is_available_) { + is_available_ = true; send(); } } @@ -102,7 +103,8 @@ public: << "/" << std::setw(4) << std::setfill('0') << std::hex << _response->get_session() << "]"; - send(); + if (is_available_) + send(); } void send() { @@ -147,6 +149,7 @@ private: std::thread sender_; bool running_; bool blocked_; + bool is_available_; }; diff --git a/examples/subscribe-sample.cpp b/examples/subscribe-sample.cpp index d9797fd..15ebba7 100644 --- a/examples/subscribe-sample.cpp +++ b/examples/subscribe-sample.cpp @@ -29,18 +29,32 @@ public: << (use_tcp_ ? "TCP" : "UDP") << "]"; + app_->register_availability_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, + std::bind(&client_sample::on_availability, + this, + std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + app_->register_message_handler(vsomeip::ANY_SERVICE, SAMPLE_INSTANCE_ID, vsomeip::ANY_METHOD, std::bind(&client_sample::on_message, this, std::placeholders::_1)); - - app_->subscribe(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENTGROUP_ID); } void start() { app_->start(); } + void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, bool _is_available) { + VSOMEIP_INFO << "Service [" + << std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance + << "] is " + << (_is_available ? "available." : "NOT available."); + + if (_is_available && SAMPLE_SERVICE_ID == _service && SAMPLE_INSTANCE_ID == _instance) { + app_->subscribe(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENTGROUP_ID); + } + } + void on_message(std::shared_ptr<vsomeip::message> &_response) { std::stringstream its_message; its_message << "Received a notification for Event [" << std::setw(4) diff --git a/implementation/endpoints/src/local_client_endpoint_impl.cpp b/implementation/endpoints/src/local_client_endpoint_impl.cpp index 747d5ec..9d1fc0e 100644 --- a/implementation/endpoints/src/local_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/local_client_endpoint_impl.cpp @@ -59,9 +59,9 @@ void local_client_endpoint_impl::send_queued(message_buffer_ptr_t _buffer) { #if 0
std::stringstream msg;
msg << "lce<" << this << ">::sq: ";
- for (std::size_t i = 0; i < _data->size(); i++)
+ for (std::size_t i = 0; i < _buffer->size(); i++)
msg << std::setw(2) << std::setfill('0') << std::hex << (int)(*_buffer)[i] << " ";
- msg << std::endl;
+ VSOMEIP_DEBUG << msg.str();
#endif
static byte_t its_start_tag[] = { 0x67, 0x37, 0x6D, 0x07 };
diff --git a/implementation/routing/include/routing_manager.hpp b/implementation/routing/include/routing_manager.hpp index 3549b23..b6dac3e 100644 --- a/implementation/routing/include/routing_manager.hpp +++ b/implementation/routing/include/routing_manager.hpp @@ -25,11 +25,10 @@ class service_info; class routing_manager { public: - virtual ~routing_manager() { - } - ; + virtual ~routing_manager() {}; virtual boost::asio::io_service & get_io() = 0; + virtual client_t get_client() const = 0; virtual void init() = 0; virtual void start() = 0; @@ -79,13 +78,6 @@ public: virtual bool is_available(service_t _service, instance_t _instance) const = 0; - - virtual std::shared_ptr<endpoint> find_local(client_t _client) = 0; - virtual std::shared_ptr<endpoint> find_local(service_t _service, - instance_t _instance) = 0; - virtual std::shared_ptr<endpoint> find_or_create_local( - client_t _client) = 0; - virtual void remove_local(client_t _client) = 0; }; } // namespace vsomeip diff --git a/implementation/routing/include/routing_manager_impl.hpp b/implementation/routing/include/routing_manager_impl.hpp index 4406404..4774367 100644 --- a/implementation/routing/include/routing_manager_impl.hpp +++ b/implementation/routing/include/routing_manager_impl.hpp @@ -18,6 +18,7 @@ #include <vsomeip/primitive_types.hpp> #include "routing_manager.hpp" +#include "routing_manager_stub_host.hpp" #include "../../endpoints/include/endpoint_host.hpp" #include "../../service_discovery/include/service_discovery_host.hpp" @@ -40,8 +41,13 @@ class service_discovery; } // namespace sd -class routing_manager_impl: public routing_manager, +// TODO: encapsulate common parts of classes "routing_manager_impl" +// and "routing_manager_proxy" into a base class. + +class routing_manager_impl: + public routing_manager, public endpoint_host, + public routing_manager_stub_host, public sd::service_discovery_host, public std::enable_shared_from_this<routing_manager_impl> { public: @@ -49,6 +55,7 @@ public: ~routing_manager_impl(); boost::asio::io_service & get_io(); + client_t get_client() const; std::shared_ptr<configuration> get_configuration() const; void init(); @@ -113,6 +120,7 @@ public: void on_connect(std::shared_ptr<endpoint> _endpoint); void on_disconnect(std::shared_ptr<endpoint> _endpoint); void on_message(const byte_t *_data, length_t _length, endpoint *_receiver); + void on_message(service_t _service, instance_t _instance, const byte_t *_data, length_t _size); // interface "service_discovery_host" typedef std::map<std::string, std::shared_ptr<servicegroup> > servicegroups_t; @@ -144,6 +152,10 @@ public: private: bool deliver_message(const byte_t *_data, length_t _length, instance_t _instance); + bool send_local(std::shared_ptr<endpoint> &_target, client_t _client, + const byte_t *_data, uint32_t _size, + instance_t _instance, + bool _flush, bool _reliable) const; client_t find_local_client(service_t _service, instance_t _instance); std::set<client_t> find_local_clients(service_t _service, diff --git a/implementation/routing/include/routing_manager_proxy.hpp b/implementation/routing/include/routing_manager_proxy.hpp index 00c5bc1..c0d15c2 100644 --- a/implementation/routing/include/routing_manager_proxy.hpp +++ b/implementation/routing/include/routing_manager_proxy.hpp @@ -18,8 +18,12 @@ namespace vsomeip { class configuration; +class event; class routing_manager_host; +// TODO: encapsulate common parts of classes "routing_manager_impl" +// and "routing_manager_proxy" into a base class. + class routing_manager_proxy: public routing_manager, public endpoint_host, public std::enable_shared_from_this<routing_manager_proxy> { @@ -28,6 +32,7 @@ public: virtual ~routing_manager_proxy(); boost::asio::io_service & get_io(); + client_t get_client() const; void init(); void start(); @@ -77,6 +82,7 @@ public: void on_connect(std::shared_ptr<endpoint> _endpoint); void on_disconnect(std::shared_ptr<endpoint> _endpoint); void on_message(const byte_t *_data, length_t _length, endpoint *_receiver); + void on_message(service_t _service, instance_t _instance, const byte_t *_data, length_t _size); void on_routing_info(const byte_t *_data, uint32_t _size); @@ -93,8 +99,8 @@ private: void deregister_application(); std::shared_ptr<endpoint> create_local(client_t _client); - - bool is_request(byte_t _message_type) const; + std::shared_ptr<event> find_event(service_t _service, instance_t _instance, + event_t _event) const; void send_pong() const; @@ -112,6 +118,9 @@ private: std::map<client_t, std::shared_ptr<endpoint> > local_endpoints_; std::map<service_t, std::map<instance_t, client_t> > local_services_; + std::map<service_t, + std::map<instance_t, std::map<event_t, std::shared_ptr<event> > > > events_; + std::mutex send_mutex_; std::mutex serialize_mutex_; std::mutex deserialize_mutex_; diff --git a/implementation/routing/include/routing_manager_stub.hpp b/implementation/routing/include/routing_manager_stub.hpp index bf51251..c06891e 100644 --- a/implementation/routing/include/routing_manager_stub.hpp +++ b/implementation/routing/include/routing_manager_stub.hpp @@ -19,18 +19,20 @@ namespace vsomeip { +class routing_manager_stub_host; + class routing_manager_stub: public endpoint_host, public std::enable_shared_from_this< routing_manager_stub > { public: - routing_manager_stub(routing_manager *_its_routing); + routing_manager_stub(routing_manager_stub_host *_host); ~routing_manager_stub(); void init(); void start(); void stop(); - routing_manager * get_manager(); + //routing_manager * get_manager(); void on_connect(std::shared_ptr< endpoint > _endpoint); void on_disconnect(std::shared_ptr< endpoint > _endpoint); @@ -58,7 +60,7 @@ private: boost::asio::io_service &io_; boost::asio::system_timer watchdog_timer_; - routing_manager *routing_; + routing_manager_stub_host *host_; std::shared_ptr< endpoint > endpoint_; std::map< client_t, std::pair< uint8_t, diff --git a/implementation/routing/include/routing_manager_stub_host.hpp b/implementation/routing/include/routing_manager_stub_host.hpp new file mode 100644 index 0000000..bf113ba --- /dev/null +++ b/implementation/routing/include/routing_manager_stub_host.hpp @@ -0,0 +1,55 @@ +// 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_ROUTING_MANAGER_STUB_HOST +#define VSOMEIP_ROUTING_MANAGER_STUB_HOST + +#include <boost/asio/io_service.hpp> + +namespace vsomeip { + +class routing_manager_stub_host { +public: + virtual ~routing_manager_stub_host() {}; + + virtual void offer_service(client_t _client, service_t _service, + instance_t _instance, major_version_t _major, + minor_version_t _minor, ttl_t _ttl) = 0; + + virtual void stop_offer_service(client_t _client, service_t _service, + instance_t _instance) = 0; + + virtual void request_service(client_t _client, service_t _service, + instance_t _instance, major_version_t _major, + minor_version_t _minor, ttl_t _ttl) = 0; + + virtual void release_service(client_t _client, service_t _service, + instance_t _instance) = 0; + + virtual void subscribe(client_t _client, service_t _service, + instance_t _instance, eventgroup_t _eventgroup, + major_version_t _major, ttl_t _ttl) = 0; + + virtual void unsubscribe(client_t _client, service_t _service, + instance_t _instance, eventgroup_t _eventgroup) = 0; + + virtual void on_message(service_t _service, instance_t _instance, + const byte_t *_data, length_t _size) = 0; + + virtual std::shared_ptr<endpoint> find_local(client_t _client) = 0; + virtual std::shared_ptr<endpoint> find_local(service_t _service, + instance_t _instance) = 0; + virtual std::shared_ptr<endpoint> find_or_create_local( + client_t _client) = 0; + virtual void remove_local(client_t _client) = 0; + + virtual boost::asio::io_service & get_io() = 0; + virtual client_t get_client() const = 0; +}; + +} // namespace vsomeip + +#endif // VSOMEIP_ROUTING_MANAGER_STUB_HOST diff --git a/implementation/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp index 634a447..36ad00a 100644 --- a/implementation/routing/src/routing_manager_impl.cpp +++ b/implementation/routing/src/routing_manager_impl.cpp @@ -53,6 +53,10 @@ boost::asio::io_service & routing_manager_impl::get_io() { return (io_); } +client_t routing_manager_impl::get_client() const { + return host_->get_client(); +} + 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) @@ -122,11 +126,16 @@ void routing_manager_impl::offer_service(client_t _client, service_t _service, (void) create_service(_service, _instance, _major, _minor, _ttl); } + stub_->on_offer_service(_client, _service, _instance); host_->on_availability(_service, _instance, true); } -void routing_manager_impl::stop_offer_service(client_t its_client, +void routing_manager_impl::stop_offer_service(client_t _client, service_t _service, instance_t _instance) { + + host_->on_availability(_service, _instance, false); + stub_->on_stop_offer_service(_client, _service, _instance); + if (discovery_) { auto found_service = services_.find(_service); if (found_service != services_.end()) { @@ -256,27 +265,7 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, } 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); + is_sent = send_local(its_target, _client, _data, _size, _instance, _flush, _reliable); } else { // Check whether hosting application should get the message // If not, check routes to external @@ -305,13 +294,15 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, _data[VSOMEIP_METHOD_POS_MAX]); std::shared_ptr<event> its_event = find_event(its_service, _instance, its_method); if (its_event) { + std::vector< byte_t > its_data(); + for (auto its_group : its_event->get_eventgroups()) { // local auto its_local_clients = find_local_clients(its_service, _instance, its_group); for (auto its_local_client : its_local_clients) { std::shared_ptr<endpoint> its_local_target = find_local(its_local_client); if (its_target) { - its_local_target->send(_data, _size); + send_local(its_local_target, _client, _data, _size, _instance, _flush, _reliable); } } @@ -341,6 +332,34 @@ bool routing_manager_impl::send(client_t _client, const byte_t *_data, return (is_sent); } +bool routing_manager_impl::send_local( + std::shared_ptr<endpoint> &_target, client_t _client, + const byte_t *_data, uint32_t _size, + instance_t _instance, + bool _flush, bool _reliable) const { + 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)); + + return _target->send(&its_command[0], its_command.size(),_flush); +} + bool routing_manager_impl::get(client_t _client, session_t _session, service_t _service, instance_t _instance, event_t _event, bool _reliable) { bool is_sent(false); @@ -362,7 +381,7 @@ bool routing_manager_impl::get(client_t _client, session_t _session, if (serializer_->serialize(its_request.get())) { is_sent = its_target->send(serializer_->get_data(), serializer_->get_size()); } else { - VSOMEIP_ERROR << "routing_manager_impl: serialization error."; + VSOMEIP_ERROR << "routing_manager_impl::get: serialization error."; } serializer_->reset(); } @@ -397,6 +416,8 @@ bool routing_manager_impl::set(client_t _client, session_t _session, std::unique_lock<std::mutex> its_lock(serialize_mutex_); if (serializer_->serialize(its_request.get())) { is_set = its_target->send(serializer_->get_data(), serializer_->get_size()); + } else { + VSOMEIP_ERROR << "routing_manager_impl::set: serialization error."; } serializer_->reset(); } @@ -433,7 +454,7 @@ bool routing_manager_impl::send_to( void routing_manager_impl::on_message(const byte_t *_data, length_t _size, endpoint *_receiver) { -#if 0 +#if 1 std::stringstream msg; msg << "rmi::on_message: "; for (uint32_t i = 0; i < _size; ++i) @@ -442,9 +463,6 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, #endif service_t its_service; instance_t its_instance; - method_t its_method; - client_t its_client; - session_t its_session; if (_size >= VSOMEIP_SOMEIP_HEADER_SIZE) { its_service = VSOMEIP_BYTES_TO_WORD(_data[VSOMEIP_SERVICE_POS_MIN], @@ -454,104 +472,89 @@ void routing_manager_impl::on_message(const byte_t *_data, length_t _size, discovery_->on_message(_data, _size); } else { its_instance = find_instance(its_service, _receiver); - if (its_instance != ANY_INSTANCE) { - if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) { - its_method = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_METHOD_POS_MIN], - _data[VSOMEIP_METHOD_POS_MAX]); - if (utility::is_event(its_method)) { - std::shared_ptr<event> its_event = find_event( - its_service, its_instance, its_method); - if (its_event) { - if (its_event->is_field()) { - uint32_t its_length = utility::get_payload_size(_data, _size); - if (its_length > 0) { // set - std::shared_ptr<payload> its_payload = - runtime::get()->create_payload( - &_data[VSOMEIP_PAYLOAD_POS], - its_length); - its_event->set_payload(its_payload); - } + on_message(its_service, its_instance, _data, _size); + } + } +} - if (!utility::is_request_no_return( - _data[VSOMEIP_RETURN_CODE_POS])) { - std::shared_ptr<message> its_response = - runtime::get()->create_message(); - its_client = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_CLIENT_POS_MIN], - _data[VSOMEIP_CLIENT_POS_MAX]); - its_session = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SESSION_POS_MIN], - _data[VSOMEIP_SESSION_POS_MAX]); - - its_response->set_service(its_service); - its_response->set_method(its_method); - its_response->set_client(its_client); - its_response->set_session(its_session); - its_response->set_message_type( - message_type_e::RESPONSE); - its_response->set_payload(its_event->get_payload()); - - std::unique_lock<std::mutex> its_lock(serialize_mutex_); - if (serializer_->serialize(its_response.get())) { - _receiver->send(serializer_->get_data(), serializer_->get_size(), true); - } else { - VSOMEIP_ERROR << "routing_manager_impl::on_message: serialization error."; - } - serializer_->reset(); - } - } else { - std::shared_ptr<message> its_response = - runtime::get()->create_message(); - its_client = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_CLIENT_POS_MIN], - _data[VSOMEIP_CLIENT_POS_MAX]); - its_session = VSOMEIP_BYTES_TO_WORD( - _data[VSOMEIP_SESSION_POS_MIN], - _data[VSOMEIP_SESSION_POS_MAX]); - - its_response->set_service(its_service); - its_response->set_method(its_method); - its_response->set_client(its_client); - its_response->set_session(its_session); - its_response->set_message_type(message_type_e::ERROR); - - std::unique_lock<std::mutex> its_lock(serialize_mutex_); - if (serializer_->serialize(its_response.get())) { - _receiver->send(serializer_->get_data(), serializer_->get_size(), true); - } else { - VSOMEIP_ERROR << "routing_manager_impl::on_message: serialization error."; - } - serializer_->reset(); - } - } else { - its_client = VSOMEIP_ROUTING_CLIENT; - } - } else { - its_client = find_local_client(its_service, - its_instance); +void routing_manager_impl::on_message(service_t _service, instance_t _instance, const byte_t *_data, length_t _size) { + method_t its_method; + client_t its_client; + session_t its_session; + + if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) { + if (utility::is_event(_data[VSOMEIP_METHOD_POS_MIN])) { + its_method = VSOMEIP_BYTES_TO_WORD( + _data[VSOMEIP_METHOD_POS_MIN], + _data[VSOMEIP_METHOD_POS_MAX]); + std::shared_ptr<event> its_event + = find_event(_service, _instance, its_method); + if (its_event) { + if (its_event->is_field()) { + uint32_t its_length = utility::get_payload_size(_data, _size); + if (its_length > 0) { // set + std::shared_ptr<payload> its_payload = + runtime::get()->create_payload( + &_data[VSOMEIP_PAYLOAD_POS], + its_length); + its_event->set_payload(its_payload); } - } else { + } + + if (!utility::is_request_no_return( + _data[VSOMEIP_RETURN_CODE_POS])) { + std::shared_ptr<message> its_response = + runtime::get()->create_message(); its_client = VSOMEIP_BYTES_TO_WORD( _data[VSOMEIP_CLIENT_POS_MIN], _data[VSOMEIP_CLIENT_POS_MAX]); - } + its_session = VSOMEIP_BYTES_TO_WORD( + _data[VSOMEIP_SESSION_POS_MIN], + _data[VSOMEIP_SESSION_POS_MAX]); + + its_response->set_service(_service); + its_response->set_method(its_method); + its_response->set_client(its_client); + its_response->set_session(its_session); + + if (its_event->is_field()) { + its_response->set_message_type( + message_type_e::RESPONSE); + its_response->set_payload(its_event->get_payload()); + } else { + its_response->set_message_type(message_type_e::ERROR); + } - if (its_client == host_->get_client() - || utility::is_notification(_data)) { - 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<< "Cannot determine target application!"; + std::unique_lock<std::mutex> its_lock(serialize_mutex_); + if (serializer_->serialize(its_response.get())) { + send(its_client, + serializer_->get_data(), serializer_->get_size(), + _instance, + true, its_event->is_reliable()); + } else { + VSOMEIP_ERROR << "routing_manager_impl::on_message: serialization error."; + } + serializer_->reset(); } } else { - VSOMEIP_ERROR - << "Cannot determine service instance for [" << its_service << "]"; + its_client = VSOMEIP_ROUTING_CLIENT; } + } else { + its_client = find_local_client(_service, _instance); } } else { - //send_error(); // TODO: send error "malformed message" + its_client = VSOMEIP_BYTES_TO_WORD( + _data[VSOMEIP_CLIENT_POS_MIN], + _data[VSOMEIP_CLIENT_POS_MAX]); + } + + if (its_client == host_->get_client() + || utility::is_notification(_data)) { + deliver_message(_data, _size, _instance); + } else if (its_client != VSOMEIP_ROUTING_CLIENT) { + send(its_client, _data, _size, _instance, true, false); + } else { + VSOMEIP_ERROR<< "Cannot determine target application!"; } } diff --git a/implementation/routing/src/routing_manager_proxy.cpp b/implementation/routing/src/routing_manager_proxy.cpp index eab0e87..a4ed3d2 100644 --- a/implementation/routing/src/routing_manager_proxy.cpp +++ b/implementation/routing/src/routing_manager_proxy.cpp @@ -10,6 +10,7 @@ #include <vsomeip/configuration.hpp> #include <vsomeip/constants.hpp> #include <vsomeip/logger.hpp> +#include <vsomeip/runtime.hpp> #include "../include/event.hpp" #include "../include/routing_manager_host.hpp" @@ -38,6 +39,10 @@ boost::asio::io_service & routing_manager_proxy::get_io() { return (io_); } +client_t routing_manager_proxy::get_client() const { + return client_; +} + void routing_manager_proxy::init() { uint32_t its_max_message_size = VSOMEIP_MAX_LOCAL_MESSAGE_SIZE; if (VSOMEIP_MAX_TCP_MESSAGE_SIZE > its_max_message_size) @@ -68,12 +73,14 @@ void routing_manager_proxy::start() { if (receiver_) receiver_->start(); - // Tell the stub where to find us register_application(); + + host_->on_event(event_type_e::REGISTERED); } void routing_manager_proxy::stop() { - // Tell the stub we are no longer active + host_->on_event(event_type_e::DEREGISTERED); + deregister_application(); if (receiver_) @@ -210,9 +217,8 @@ bool routing_manager_proxy::send(client_t _client, const byte_t *_data, bool _reliable) { bool is_sent(false); std::shared_ptr<endpoint> its_target; - if (_size > VSOMEIP_MESSAGE_TYPE_POS) { - if (is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) { + if (utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS])) { service_t its_service = VSOMEIP_BYTES_TO_WORD( _data[VSOMEIP_SERVICE_POS_MIN], _data[VSOMEIP_SERVICE_POS_MAX]); @@ -247,10 +253,11 @@ bool routing_manager_proxy::send(client_t _client, const byte_t *_data, + sizeof(bool)] = _reliable; #if 0 - std::cout << "rmp:send: "; + std::stringstream msg; + msg << "rmp:send: "; for (int i = 0; i < its_command.size(); i++) - std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)its_command[i] << " "; - std::cout << std::endl; + msg << std::hex << std::setw(2) << std::setfill('0') << (int)its_command[i] << " "; + VSOMEIP_DEBUG << msg.str(); #endif is_sent = its_target->send(&its_command[0], its_command.size()); @@ -271,16 +278,48 @@ bool routing_manager_proxy::send_to( } bool routing_manager_proxy::get(client_t _client, session_t _session, - service_t _service, instance_t _instance, event_t _event, - bool _reliable) { - bool is_gotten(false); - return (is_gotten); + service_t _service, instance_t _instance, event_t _event, bool _reliable) { + bool is_sent(false); + std::shared_ptr<event> its_event = find_event(_service, _instance, _event); + if (its_event) { // local + // TODO: bring back the result to the application + } else { // remote + std::shared_ptr<message> its_request = runtime::get()->create_request(); + if (its_request) { + its_request->set_service(_service); + its_request->set_instance(_instance); + its_request->set_method(_event); + its_request->set_client(_client); + its_request->set_session(_session); + + is_sent = send(_client, its_request, true, _reliable); + } + } + return (is_sent); } bool routing_manager_proxy::set(client_t _client, session_t _session, - service_t _service, instance_t _instance, event_t _event, - const std::shared_ptr<payload> &_value, bool _reliable) { + service_t _service, instance_t _instance, event_t _event, + const std::shared_ptr<payload> &_payload, bool _reliable) { bool is_set(false); + std::shared_ptr<event> its_event = find_event(_service, _instance, _event); + if (its_event) { + its_event->set_payload(_payload); + // TODO: somehow bring back the result to the application as set according to SOME/IP is set+get + is_set = true; + } else { + std::shared_ptr<message> its_request = runtime::get()->create_request(); + if (its_request) { + its_request->set_service(_service); + its_request->set_instance(_instance); + its_request->set_method(_event); + its_request->set_client(_client); + its_request->set_session(_session); + its_request->set_payload(_payload); + + is_set = send(_client, its_request, true, _reliable); + } + } return (is_set); } @@ -293,10 +332,11 @@ void routing_manager_proxy::on_disconnect(std::shared_ptr<endpoint> _endpoint) { void routing_manager_proxy::on_message(const byte_t *_data, length_t _size, endpoint *_receiver) { #if 0 - std::cout << "rmp::on_message: "; + std::stringstream msg; + msg << "rmp::on_message: "; for (int i = 0; i < _size; ++i) - std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; - std::cout << std::endl; + msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; + VSOMEIP_DEBUG << msg.str(); #endif byte_t its_command; client_t its_client; @@ -343,6 +383,10 @@ void routing_manager_proxy::on_message(const byte_t *_data, length_t _size, } } +void routing_manager_proxy::on_message(service_t _service, instance_t _instance, const byte_t *_data, length_t _size) { + // TODO: Remove dummy implementation after creating an interface between stub and implementation. +} + void routing_manager_proxy::on_routing_info(const byte_t *_data, uint32_t _size) { #if 0 @@ -492,8 +536,8 @@ std::shared_ptr<endpoint> routing_manager_proxy::create_local( std::stringstream its_path; its_path << base_path << std::hex << _client; - VSOMEIP_DEBUG<< "Connecting to [" << std::hex << _client - << "] at " << its_path.str(); + VSOMEIP_DEBUG<< "Connecting to [" + << std::hex << _client << "] at " << its_path.str(); std::shared_ptr<endpoint> its_endpoint = std::make_shared< local_client_endpoint_impl>(shared_from_this(), @@ -534,11 +578,20 @@ std::shared_ptr<endpoint> routing_manager_proxy::find_local(service_t _service, return (find_local(its_client)); } -bool routing_manager_proxy::is_request(byte_t _message_type) const { - message_type_e its_type = static_cast<message_type_e>(_message_type); - return (its_type < message_type_e::NOTIFICATION - || its_type == message_type_e::REQUEST_ACK - || its_type == message_type_e::REQUEST_NO_RETURN_ACK); +std::shared_ptr<event> routing_manager_proxy::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); } void routing_manager_proxy::send_pong() const { diff --git a/implementation/routing/src/routing_manager_stub.cpp b/implementation/routing/src/routing_manager_stub.cpp index 9360606..b62c8bc 100644 --- a/implementation/routing/src/routing_manager_stub.cpp +++ b/implementation/routing/src/routing_manager_stub.cpp @@ -15,16 +15,16 @@ #include <vsomeip/primitive_types.hpp> #include <vsomeip/runtime.hpp> -#include "../include/routing_manager.hpp" #include "../include/routing_manager_stub.hpp" +#include "../include/routing_manager_stub_host.hpp" #include "../../configuration/include/internal.hpp" #include "../../endpoints/include/local_server_endpoint_impl.hpp" +#include "../../utility/include/byteorder.hpp" namespace vsomeip { -routing_manager_stub::routing_manager_stub(routing_manager *_routing) : - routing_(_routing), io_(_routing->get_io()), watchdog_timer_( - _routing->get_io()) { +routing_manager_stub::routing_manager_stub(routing_manager_stub_host *_host) : + host_(_host), io_(_host->get_io()), watchdog_timer_(_host->get_io()) { } routing_manager_stub::~routing_manager_stub() { @@ -58,10 +58,6 @@ void routing_manager_stub::stop() { ::unlink(its_endpoint_path.str().c_str()); } -routing_manager * routing_manager_stub::get_manager() { - return routing_; -} - void routing_manager_stub::on_connect(std::shared_ptr<endpoint> _endpoint) { } @@ -73,10 +69,11 @@ void routing_manager_stub::on_disconnect(std::shared_ptr<endpoint> _endpoint) { void routing_manager_stub::on_message(const byte_t *_data, length_t _size, endpoint *_receiver) { #if 0 - std::cout << "rms::on_message: "; + std::stringstream msg; + msg << "rms::on_message: "; for (int i = 0; i < _size; ++i) - std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; - std::cout << std::endl; + msg << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; + VSOMEIP_DEBUG << msg.str(); #endif if (VSOMEIP_COMMAND_SIZE_POS_MAX < _size) { @@ -100,14 +97,14 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, its_command = _data[VSOMEIP_COMMAND_TYPE_POS]; std::memcpy(&its_client, &_data[VSOMEIP_COMMAND_CLIENT_POS], sizeof(its_client)); - // TODO: read session + std::memcpy(&its_size, &_data[VSOMEIP_COMMAND_SIZE_POS_MIN], sizeof(its_size)); if (its_size <= _size - VSOMEIP_COMMAND_HEADER_SIZE) { switch (its_command) { case VSOMEIP_REGISTER_APPLICATION: - (void) routing_->find_or_create_local(its_client); + (void)host_->find_or_create_local(its_client); routing_info_[its_client].first = 0; broadcast_routing_info(); VSOMEIP_DEBUG << "Application/Client " << its_client @@ -136,7 +133,7 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, sizeof(its_minor)); std::memcpy(&its_ttl, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 9], sizeof(its_ttl)); - routing_->offer_service(its_client, its_service, its_instance, + host_->offer_service(its_client, its_service, its_instance, its_major, its_minor, its_ttl); on_offer_service(its_client, its_service, its_instance); break; @@ -147,37 +144,47 @@ void routing_manager_stub::on_message(const byte_t *_data, length_t _size, std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], sizeof(its_instance)); - routing_->stop_offer_service(its_client, its_service, + host_->stop_offer_service(its_client, its_service, its_instance); on_stop_offer_service(its_client, its_service, its_instance); break; case VSOMEIP_SUBSCRIBE: - routing_->subscribe(its_client, its_service, + std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], + sizeof(its_service)); + std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], + sizeof(its_instance)); + std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], + sizeof(its_eventgroup)); + std::memcpy(&its_major, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 6], + sizeof(its_major)); + std::memcpy(&its_ttl, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 7], + sizeof(its_ttl)); + + host_->subscribe(its_client, its_service, its_instance, its_eventgroup, its_major, its_ttl); break; case VSOMEIP_UNSUBSCRIBE: - routing_->unsubscribe(its_client, its_service, + std::memcpy(&its_service, &_data[VSOMEIP_COMMAND_PAYLOAD_POS], + sizeof(its_service)); + std::memcpy(&its_instance, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 2], + sizeof(its_instance)); + std::memcpy(&its_eventgroup, &_data[VSOMEIP_COMMAND_PAYLOAD_POS + 4], + sizeof(its_eventgroup)); + host_->unsubscribe(its_client, its_service, its_instance, its_eventgroup); break; case VSOMEIP_SEND: its_data = &_data[VSOMEIP_COMMAND_PAYLOAD_POS]; - std::memcpy(&its_instance, &_data[_size - 4], - sizeof(its_instance)); + its_service = VSOMEIP_BYTES_TO_WORD( + its_data[VSOMEIP_SERVICE_POS_MIN], + its_data[VSOMEIP_SERVICE_POS_MAX]); its_flush = static_cast<bool>(_data[_size - 2]); its_reliable = static_cast<bool>(_data[_size - 1]); - routing_->send(its_client, its_data, its_size, its_instance, - its_flush, its_reliable); - break; - - case VSOMEIP_SET: - its_data = &_data[VSOMEIP_COMMAND_PAYLOAD_POS]; - its_payload = runtime::get()->create_payload(its_data, its_size); - its_reliable = static_cast<bool>(_data[_size - 1]); - routing_->set(its_client, its_session, its_service, its_instance, its_event, - its_payload, its_reliable); + std::memcpy(&its_instance, &_data[_size - 4], sizeof(its_instance)); + host_->on_message(its_service, its_instance, its_data, its_size); break; } } @@ -193,13 +200,13 @@ void routing_manager_stub::on_deregister_application(client_t _client) { if (its_info != routing_info_.end()) { for (auto &its_service : its_info->second.second) { for (auto &its_instance : its_service.second) { - routing_->stop_offer_service(_client, its_service.first, + host_->stop_offer_service(_client, its_service.first, its_instance); } } } - routing_->remove_local(_client); + host_->remove_local(_client); routing_info_.erase(_client); broadcast_routing_info(); } @@ -226,7 +233,7 @@ void routing_manager_stub::on_stop_offer_service(client_t _client, } void routing_manager_stub::send_routing_info(client_t _client) { - std::shared_ptr<endpoint> its_endpoint = routing_->find_local(_client); + std::shared_ptr<endpoint> its_endpoint = host_->find_local(_client); if (its_endpoint) { uint32_t its_capacity = 4096; // TODO: dynamic resizing std::vector<byte_t> its_command(its_capacity); @@ -234,13 +241,19 @@ void routing_manager_stub::send_routing_info(client_t _client) { std::memset(&its_command[VSOMEIP_COMMAND_CLIENT_POS], 0, sizeof(client_t)); uint32_t its_size = VSOMEIP_COMMAND_PAYLOAD_POS; + for (auto &info : routing_info_) { uint32_t its_size_pos = its_size; uint32_t its_entry_size = its_size; its_size += sizeof(uint32_t); // placeholder - std::memcpy(&its_command[its_size], &info.first, sizeof(client_t)); + if (info.first != host_->get_client()) { + std::memcpy(&its_command[its_size], &info.first, sizeof(client_t)); + } else { + std::memset(&its_command[its_size], 0x0, sizeof(client_t)); + } + its_size += sizeof(client_t); for (auto &service : info.second.second) { @@ -290,8 +303,8 @@ void routing_manager_stub::broadcast_routing_info() { void routing_manager_stub::broadcast(std::vector<byte_t> &_command) const { for (auto a : routing_info_) { if (a.first > 0) { - std::shared_ptr<endpoint> its_endpoint = routing_->find_local( - a.first); + std::shared_ptr<endpoint> its_endpoint + = host_->find_local(a.first); if (its_endpoint) { its_endpoint->send(&_command[0], _command.size(), true); } @@ -346,7 +359,7 @@ void routing_manager_stub::check_watchdog() { std::list< client_t > lost; for (auto i : routing_info_) { - if (i.first > 0) { + if (i.first > 0 && i.first != host_->get_client()) { if (i.second.first > VSOMEIP_DEFAULT_MAX_MISSING_PONGS) { // TODO: use config variable VSOMEIP_WARNING << "Lost contact to application " << std::hex << (int)i.first; lost.push_back(i.first); diff --git a/implementation/runtime/src/application_impl.cpp b/implementation/runtime/src/application_impl.cpp index 44dbc2f..b6a9997 100644 --- a/implementation/runtime/src/application_impl.cpp +++ b/implementation/runtime/src/application_impl.cpp @@ -31,7 +31,7 @@ bool application_impl::init() { // Application name if (name_ == "") { - const char *its_name = getenv(VSOMEIP_APPLICATION_NAME); + const char *its_name = getenv(VSOMEIP_ENV_APPLICATION_NAME); if (nullptr != its_name) { name_ = its_name; } else { diff --git a/interface/vsomeip/defines.hpp b/interface/vsomeip/defines.hpp index e72083f..9f72807 100644 --- a/interface/vsomeip/defines.hpp +++ b/interface/vsomeip/defines.hpp @@ -7,11 +7,11 @@ #ifndef VSOMEIP_DEFINES_HPP #define VSOMEIP_DEFINES_HPP -#define VSOMEIP_APPLICATION_NAME "VSOMEIP_APPLICATION_NAME" - -#define VSOMEIP_DEFAULT_CONFIGURATION_FILE_PATH "/etc/vsomeip.xml" +#define VSOMEIP_ENV_APPLICATION_NAME "VSOMEIP_APPLICATION_NAME" #define VSOMEIP_ENV_CONFIGURATION_FILE_PATH "VSOMEIP_CONFIGURATION_FILE" -#define VSOMEIP_LOCAL_CONFIGURATION_FILE_PATH "./vsomeip.xml" + +#define VSOMEIP_DEFAULT_CONFIGURATION_FILE_PATH "/etc/vsomeip.json" +#define VSOMEIP_LOCAL_CONFIGURATION_FILE_PATH "./vsomeip.json" #define VSOMEIP_PROTOCOL_VERSION 0x1 @@ -28,16 +28,18 @@ #define VSOMEIP_SERVICE_POS_MAX 1 #define VSOMEIP_METHOD_POS_MIN 2 #define VSOMEIP_METHOD_POS_MAX 3 +#define VSOMEIP_EVENT_POS_MIN 2 +#define VSOMEIP_EVENT_POS_MAX 3 #define VSOMEIP_LENGTH_POS_MIN 4 #define VSOMEIP_LENGTH_POS_MAX 7 #define VSOMEIP_CLIENT_POS_MIN 8 #define VSOMEIP_CLIENT_POS_MAX 9 #define VSOMEIP_SESSION_POS_MIN 10 #define VSOMEIP_SESSION_POS_MAX 11 -#define VSOMEIP_PROTOCOL_VERSION_POS 12 -#define VSOMEIP_INTERFACE_VERSION_POS 13 +#define VSOMEIP_PROTOCOL_VERSION_POS 12 +#define VSOMEIP_INTERFACE_VERSION_POS 13 #define VSOMEIP_MESSAGE_TYPE_POS 14 #define VSOMEIP_RETURN_CODE_POS 15 -#define VSOMEIP_PAYLOAD_POS 16 +#define VSOMEIP_PAYLOAD_POS 16 #endif // VSOMEIP_DEFINES_HPP |