diff options
author | Lutz Bichler <Lutz.Bichler@bmw.de> | 2014-07-08 17:47:31 +0200 |
---|---|---|
committer | Lutz Bichler <Lutz.Bichler@bmw.de> | 2014-07-08 17:47:31 +0200 |
commit | 374a6ebbac57c371f55628cafe862b9c38be56f1 (patch) | |
tree | 1a0ddd085fb049b9d7341d67f9be2d75cf20a756 /implementation | |
parent | 18044e7847f3f9f1c56ac118ccbfb06eb68a2e45 (diff) | |
download | vSomeIP-374a6ebbac57c371f55628cafe862b9c38be56f1.tar.gz |
Implemented endpoint options.
Diffstat (limited to 'implementation')
33 files changed, 463 insertions, 42 deletions
diff --git a/implementation/endpoints/include/endpoint.hpp b/implementation/endpoints/include/endpoint.hpp index 640536e..1b4ad12 100644 --- a/implementation/endpoints/include/endpoint.hpp +++ b/implementation/endpoints/include/endpoint.hpp @@ -11,8 +11,6 @@ namespace vsomeip {
-class message_base;
-
class endpoint
{
public:
@@ -32,6 +30,11 @@ public: virtual void enable_magic_cookies() = 0;
virtual void disable_magic_cookies() = 0;
+
+ virtual bool is_v4() const = 0;
+ virtual bool get_address(std::vector< byte_t > &_address) const = 0;
+ virtual unsigned short get_port() const = 0;
+ virtual bool is_udp() const = 0;
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/endpoint_impl.hpp b/implementation/endpoints/include/endpoint_impl.hpp index bacb440..b062a56 100644 --- a/implementation/endpoints/include/endpoint_impl.hpp +++ b/implementation/endpoints/include/endpoint_impl.hpp @@ -33,8 +33,14 @@ public: void open_filter(service_t _service);
void close_filter(service_t _service);
+ // Dummy implementations as we only need these for server endpoints
+ // TODO: redesign to avoid dummy implementations
+ bool is_v4() const;
+ bool get_address(std::vector< byte_t > &_address) const;
+ unsigned short get_port() const;
+ bool is_udp() const;
+
public: // required
- virtual bool is_client() const = 0;
virtual const uint8_t * get_buffer() const = 0;
virtual void receive() = 0;
diff --git a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp index fccdd78..a2cd635 100644 --- a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp @@ -42,6 +42,11 @@ public: void join(const std::string &);
void leave(const std::string &);
+ bool is_v4() const;
+ bool get_address(std::vector< byte_t > &_address) const;
+ unsigned short get_port() const;
+ bool is_udp() const;
+
private:
class connection
: public boost::enable_shared_from_this< connection > {
diff --git a/implementation/endpoints/include/udp_server_endpoint_impl.hpp b/implementation/endpoints/include/udp_server_endpoint_impl.hpp index fbf4fd1..b0e8fb9 100644 --- a/implementation/endpoints/include/udp_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/udp_server_endpoint_impl.hpp @@ -45,6 +45,11 @@ public: void join(const std::string &_multicast_address);
void leave(const std::string &_multicast_address);
+ bool is_v4() const;
+ bool get_address(std::vector< byte_t > &_address) const;
+ unsigned short get_port() const;
+ bool is_udp() const;
+
public:
void receive_cbk(boost::system::error_code const &_error, std::size_t _size);
diff --git a/implementation/endpoints/src/endpoint_impl.cpp b/implementation/endpoints/src/endpoint_impl.cpp index fe73013..5eb91c7 100644 --- a/implementation/endpoints/src/endpoint_impl.cpp +++ b/implementation/endpoints/src/endpoint_impl.cpp @@ -121,6 +121,26 @@ bool endpoint_impl< MaxBufferSize >::resync_on_magic_cookie() { }
*/
+template < int MaxBufferSize >
+bool endpoint_impl< MaxBufferSize >::is_v4() const {
+ return false;
+}
+
+template < int MaxBufferSize >
+bool endpoint_impl< MaxBufferSize >::get_address(std::vector< byte_t > &_address) const {
+ return false;
+}
+
+template < int MaxBufferSize >
+unsigned short endpoint_impl< MaxBufferSize >::get_port() const {
+ return 0;
+}
+
+template < int MaxBufferSize >
+bool endpoint_impl< MaxBufferSize >::is_udp() const {
+ return false;
+}
+
// Instantiate template
template class endpoint_impl< VSOMEIP_MAX_LOCAL_MESSAGE_SIZE >;
template class endpoint_impl< VSOMEIP_MAX_TCP_MESSAGE_SIZE >;
diff --git a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp index b7b5fc6..e30abb4 100644 --- a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp @@ -7,6 +7,7 @@ #include <boost/asio/write.hpp>
#include <vsomeip/defines.hpp>
+#include <vsomeip/logger.hpp>
#include "../include/tcp_client_endpoint_impl.hpp"
@@ -99,7 +100,7 @@ void tcp_client_endpoint_impl::send_magic_cookie() { data + sizeof(data)
);
} else {
- //VSOMEIP_WARNING << "Packet full. Cannot insert magic cookie!";
+ VSOMEIP_WARNING << "Packet full. Cannot insert magic cookie!";
}
}
diff --git a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp index b8b758b..f095c75 100644 --- a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp @@ -88,6 +88,31 @@ void tcp_server_endpoint_impl::join(const std::string &) { void tcp_server_endpoint_impl::leave(const std::string &) {
}
+bool tcp_server_endpoint_impl::is_v4() const {
+ return acceptor_.local_endpoint().address().is_v4();
+}
+
+bool tcp_server_endpoint_impl::get_address(std::vector< byte_t > &_address) const {
+ boost::asio::ip::address its_address = acceptor_.local_endpoint().address();
+ if (its_address.is_v4()) {
+ boost::asio::ip::address_v4 its_address_v4 = its_address.to_v4();
+ boost::asio::ip::address_v4::bytes_type its_bytes = its_address_v4.to_bytes();
+ _address.assign(its_bytes.data(), its_bytes.data() + sizeof(its_bytes));
+ } else {
+ boost::asio::ip::address_v6 its_address_v6 = its_address.to_v6();
+ boost::asio::ip::address_v6::bytes_type its_bytes = its_address_v6.to_bytes();
+ _address.assign(its_bytes.data(), its_bytes.data() + sizeof(its_bytes));
+ }
+ return true;
+}
+
+unsigned short tcp_server_endpoint_impl::get_port() const {
+ return acceptor_.local_endpoint().port();
+}
+
+bool tcp_server_endpoint_impl::is_udp() const {
+ return false;
+}
///////////////////////////////////////////////////////////////////////////////
// class tcp_service_impl::connection
diff --git a/implementation/endpoints/src/udp_server_endpoint_impl.cpp b/implementation/endpoints/src/udp_server_endpoint_impl.cpp index 71efb86..5a2bca2 100644 --- a/implementation/endpoints/src/udp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/udp_server_endpoint_impl.cpp @@ -106,6 +106,32 @@ void udp_server_endpoint_impl::leave(const std::string &_multicast_address) { }
}
+bool udp_server_endpoint_impl::is_v4() const {
+ return socket_.local_endpoint().address().is_v4();
+}
+
+bool udp_server_endpoint_impl::get_address(std::vector< byte_t > &_address) const {
+ boost::asio::ip::address its_address = socket_.local_endpoint().address();
+ if (its_address.is_v4()) {
+ boost::asio::ip::address_v4 its_address_v4 = its_address.to_v4();
+ boost::asio::ip::address_v4::bytes_type its_bytes = its_address_v4.to_bytes();
+ _address.assign(its_bytes.data(), its_bytes.data() + sizeof(its_bytes));
+ } else {
+ boost::asio::ip::address_v6 its_address_v6 = its_address.to_v6();
+ boost::asio::ip::address_v6::bytes_type its_bytes = its_address_v6.to_bytes();
+ _address.assign(its_bytes.data(), its_bytes.data() + sizeof(its_bytes));
+ }
+ return 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(boost::system::error_code const &_error, std::size_t _bytes) {
if (!_error && 0 < _bytes) {
diff --git a/implementation/routing/include/routing_manager_impl.hpp b/implementation/routing/include/routing_manager_impl.hpp index f10440b..cac752a 100644 --- a/implementation/routing/include/routing_manager_impl.hpp +++ b/implementation/routing/include/routing_manager_impl.hpp @@ -93,7 +93,7 @@ public: service_t _service, instance_t _instance, eventgroup_t _eventgroup); void send(client_t _client, - std::shared_ptr< message > _message, bool _reliable, bool _flush); + std::shared_ptr< message > _message, bool _flush, bool _reliable); void send(client_t _client, const byte_t *_data, uint32_t _size, instance_t _instance, bool _flush, bool _reliable); @@ -112,6 +112,7 @@ public: endpoint * find_local(service_t _service, instance_t _instance); const std::map< std::string, std::shared_ptr< servicegroup > > & get_servicegroups() const; + service_map_t get_offered_services(const std::string &_name) const; private: void on_message(const byte_t *_data, length_t _length, instance_t _instance); @@ -167,6 +168,9 @@ private: std::set< std::shared_ptr< endpoint > > > > > eventgroups_; std::map< service_t, std::map< instance_t, std::map< event_t, eventgroup_t > > > events_; + // Requested (but unknown) + std::set< std::shared_ptr< serviceinfo > > requested_; + // Mutexes std::recursive_mutex endpoint_mutex_; std::mutex serialize_mutex_; diff --git a/implementation/routing/include/routing_types.hpp b/implementation/routing/include/routing_types.hpp new file mode 100644 index 0000000..9016b78 --- /dev/null +++ b/implementation/routing/include/routing_types.hpp @@ -0,0 +1,25 @@ +// 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_TYPES_HPP +#define VSOMEIP_ROUTING_TYPES_HPP + +#include <map> +#include <memory> + +#include <vsomeip/primitive_types.hpp> + +namespace vsomeip { + +class serviceinfo; + +typedef std::map< service_t, + std::map< instance_t, + std::shared_ptr< serviceinfo > > > service_map_t; + +} // namespace vsomeip + +#endif // VSOMEIP_ROUTING_TYPES_HPP diff --git a/implementation/routing/include/servicegroup.hpp b/implementation/routing/include/servicegroup.hpp index f8ae4d9..0ea997b 100644 --- a/implementation/routing/include/servicegroup.hpp +++ b/implementation/routing/include/servicegroup.hpp @@ -11,6 +11,8 @@ #include <set> #include <string> +#include "routing_types.hpp" + namespace vsomeip { class serviceinfo; @@ -22,12 +24,14 @@ public: std::string get_name() const; - void add_service(std::shared_ptr< serviceinfo > _service); - void remove_service(std::shared_ptr< serviceinfo > _service); + 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; private: std::string name_; - std::set< std::shared_ptr< serviceinfo > > services_; + service_map_t services_; }; } // namespace vsomeip diff --git a/implementation/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp index 9196d28..6d8d94a 100644 --- a/implementation/routing/src/routing_manager_impl.cpp +++ b/implementation/routing/src/routing_manager_impl.cpp @@ -323,7 +323,8 @@ bool routing_manager_impl::is_available(service_t _service, instance_t _instance return false; } -const std::map< std::string, std::shared_ptr< servicegroup > > & routing_manager_impl::get_servicegroups() const { +const std::map< std::string, std::shared_ptr< servicegroup > > & +routing_manager_impl::get_servicegroups() const { return servicegroups_; } @@ -331,6 +332,17 @@ std::shared_ptr< configuration > routing_manager_impl::get_configuration() const return host_->get_configuration(); } +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(); + } + + return its_offers; +} + /////////////////////////////////////////////////////////////////////////////// // PRIVATE /////////////////////////////////////////////////////////////////////////////// @@ -380,7 +392,7 @@ void routing_manager_impl::create_service( if (found_servicegroup == servicegroups_.end()) { servicegroups_[its_servicegroup] = std::make_shared< servicegroup >(its_servicegroup); } - servicegroups_[its_servicegroup]->add_service(its_info); + servicegroups_[its_servicegroup]->add_service(_service, _instance, its_info); services_[_service][_instance] = its_info; } else { host_->on_error(); // TODO: Define configuration error "No valid port for service!" diff --git a/implementation/routing/src/servicegroup.cpp b/implementation/routing/src/servicegroup.cpp index b141fcc..d75ba80 100644 --- a/implementation/routing/src/servicegroup.cpp +++ b/implementation/routing/src/servicegroup.cpp @@ -19,12 +19,43 @@ std::string servicegroup::get_name() const { return name_; } -void servicegroup::add_service(std::shared_ptr< serviceinfo > _service) { - services_.insert(_service); +bool servicegroup::add_service( + service_t _service, instance_t _instance, + std::shared_ptr< serviceinfo > _info) { + bool its_result(true); + 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_result = false; + } else { + find_service->second[_instance] = _info; + } + } else { + services_[_service][_instance] = _info; + } + + return its_result; +} + +bool servicegroup::remove_service(service_t _service, instance_t _instance) { + bool its_result(false); + 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()) { + find_service->second.erase(_instance); + if (0 == find_service->second.size()) { + services_.erase(_service); + } + its_result = true; + } + } + return its_result; } -void servicegroup::remove_service(std::shared_ptr< serviceinfo > _service) { - services_.erase(_service); +service_map_t servicegroup::get_services() const { + return services_; } } // namespace vsomeip diff --git a/implementation/service_discovery/include/constants.hpp b/implementation/service_discovery/include/constants.hpp index 412c39d..d083882 100644 --- a/implementation/service_discovery/include/constants.hpp +++ b/implementation/service_discovery/include/constants.hpp @@ -13,16 +13,14 @@ namespace vsomeip { namespace sd { -const service_t VSOMEIP_SERVICE_DISCOVERY_SERVICE = 0xFFFF; -const instance_t VSOMEIP_SERVICE_DISCOVERY_INSTANCE = 0x0000; -const method_t VSOMEIP_SERVICE_DISCOVERY_METHOD = 0x8100; -const client_t VSOMEIP_SERVICE_DISCOVERY_CLIENT = 0x0000; -const protocol_version_t VSOMEIP_SERVICE_DISCOVERY_PROTOCOL_VERSION = 0x01; -const interface_version_t VSOMEIP_SERVICE_DISCOVERY_INTERFACE_VERSION = 0x01; -const message_type_e VSOMEIP_SERVICE_DISCOVERY_MESSAGE_TYPE = message_type_e::NOTIFICATION; -const return_code_e VSOMEIP_SERVICE_DISCOVERY_RETURN_CODE = return_code_e::E_OK; - -} // namespace sd +const service_t VSOMEIP_SD_SERVICE = 0xFFFF; +const instance_t VSOMEIP_SD_INSTANCE = 0x0000; +const method_t VSOMEIP_SD_METHOD = 0x8100; +const client_t VSOMEIP_SD_CLIENT = 0x0000; +const protocol_version_t VSOMEIP_SD_PROTOCOL_VERSION = 0x01; +const interface_version_t VSOMEIP_SD_INTERFACE_VERSION = 0x01; +const message_type_e VSOMEIP_SD_MESSAGE_TYPE = message_type_e::NOTIFICATION; +const return_code_e VSOMEIP_SD_RETURN_CODE = return_code_e::E_OK; namespace protocol { @@ -30,7 +28,11 @@ 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; + } // namespace protocol +} // namespace sd } // namespace vsomeip #endif // VSOMEIP_SD_CONSTANTS_HPP diff --git a/implementation/service_discovery/include/entry_impl.hpp b/implementation/service_discovery/include/entry_impl.hpp index b544230..71e0c73 100755 --- a/implementation/service_discovery/include/entry_impl.hpp +++ b/implementation/service_discovery/include/entry_impl.hpp @@ -7,6 +7,7 @@ #ifndef VSOMEIP_SD_ENTRY_IMPL_HPP
#define VSOMEIP_SD_ENTRY_IMPL_HPP
+#include <memory>
#include <vector>
#include <vsomeip/primitive_types.hpp>
@@ -46,7 +47,7 @@ public: void set_ttl(ttl_t _ttl);
const std::vector< uint8_t > & get_options(uint8_t _run) const;
- void assign_option(const option_impl &_option, uint8_t _run);
+ void assign_option(const std::shared_ptr< option_impl > &_option, uint8_t _run);
bool is_service_entry() const;
bool is_eventgroup_entry() const;
diff --git a/implementation/service_discovery/include/ipv4_option_impl.hpp b/implementation/service_discovery/include/ipv4_option_impl.hpp index 0d04a49..f6ec0d2 100644 --- a/implementation/service_discovery/include/ipv4_option_impl.hpp +++ b/implementation/service_discovery/include/ipv4_option_impl.hpp @@ -7,6 +7,10 @@ #ifndef VSOMEIP_SD_IPV4_OPTION_IMPL_HPP
#define VSOMEIP_SD_IPV4_OPTION_IMPL_HPP
+#include <vector>
+
+#include <vsomeip/primitive_types.hpp>
+
#include "option_impl.hpp"
namespace vsomeip {
@@ -18,13 +22,24 @@ public: virtual ~ipv4_option_impl();
bool operator == (const option_impl &_option) const;
+ const std::vector< byte_t > & get_address() const;
+ void set_address(const std::vector< byte_t > &_address);
+
+ unsigned short get_port() const;
+ void set_port(unsigned short _port);
+
+ bool is_udp() const;
+ void set_udp(bool _is_udp);
+
bool is_multicast() const;
bool serialize(vsomeip::serializer *_to) const;
bool deserialize(vsomeip::deserializer *_from);
protected:
- // TODO: add endpoint description based on boost classes
+ std::vector< byte_t > address_;
+ unsigned short port_;
+ bool is_udp_;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/ipv6_option_impl.hpp b/implementation/service_discovery/include/ipv6_option_impl.hpp index 4e11cde..8904c1d 100644 --- a/implementation/service_discovery/include/ipv6_option_impl.hpp +++ b/implementation/service_discovery/include/ipv6_option_impl.hpp @@ -7,6 +7,10 @@ #ifndef VSOMEIP_SD_IPV6_OPTION_IMPL_HPP
#define VSOMEIP_SD_IPV6_OPTION_IMPL_HPP
+#include <vector>
+
+#include <vsomeip/primitive_types.hpp>
+
#include "option_impl.hpp"
namespace vsomeip {
@@ -18,12 +22,24 @@ public: virtual ~ipv6_option_impl();
bool operator == (const option_impl &_option) const;
+ const std::vector< byte_t > & get_address() const;
+ void set_address(const std::vector< byte_t > &_address);
+
+ unsigned short get_port() const;
+ void set_port(unsigned short _port);
+
+ bool is_udp() const;
+ void set_udp(bool _is_udp);
+
bool is_multicast() const;
bool serialize(vsomeip::serializer *_to) const;
bool deserialize(vsomeip::deserializer *_from);
protected:
+ std::vector< byte_t > address_;
+ unsigned short port_;
+ bool is_udp_;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/message_impl.hpp b/implementation/service_discovery/include/message_impl.hpp index bad1cd4..a0cd30c 100755 --- a/implementation/service_discovery/include/message_impl.hpp +++ b/implementation/service_discovery/include/message_impl.hpp @@ -10,6 +10,8 @@ #include <memory>
#include <vector>
+#include <vsomeip/message.hpp>
+
#include "../include/primitive_types.hpp"
#include "../../message/include/message_base_impl.hpp"
@@ -27,7 +29,9 @@ class ipv6_option_impl; class load_balancing_option_impl;
class protection_option_impl;
-class message_impl: public vsomeip::message_base_impl {
+class message_impl:
+ public vsomeip::message,
+ public vsomeip::message_base_impl {
public:
message_impl();
virtual ~message_impl();
@@ -53,7 +57,10 @@ public: const std::vector< std::shared_ptr< entry_impl > > get_entries() const;
const std::vector< std::shared_ptr< option_impl > > get_options() const;
- int16_t get_option_index(const option_impl &_option) const;
+ int16_t get_option_index(const std::shared_ptr< option_impl > &_option) const;
+
+ std::shared_ptr< payload > get_payload() const;
+ void set_payload(std::shared_ptr< payload > _payload);
bool serialize(vsomeip::serializer *_to) const;
bool deserialize(vsomeip::deserializer *_from);
diff --git a/implementation/service_discovery/include/runtime.hpp b/implementation/service_discovery/include/runtime.hpp index 957ddf0..b2e0c8d 100644 --- a/implementation/service_discovery/include/runtime.hpp +++ b/implementation/service_discovery/include/runtime.hpp @@ -10,8 +10,10 @@ #include <memory>
namespace vsomeip {
+
namespace sd {
+class message_impl;
class service_discovery;
class service_discovery_host;
@@ -21,6 +23,7 @@ public: virtual ~runtime() {};
virtual std::shared_ptr< service_discovery > create_service_discovery(service_discovery_host *_host) const = 0;
+ virtual std::shared_ptr< message_impl > create_message() const = 0;
};
} // namespace sd
diff --git a/implementation/service_discovery/include/runtime_impl.hpp b/implementation/service_discovery/include/runtime_impl.hpp index 6f5c1f0..731c0be 100644 --- a/implementation/service_discovery/include/runtime_impl.hpp +++ b/implementation/service_discovery/include/runtime_impl.hpp @@ -18,6 +18,7 @@ public: virtual ~runtime_impl(); std::shared_ptr< service_discovery > create_service_discovery(service_discovery_host *_host) const; + std::shared_ptr< message_impl > create_message() const; }; } // namespace sd diff --git a/implementation/service_discovery/include/service_discovery.hpp b/implementation/service_discovery/include/service_discovery.hpp index 83f04f6..e49c749 100644 --- a/implementation/service_discovery/include/service_discovery.hpp +++ b/implementation/service_discovery/include/service_discovery.hpp @@ -34,6 +34,8 @@ public: virtual void request_service(service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor, ttl_t _ttl) = 0; virtual void release_service(service_t _service, instance_t _instance) = 0; + + virtual void send(const std::string &_name, bool _is_announcing) = 0; }; } // namespace sd diff --git a/implementation/service_discovery/include/service_discovery_fsm.hpp b/implementation/service_discovery/include/service_discovery_fsm.hpp index 74eaaf5..e5663be 100644 --- a/implementation/service_discovery/include/service_discovery_fsm.hpp +++ b/implementation/service_discovery/include/service_discovery_fsm.hpp @@ -127,6 +127,8 @@ public: void start(); void stop(); + void send(bool _is_announcing); + inline void process(const sc::event_base &_event) { fsm_->process_event(_event); } diff --git a/implementation/service_discovery/include/service_discovery_host.hpp b/implementation/service_discovery/include/service_discovery_host.hpp index 2120c15..61f068c 100644 --- a/implementation/service_discovery/include/service_discovery_host.hpp +++ b/implementation/service_discovery/include/service_discovery_host.hpp @@ -12,6 +12,8 @@ #include <boost/asio/io_service.hpp> +#include "../../routing/include/routing_types.hpp" + namespace vsomeip { class configuration; @@ -24,6 +26,10 @@ public: virtual boost::asio::io_service & get_io() = 0; virtual std::shared_ptr< configuration > get_configuration() const = 0; + + virtual service_map_t get_offered_services(const std::string &_name) const = 0; + + virtual void send(client_t _client, std::shared_ptr< message > _message, bool _flush, bool _reliable) = 0; }; } // namespace sd diff --git a/implementation/service_discovery/include/service_discovery_impl.hpp b/implementation/service_discovery/include/service_discovery_impl.hpp index d63c382..ac10b53 100644 --- a/implementation/service_discovery/include/service_discovery_impl.hpp +++ b/implementation/service_discovery/include/service_discovery_impl.hpp @@ -13,6 +13,7 @@ #include "service_discovery.hpp" #include "../../endpoints/include/endpoint_host.hpp" +#include "../../routing/include/routing_types.hpp" namespace vsomeip { @@ -45,15 +46,24 @@ public: major_version_t _major, minor_version_t _minor, ttl_t _ttl); void release_service(service_t _service, instance_t _instance); + void send(const std::string &_name, bool _is_announcing); + // endpoint_host void on_message(const byte_t *_data, length_t _length, endpoint *_receiver); private: + void insert_service_entries(std::shared_ptr< message_impl > &_message, + service_map_t &_services, bool _is_offer); + +private: boost::asio::io_service &io_; service_discovery_host *host_; std::shared_ptr< service_discovery_fsm > default_; - std::map< std::string, std::shared_ptr< service_discovery_fsm > > additional_; // one fsm represents one service group + std::map< std::string, + std::shared_ptr< service_discovery_fsm > > additional_; + + service_map_t requested_; std::shared_ptr< endpoint > endpoint_; }; diff --git a/implementation/service_discovery/src/entry_impl.cpp b/implementation/service_discovery/src/entry_impl.cpp index 75b2642..ba89c85 100755 --- a/implementation/service_discovery/src/entry_impl.cpp +++ b/implementation/service_discovery/src/entry_impl.cpp @@ -82,7 +82,7 @@ const std::vector< uint8_t > & entry_impl::get_options(uint8_t _run) const { return invalid_options;
}
-void entry_impl::assign_option(const option_impl &_option, uint8_t _run) {
+void entry_impl::assign_option(const std::shared_ptr< option_impl > &_option, uint8_t _run) {
if (_run > 0 && _run <= VSOMEIP_MAX_OPTION_RUN) {
_run--; // Index = Run-1
diff --git a/implementation/service_discovery/src/eventgroupentry_impl.cpp b/implementation/service_discovery/src/eventgroupentry_impl.cpp index ddfe58c..7f2481a 100755 --- a/implementation/service_discovery/src/eventgroupentry_impl.cpp +++ b/implementation/service_discovery/src/eventgroupentry_impl.cpp @@ -37,13 +37,13 @@ bool eventgroupentry_impl::serialize(vsomeip::serializer *_to) const { bool is_successful = entry_impl::serialize(_to);
is_successful = is_successful
- && _to->serialize(vsomeip::protocol::reserved_byte);
+ && _to->serialize(protocol::reserved_byte);
is_successful = is_successful
&& _to->serialize(static_cast< uint32_t >(ttl_), true);
is_successful = is_successful
- && _to->serialize(vsomeip::protocol::reserved_word);
+ && _to->serialize(protocol::reserved_word);
is_successful = is_successful
&& _to->serialize(static_cast< uint16_t >(eventgroup_));
diff --git a/implementation/service_discovery/src/ipv4_option_impl.cpp b/implementation/service_discovery/src/ipv4_option_impl.cpp index 272330b..5c1d863 100644 --- a/implementation/service_discovery/src/ipv4_option_impl.cpp +++ b/implementation/service_discovery/src/ipv4_option_impl.cpp @@ -6,6 +6,7 @@ #include <vsomeip/constants.hpp>
+#include "../include/constants.hpp"
#include "../include/ipv4_option_impl.hpp"
#include "../../message/include/deserializer.hpp"
#include "../../message/include/serializer.hpp"
@@ -29,19 +30,51 @@ bool ipv4_option_impl::operator ==(const option_impl &_other) const { return true;
}
+const std::vector< byte_t > & ipv4_option_impl::get_address() const {
+ return address_;
+}
+
+void ipv4_option_impl::set_address(const std::vector< byte_t > &_address) {
+ address_ = _address;
+}
+
+unsigned short ipv4_option_impl::get_port() const {
+ return port_;
+}
+
+void ipv4_option_impl::set_port(unsigned short _port) {
+ port_ = _port;
+}
+
+bool ipv4_option_impl::is_udp() const {
+ return is_udp_;
+}
+
+void ipv4_option_impl::set_udp(bool _is_udp) {
+ is_udp_ = _is_udp;
+}
+
bool ipv4_option_impl::is_multicast() const {
return (type_ == option_type_e::IP4_MULTICAST);
}
bool ipv4_option_impl::serialize(vsomeip::serializer *_to) const {
bool is_successful = option_impl::serialize(_to);
- // TODO: serialize specific part
+ _to->serialize(&address_[0], address_.size());
+ _to->serialize(protocol::reserved_byte);
+ _to->serialize(is_udp_ ? protocol::udp : protocol::tcp);
+ _to->serialize(port_);
return is_successful;
}
bool ipv4_option_impl::deserialize(vsomeip::deserializer *_from) {
bool is_successful = option_impl::deserialize(_from);
- // TODO: serialize specific part
+ uint8_t its_reserved;
+ _from->deserialize(&address_[0], 16);
+ _from->deserialize(its_reserved);
+ _from->deserialize(its_reserved);
+ is_udp_ = (protocol::udp == its_reserved);
+ _from->deserialize(port_);
return is_successful;
}
diff --git a/implementation/service_discovery/src/ipv6_option_impl.cpp b/implementation/service_discovery/src/ipv6_option_impl.cpp index 20a7988..9408e43 100755 --- a/implementation/service_discovery/src/ipv6_option_impl.cpp +++ b/implementation/service_discovery/src/ipv6_option_impl.cpp @@ -6,6 +6,7 @@ #include <cstring>
+#include "../include/constants.hpp"
#include "../include/ipv6_option_impl.hpp"
#include "../../message/include/deserializer.hpp"
#include "../../message/include/serializer.hpp"
@@ -31,16 +32,47 @@ bool ipv6_option_impl::operator ==(const option_impl &_other) const { return true; // TODO:
}
+const std::vector< byte_t > & ipv6_option_impl::get_address() const {
+ return address_;
+}
+
+void ipv6_option_impl::set_address(const std::vector< byte_t > &_address) {
+ address_ = _address;
+}
+
+unsigned short ipv6_option_impl::get_port() const {
+ return port_;
+}
+
+void ipv6_option_impl::set_port(unsigned short _port) {
+ port_ = _port;
+}
+
+bool ipv6_option_impl::is_udp() const {
+ return is_udp_;
+}
+
+void ipv6_option_impl::set_udp(bool _is_udp) {
+ is_udp_ = _is_udp;
+}
bool ipv6_option_impl::serialize(vsomeip::serializer *_to) const {
bool is_successful = option_impl::serialize(_to);
- // TODO: deserialize content
+ _to->serialize(&address_[0], address_.size());
+ _to->serialize(protocol::reserved_byte);
+ _to->serialize(is_udp_ ? protocol::udp : protocol::tcp);
+ _to->serialize(port_);
return is_successful;
}
bool ipv6_option_impl::deserialize(vsomeip::deserializer *_from) {
bool is_successful = option_impl::deserialize(_from);
- // TODO: deserialize content
+ uint8_t its_reserved;
+ _from->deserialize(&address_[0], 4);
+ _from->deserialize(its_reserved);
+ _from->deserialize(its_reserved);
+ is_udp_ = (protocol::udp == its_reserved);
+ _from->deserialize(port_);
return is_successful;
}
diff --git a/implementation/service_discovery/src/message_impl.cpp b/implementation/service_discovery/src/message_impl.cpp index 8840a47..9cf8c44 100755 --- a/implementation/service_discovery/src/message_impl.cpp +++ b/implementation/service_discovery/src/message_impl.cpp @@ -141,11 +141,11 @@ const std::vector< std::shared_ptr< option_impl > > message_impl::get_options() }
// TODO: throw exception to signal "OptionNotFound"
-int16_t message_impl::get_option_index(const option_impl &_option) const {
+int16_t message_impl::get_option_index(const std::shared_ptr< option_impl > &_option) const {
int16_t i = 0;
while (i < options_.size()) {
- if (*(options_[i].get()) == _option)
+ if (options_[i] == _option)
return i;
i++;
}
@@ -158,7 +158,7 @@ bool message_impl::serialize(vsomeip::serializer *_to) const { is_successful = is_successful && _to->serialize(flags_);
is_successful = is_successful
- && _to->serialize(vsomeip::protocol::reserved_long, true);
+ && _to->serialize(protocol::reserved_long, true);
uint32_t entries_length = (entries_.size() * VSOMEIP_SOMEIP_SD_ENTRY_SIZE);
is_successful = is_successful && _to->serialize(entries_length);
diff --git a/implementation/service_discovery/src/option_impl.cpp b/implementation/service_discovery/src/option_impl.cpp index 552aad8..92c3132 100755 --- a/implementation/service_discovery/src/option_impl.cpp +++ b/implementation/service_discovery/src/option_impl.cpp @@ -36,7 +36,7 @@ bool option_impl::serialize(vsomeip::serializer *_to) const { return (0 != _to
&& _to->serialize(length_)
&& _to->serialize(static_cast<uint8_t>(type_))
- && _to->serialize(vsomeip::protocol::reserved_byte));
+ && _to->serialize(protocol::reserved_byte));
}
bool option_impl::deserialize(vsomeip::deserializer *_from) {
diff --git a/implementation/service_discovery/src/runtime_impl.cpp b/implementation/service_discovery/src/runtime_impl.cpp index 32c943d..b1f9b47 100644 --- a/implementation/service_discovery/src/runtime_impl.cpp +++ b/implementation/service_discovery/src/runtime_impl.cpp @@ -5,7 +5,10 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include <vsomeip/defines.hpp> +#include <vsomeip/message.hpp> +#include "../include/constants.hpp" +#include "../include/message_impl.hpp" #include "../include/runtime_impl.hpp" #include "../include/service_discovery_impl.hpp" @@ -24,5 +27,19 @@ std::shared_ptr< service_discovery > runtime_impl::create_service_discovery(serv return std::make_shared< service_discovery_impl >(_host); } +std::shared_ptr< message_impl > runtime_impl::create_message() const { + std::shared_ptr< message_impl > its_message = std::make_shared< message_impl >(); + its_message->set_service(VSOMEIP_SD_SERVICE); + its_message->set_instance(VSOMEIP_SD_INSTANCE); + its_message->set_method(VSOMEIP_SD_METHOD); + its_message->set_client(VSOMEIP_SD_CLIENT); + // session must be set dynamically + its_message->set_protocol_version(VSOMEIP_SD_PROTOCOL_VERSION); + its_message->set_interface_version(VSOMEIP_SD_INTERFACE_VERSION); + its_message->set_message_type(VSOMEIP_SD_MESSAGE_TYPE); + its_message->set_return_code(VSOMEIP_SD_RETURN_CODE); + return its_message; +} + } // namespace sd } // namespace vsomeip diff --git a/implementation/service_discovery/src/service_discovery_fsm.cpp b/implementation/service_discovery/src/service_discovery_fsm.cpp index 6694c44..7ed190d 100644 --- a/implementation/service_discovery/src/service_discovery_fsm.cpp +++ b/implementation/service_discovery/src/service_discovery_fsm.cpp @@ -97,6 +97,7 @@ repeat::repeat(my_context _context): sc::state< repeat, active >(_context) { VSOMEIP_DEBUG << "sd<" << outermost_context().fsm_->get_name() << ">::active.repeat"; uint32_t its_timeout = (outermost_context().repetition_base_delay_ << outermost_context().run_); outermost_context().run_ ++; + outermost_context().fsm_->send(false); outermost_context().start_timer(its_timeout); } @@ -117,6 +118,7 @@ sc::result repeat::react(const ev_find_service &_event) { announce::announce(my_context _context): sc::state< announce, active >(_context) { VSOMEIP_DEBUG << "sd<" << outermost_context().fsm_->get_name() << ">::active.announce"; outermost_context().start_timer(outermost_context().cyclic_offer_delay_); + outermost_context().fsm_->send(true); } sc::result announce::react(const ev_timeout &_event) { @@ -176,5 +178,9 @@ void service_discovery_fsm::start() { void service_discovery_fsm::stop() { } +void service_discovery_fsm::send(bool _is_announcing) { + discovery_->send(name_, _is_announcing); +} + } // 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 9675943..bb86bb9 100644 --- a/implementation/service_discovery/src/service_discovery_impl.cpp +++ b/implementation/service_discovery/src/service_discovery_impl.cpp @@ -7,12 +7,19 @@ #include <vsomeip/configuration.hpp> #include <vsomeip/logger.hpp> +#include "../include/constants.hpp" +#include "../include/ipv4_option_impl.hpp" +#include "../include/ipv6_option_impl.hpp" +#include "../include/message_impl.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 "../../endpoints/include/tcp_server_endpoint_impl.hpp" #include "../../endpoints/include/udp_server_endpoint_impl.hpp" #include "../../routing/include/servicegroup.hpp" +#include "../../routing/include/serviceinfo.hpp" namespace vsomeip { namespace sd { @@ -100,12 +107,106 @@ void service_discovery_impl::request_service(service_t _service, ttl_t _ttl) { VSOMEIP_DEBUG << "sdi::request_service [" << std::hex << _service << "." << _instance << "]"; + 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); + } } void service_discovery_impl::release_service(service_t _service, instance_t _instance) { - VSOMEIP_DEBUG << "sdi::release_service [" << std::hex << _service << "." - << _instance << "]"; + auto find_service = requested_.find(_service); + if (find_service != requested_.end()) { + find_service->second.erase(_instance); + } +} + +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_reliable_endpoint(); + if (its_endpoint) { + if (its_endpoint->is_v4()) { + std::shared_ptr< ipv4_option_impl > its_option + = _message->create_ipv4_option(false); + if (its_option) { + std::vector< byte_t > its_address; + if (its_endpoint->get_address(its_address)) { + its_option->set_address(its_address); + its_option->set_port(its_endpoint->get_port()); + its_option->set_udp(its_endpoint->is_udp()); + its_entry->assign_option(its_option, 1); + } + } + } else { + std::shared_ptr< ipv6_option_impl > its_option + = _message->create_ipv6_option(false); + if (its_option) { + std::shared_ptr< ipv4_option_impl > its_option + = _message->create_ipv4_option(false); + if (its_option) { + std::vector< byte_t > its_address; + if (its_endpoint->get_address(its_address)) { + its_option->set_address(its_address); + its_option->set_port(its_endpoint->get_port()); + its_option->set_udp(its_endpoint->is_udp()); + its_entry->assign_option(its_option, 1); + } + } + } + } + } + } else { + VSOMEIP_ERROR << "Failed to create service entry."; + } + } + } +} + + +void service_discovery_impl::send(const std::string &_name, bool _is_announcing) { + //std::unique_lock its_lock(serializer_mutex_); + + std::shared_ptr< message_impl > its_message = runtime::get()->create_message(); + + // TODO: optimize building of SD message (common options) + + // 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); + + // Serialize and send + host_->send(VSOMEIP_SD_CLIENT, its_message, true, false); } // Interface endpoint_host |