diff options
author | Lutz Bichler <Lutz.Bichler@bmw.de> | 2014-07-14 12:06:20 +0200 |
---|---|---|
committer | Lutz Bichler <Lutz.Bichler@bmw.de> | 2014-07-14 12:06:20 +0200 |
commit | ecd8282b5998a384a3c746a7826204c22760cf23 (patch) | |
tree | d4f9f742111c2d1f3a85fb11c2eb75c22a4df1e3 | |
parent | 3e8509da17d1914d2bfa3030f83c6aeddd9ee04e (diff) | |
download | vSomeIP-ecd8282b5998a384a3c746a7826204c22760cf23.tar.gz |
Implemented static UDP & TCP routing.
Added configuration files for testing TCP/UDP communication.
Replaced buffer queue handling by passing shared pointer to avoid buffer
overwrites.
Extended clients sample: Sending is now done in an extra thread as
sleeping in a callback is a bad idea if the client hosts the routing
manager ;-).
TODO: Re-enable Magic Cookies for TCP
Finalitze Service Discovery
45 files changed, 839 insertions, 536 deletions
@@ -1,2 +1,2 @@ -/build/*
+/build*/*
/.settings
diff --git a/CMakeLists.txt b/CMakeLists.txt index c49e512..ebdb847 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -79,13 +79,13 @@ add_library(vsomeip-sd SHARED ${vsomeip-sd_SRC}) target_link_libraries(vsomeip-sd vsomeip ${Boost_LIBRARIES} rt ${DL_LIBRARY})
# Executables
-add_executable(configuration-test implementation/test/configuration-test.cpp)
+add_executable(configuration-test test/configuration-test.cpp)
target_link_libraries(configuration-test vsomeip ${Boost_LIBRARIES} ${DL_LIBRARY})
-add_executable(client-sample implementation/examples/client-sample.cpp)
+add_executable(client-sample examples/client-sample.cpp)
target_link_libraries(client-sample vsomeip ${Boost_LIBRARIES} ${DL_LIBRARY})
-add_executable(service-sample implementation/examples/service-sample.cpp)
+add_executable(service-sample examples/service-sample.cpp)
target_link_libraries(service-sample vsomeip ${Boost_LIBRARIES} ${DL_LIBRARY})
###################################################################################################
diff --git a/config/vsomeip-tcp-client.xml b/config/vsomeip-tcp-client.xml new file mode 100644 index 0000000..1917584 --- /dev/null +++ b/config/vsomeip-tcp-client.xml @@ -0,0 +1,53 @@ +<!-- vsomeip test configuration file --> +<someip> + <address>192.168.56.101</address> + <logging> + <level>trace</level> + <console>true</console> + <file> + <enable>false</enable> + <path>/tmp/vsomeip.log</path> + </file> + <dlt>false</dlt> + </logging> + <services> + <servicegroup> + <name>remote</name> + <address>192.168.56.102</address> + <service> + <service-id>0x1234</service-id> + <instance-id>0x5678</instance-id> + <ports> + <reliable>30509</reliable> + </ports> + </service> + </servicegroup> + </services> + <routing> + <host>client-sample</host> + </routing> + <service-discovery> + <enabled>false</enabled> + <protocol>udp</protocol> + <address>224.244.224.245</address> + <port>30490</port> + </service-discovery> + <applications> + <application> + <name>client-sample</name> + <id>0x1343</id> + </application> + <application> + <name>second-client-sample</name> + <id>0x1344</id> + </application> + <application> + <name>third-client-sample</name> + <id>0x1345</id> + </application> + <application> + <name>fourth-client-sample</name> + <id>0x1346</id> + </application> + </applications> +</someip> diff --git a/config/vsomeip-service.xml b/config/vsomeip-tcp-service.xml index e0f53c1..8d68831 100644 --- a/config/vsomeip-service.xml +++ b/config/vsomeip-tcp-service.xml @@ -27,7 +27,7 @@ <service-id>0x1234</service-id> <instance-id>0x5678</instance-id> <ports> - <reliable>30507</reliable> + <reliable>30509</reliable> </ports> </service> </servicegroup> diff --git a/config/vsomeip-client.xml b/config/vsomeip-udp-client.xml index 2af6295..edd66aa 100644 --- a/config/vsomeip-client.xml +++ b/config/vsomeip-udp-client.xml @@ -28,7 +28,6 @@ </routing> <service-discovery> <enabled>false</enabled> - <host>client-sample</host> <protocol>udp</protocol> <address>224.244.224.245</address> <port>30490</port> @@ -39,8 +38,16 @@ <id>0x1343</id> </application> <application> - <name>other-client-sample</name> + <name>second-client-sample</name> <id>0x1344</id> </application> + <application> + <name>third-client-sample</name> + <id>0x1345</id> + </application> + <application> + <name>fourth-client-sample</name> + <id>0x1346</id> + </application> </applications> </someip> diff --git a/config/vsomeip-udp-second-client.xml b/config/vsomeip-udp-second-client.xml new file mode 100644 index 0000000..36b4c01 --- /dev/null +++ b/config/vsomeip-udp-second-client.xml @@ -0,0 +1,53 @@ +<!-- vsomeip test configuration file --> +<someip> + <address>192.168.56.101</address> + <logging> + <level>trace</level> + <console>true</console> + <file> + <enable>false</enable> + <path>/tmp/vsomeip.log</path> + </file> + <dlt>false</dlt> + </logging> + <services> + <servicegroup> + <name>remote</name> + <address>192.168.56.102</address> + <service> + <service-id>0x1234</service-id> + <instance-id>0x5678</instance-id> + <ports> + <unreliable>30507</unreliable> + </ports> + </service> + </servicegroup> + </services> + <routing> + <host>second-client-sample</host> + </routing> + <service-discovery> + <enabled>false</enabled> + <protocol>udp</protocol> + <address>224.244.224.245</address> + <port>30490</port> + </service-discovery> + <applications> + <application> + <name>client-sample</name> + <id>0x1343</id> + </application> + <application> + <name>second-client-sample</name> + <id>0x1344</id> + </application> + <application> + <name>third-client-sample</name> + <id>0x1345</id> + </application> + <application> + <name>fourth-client-sample</name> + <id>0x1346</id> + </application> + </applications> +</someip> diff --git a/config/vsomeip-udp-service.xml b/config/vsomeip-udp-service.xml new file mode 100644 index 0000000..65320c4 --- /dev/null +++ b/config/vsomeip-udp-service.xml @@ -0,0 +1,51 @@ +<!-- vsomeip test configuration file --> +<someip> + <address>192.168.56.102</address> + <logging> + <level>trace</level> + <console>true</console> + <file> + <enable>false</enable> + <path>/tmp/vsomeip.log</path> + </file> + <dlt>false</dlt> + </logging> + <services> + <servicegroup> + <name>default</name> + <delays> + <initial> + <min>10</min> + <max>100</max> + </initial> + <repetition-base>200</repetition-base> + <repetition-max>3</repetition-max> + <cyclic-offer>2000</cyclic-offer> + <cyclic-request>2001</cyclic-request> + </delays> + <service> + <service-id>0x1234</service-id> + <instance-id>0x5678</instance-id> + <ports> + <unreliable>30507</unreliable> + </ports> + </service> + </servicegroup> + </services> + <routing> + <host>service-sample</host> + </routing> + <service-discovery> + <enabled>false</enabled> + <host>client-sample</host> + <protocol>udp</protocol> + <address>224.244.224.245</address> + <port>30490</port> + </service-discovery> + <applications> + <application> + <name>service-sample</name> + <id>0x1277</id> + </application> + </applications> +</someip> diff --git a/config/vsomeip.xml b/config/vsomeip.xml index adac510..52ca502 100644 --- a/config/vsomeip.xml +++ b/config/vsomeip.xml @@ -1,6 +1,6 @@ <!-- vsomeip test configuration file --> <someip> - <address>10.0.2.15</address> + <address>192.168.56.101</address> <logging> <level>trace</level> <console>true</console> @@ -41,24 +41,12 @@ <multicast>225.225.225.2</multicast> </service> </servicegroup> - <servicegroup> - <name>remote</name> - <address>10.0.2.17</address> - <service> - <service-id>0x4466</service-id> - <instance-id>0x0421</instance-id> - <port> - <reliable>30507</reliable> - </port> - </service> - </servicegroup> </services> <routing> <host>client-sample</host> </routing> <service-discovery> - <enabled>false</enabled> - <host>client-sample</host> + <enabled>true</enabled> <protocol>udp</protocol> <address>224.244.224.245</address> <port>30490</port> diff --git a/examples/client-sample.cpp b/examples/client-sample.cpp new file mode 100644 index 0000000..f275db1 --- /dev/null +++ b/examples/client-sample.cpp @@ -0,0 +1,185 @@ +// 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 <chrono> +#include <condition_variable> +#include <iomanip> +#include <iostream> +#include <sstream> +#include <thread> + +#include <vsomeip/vsomeip.hpp> + +#include "sample-ids.hpp" + +class client_sample { +public: + client_sample(bool _use_tcp, bool _be_quiet, uint32_t _cycle) + : app_(vsomeip::runtime::get()->create_application()), + request_(vsomeip::runtime::get()->create_request()), + use_tcp_(_use_tcp), + be_quiet_(_be_quiet), + cycle_(_cycle), + sender_(std::bind(&client_sample::run, this)), + running_(true) { + } + + void init() { + app_->init(); + + VSOMEIP_INFO << "Client settings [protocol=" + << (use_tcp_ ? "TCP" : "UDP") + << ":quiet=" + << (be_quiet_ ? "true" : "false") + << ":cycle=" + << cycle_ + << "]"; + + app_->register_event_handler( + std::bind( + &client_sample::on_event, + this, + std::placeholders::_1)); + + 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::VSOMEIP_ANY_SERVICE, SAMPLE_INSTANCE_ID, vsomeip::VSOMEIP_ANY_METHOD, + std::bind(&client_sample::on_message, + this, + std::placeholders::_1)); + + request_->set_service(SAMPLE_SERVICE_ID); + request_->set_instance(SAMPLE_INSTANCE_ID); + request_->set_method(SAMPLE_METHOD_ID); + + 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 < 10; ++i) its_payload_data.push_back(i % 256); + its_payload->set_data(its_payload_data); + request_->set_payload(its_payload); + } + + void start() { + app_->start(); + } + + void on_event(vsomeip::event_type_e _event) { + if (_event == vsomeip::event_type_e::REGISTERED) { + //app_->offer_service(OTHER_SAMPLE_SERVICE_ID, OTHER_SAMPLE_INSTANCE_ID); + app_->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID); + } + } + + 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 (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; + send(); + } + } + } + + void on_message(std::shared_ptr< vsomeip::message > &_response) { + VSOMEIP_INFO << "Received a response from Service [" + << std::setw(4) << std::setfill('0') << std::hex << _response->get_service() + << "." + << std::setw(4) << std::setfill('0') << std::hex << _response->get_instance() + << "] to Client/Session [" + << std::setw(4) << std::setfill('0') << std::hex << _response->get_client() + << "/" + << std::setw(4) << std::setfill('0') << std::hex << _response->get_session() + << "]"; + if (session_ == _response->get_session()) { + send(); + } else { + std::cout << "WRONG RESPONSE!" << std::endl; + } + } + + void send() { + if (!be_quiet_) + { + std::unique_lock< std::mutex > its_lock(mutex_); + condition_.notify_one(); + } + } + + void run() { + while (running_) { + std::unique_lock< std::mutex > its_lock(mutex_); + condition_.wait(its_lock); + std::this_thread::sleep_for(std::chrono::milliseconds(cycle_)); + app_->send(request_, true, use_tcp_); + VSOMEIP_INFO << "Client/Session [" + << std::setw(4) << std::setfill('0') << std::hex << request_->get_client() + << "/" + << std::setw(4) << std::setfill('0') << std::hex << request_->get_session() + << "] sent a request to Service [" + << std::setw(4) << std::setfill('0') << std::hex << request_->get_service() + << "." + << std::setw(4) << std::setfill('0') << std::hex << request_->get_instance() + << "]"; + session_ = request_->get_session(); + } + } + +private: + std::shared_ptr< vsomeip::application > app_; + std::shared_ptr< vsomeip::message > request_; + bool use_tcp_; + bool be_quiet_; + uint32_t cycle_; + vsomeip::session_t session_; + std::mutex mutex_; + std::condition_variable condition_; + std::thread sender_; + bool running_; +}; + + +int main(int argc, char **argv) { + bool use_tcp = false; + bool be_quiet = false; + uint32_t cycle = 1000; // Default: 1s + + std::string tcp_enable("--tcp"); + std::string udp_enable("--udp"); + std::string quiet_enable("--quiet"); + std::string cycle_arg("--cycle"); + + int i = 1; + while (i < argc) { + if (tcp_enable == argv[i]) { + use_tcp = true; + } else if (udp_enable == argv[i]) { + use_tcp = false; + } else if (quiet_enable == argv[i]) { + be_quiet = true; + } else if (cycle_arg == argv[i] && i+1 < argc) { + i++; + std::stringstream converter; + converter << argv[i]; + converter >> cycle; + } + i++; + } + + client_sample its_sample(use_tcp, be_quiet, cycle); + its_sample.init(); + its_sample.start(); + return 0; +} diff --git a/implementation/examples/readme.txt b/examples/readme.txt index 6385c08..6385c08 100644 --- a/implementation/examples/readme.txt +++ b/examples/readme.txt diff --git a/implementation/examples/sample-ids.hpp b/examples/sample-ids.hpp index 3fc097f..3fc097f 100644 --- a/implementation/examples/sample-ids.hpp +++ b/examples/sample-ids.hpp diff --git a/implementation/examples/service-sample.cpp b/examples/service-sample.cpp index fbff80d..e68a16b 100644 --- a/implementation/examples/service-sample.cpp +++ b/examples/service-sample.cpp @@ -14,11 +14,14 @@ class service_sample { public: - service_sample() - : app_(vsomeip::runtime::get()->create_application()), is_registered_(false) { + service_sample(bool _use_tcp) + : app_(vsomeip::runtime::get()->create_application()), + is_registered_(false), + use_tcp_(_use_tcp) { } void init() { + app_->init(); app_->register_message_handler( SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_METHOD_ID, std::bind(&service_sample::on_message, @@ -28,8 +31,6 @@ public: app_->register_event_handler( std::bind(&service_sample::on_event, this, std::placeholders::_1)); - - app_->init(); } void start() { @@ -71,17 +72,34 @@ public: its_payload->set_data(its_payload_data); its_response->set_payload(its_payload); - app_->send(its_response); + app_->send(its_response, true, use_tcp_); } private: std::shared_ptr< vsomeip::application > app_; bool is_registered_; + bool use_tcp_; }; int main(int argc, char **argv) { - service_sample its_sample; + 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(); diff --git a/implementation/configuration/include/internal.hpp b/implementation/configuration/include/internal.hpp index 8f2bd19..e4b75cd 100644 --- a/implementation/configuration/include/internal.hpp +++ b/implementation/configuration/include/internal.hpp @@ -15,7 +15,7 @@ namespace vsomeip { #define VSOMEIP_SD_RUNTIME_SYMBOL VSOMEIP_SD_RUNTIME #define VSOMEIP_SD_RUNTIME_SYMBOL_STRING "VSOMEIP_SD_RUNTIME" -#define VSOMEIP_ROUTING_ENDPOINT "rtg" +#define VSOMEIP_ROUTING_CLIENT 0 #define VSOMEIP_DEFAULT_CONNECT_TIMEOUT 100 #define VSOMEIP_DEFAULT_FLUSH_TIMEOUT 1000 diff --git a/implementation/endpoints/include/buffer.hpp b/implementation/endpoints/include/buffer.hpp new file mode 100644 index 0000000..071baaa --- /dev/null +++ b/implementation/endpoints/include/buffer.hpp @@ -0,0 +1,22 @@ +// 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_BUFFER_HPP +#define VSOMEIP_BUFFER_HPP + +#include <array> +#include <memory> + +#include <vsomeip/primitive_types.hpp> + +namespace vsomeip { + +typedef std::vector< byte_t > buffer_t; +typedef std::shared_ptr< buffer_t > buffer_ptr_t; + +} // namespace vsomeip + +#endif // VSOMEIP_BUFFER_HPP diff --git a/implementation/endpoints/include/client_endpoint_impl.hpp b/implementation/endpoints/include/client_endpoint_impl.hpp index 52328b1..c924474 100644 --- a/implementation/endpoints/include/client_endpoint_impl.hpp +++ b/implementation/endpoints/include/client_endpoint_impl.hpp @@ -16,6 +16,7 @@ #include <boost/asio/ip/udp.hpp>
#include <boost/utility.hpp>
+#include "buffer.hpp"
#include "endpoint_impl.hpp"
namespace vsomeip {
@@ -43,14 +44,13 @@ public: void restart();
bool is_client() const;
- const uint8_t * get_buffer() const;
public:
void connect_cbk(boost::system::error_code const &_error);
void wait_connect_cbk(boost::system::error_code const &_error);
- void send_cbk(boost::system::error_code const &_error, std::size_t _bytes);
+ void send_cbk(std::shared_ptr< buffer_t >, boost::system::error_code const &_error, std::size_t _bytes);
void flush_cbk(boost::system::error_code const &_error);
- void receive_cbk(boost::system::error_code const &_error, std::size_t _bytes);
+ void receive_cbk(buffer_ptr_t _buffer, boost::system::error_code const &_error, std::size_t _bytes);
public:
virtual void connect() = 0;
@@ -59,7 +59,6 @@ public: protected:
socket_type socket_;
endpoint_type remote_;
- boost::array< byte_t, MaxBufferSize > buffer_;
boost::asio::system_timer flush_timer_;
boost::asio::system_timer connect_timer_;
@@ -67,15 +66,16 @@ protected: bool is_connected_;
// send data
- std::deque< std::vector< byte_t > > packet_queue_;
- std::vector< byte_t > packetizer_;
+ //std::deque< std::vector< byte_t > > packet_queue_;
+ std::shared_ptr< std::vector< byte_t > > packetizer_;
// receive data
std::vector< byte_t > message_;
std::mutex mutex_;
- virtual void send_queued() = 0;
+ uint32_t queued_;
+ virtual void send_queued(std::shared_ptr< std::vector< byte_t > >) = 0;
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/endpoint.hpp b/implementation/endpoints/include/endpoint.hpp index 1b4ad12..bc1ac3b 100644 --- a/implementation/endpoints/include/endpoint.hpp +++ b/implementation/endpoints/include/endpoint.hpp @@ -20,7 +20,7 @@ public: virtual void stop() = 0;
virtual bool send(const byte_t *_data, uint32_t _size, bool _flush = true) = 0;
- virtual bool flush() = 0;
+ virtual void receive() = 0;
virtual void open_filter(service_t _service_id) = 0;
virtual void close_filter(service_t _service_id) = 0;
diff --git a/implementation/endpoints/include/endpoint_impl.hpp b/implementation/endpoints/include/endpoint_impl.hpp index b062a56..5055f99 100644 --- a/implementation/endpoints/include/endpoint_impl.hpp +++ b/implementation/endpoints/include/endpoint_impl.hpp @@ -41,8 +41,6 @@ public: bool is_udp() const;
public: // required
- virtual const uint8_t * get_buffer() const = 0;
-
virtual void receive() = 0;
virtual void restart() = 0;
diff --git a/implementation/endpoints/include/local_client_endpoint_impl.hpp b/implementation/endpoints/include/local_client_endpoint_impl.hpp index 96deaca..9224a67 100644 --- a/implementation/endpoints/include/local_client_endpoint_impl.hpp +++ b/implementation/endpoints/include/local_client_endpoint_impl.hpp @@ -23,11 +23,12 @@ typedef client_endpoint_impl< class local_client_endpoint_impl
: public local_client_endpoint_base_impl {
public:
- local_client_endpoint_impl(std::shared_ptr< endpoint_host > _host, endpoint_type _local, boost::asio::io_service &_io);
+ local_client_endpoint_impl(std::shared_ptr< endpoint_host > _host,
+ endpoint_type _local, boost::asio::io_service &_io);
void start();
- void send_queued();
+ void send_queued(buffer_ptr_t _data);
void join(const std::string &);
void leave(const std::string &);
@@ -39,7 +40,8 @@ private: void receive();
void send_tag_cbk(boost::system::error_code const &_error, std::size_t _bytes);
- void receive_cbk(boost::system::error_code const &_error, std::size_t _bytes);
+ void receive_cbk(buffer_ptr_t _buffer,
+ boost::system::error_code const &_error, std::size_t _bytes);
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/local_server_endpoint_impl.hpp b/implementation/endpoints/include/local_server_endpoint_impl.hpp index f139972..e4b0004 100644 --- a/implementation/endpoints/include/local_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/local_server_endpoint_impl.hpp @@ -14,6 +14,8 @@ #include <boost/enable_shared_from_this.hpp>
#include <vsomeip/defines.hpp>
+
+#include "buffer.hpp"
#include "server_endpoint_impl.hpp"
namespace vsomeip {
@@ -37,7 +39,7 @@ public: const uint8_t * get_buffer() const;
- void send_queued();
+ void send_queued(endpoint_type _target, std::shared_ptr< buffer_t > _data);
endpoint_type get_remote() const;
void join(const std::string &);
@@ -55,8 +57,7 @@ private: void start();
- void send_queued();
- const uint8_t * get_buffer() const;
+ void send_queued(buffer_ptr_t _data);
private:
connection(local_server_endpoint_impl *_owner);
@@ -64,14 +65,14 @@ private: void send_magic_cookie();
local_server_endpoint_impl::socket_type socket_;
- buffer_type buffer_;
local_server_endpoint_impl *server_;
// the current message
std::vector< byte_t > message_;
private:
- void receive_cbk(boost::system::error_code const &_error, std::size_t _bytes);
+ void receive_cbk(buffer_ptr_t _buffer,
+ boost::system::error_code const &_error, std::size_t _bytes);
};
boost::asio::local::stream_protocol::acceptor acceptor_;
diff --git a/implementation/endpoints/include/server_endpoint_impl.hpp b/implementation/endpoints/include/server_endpoint_impl.hpp index 14e252c..d24c11f 100644 --- a/implementation/endpoints/include/server_endpoint_impl.hpp +++ b/implementation/endpoints/include/server_endpoint_impl.hpp @@ -16,6 +16,7 @@ #include <boost/array.hpp>
#include <boost/asio/io_service.hpp>
+#include "buffer.hpp"
#include "endpoint_impl.hpp"
namespace vsomeip {
@@ -23,44 +24,40 @@ 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 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 send(const uint8_t *_data, uint32_t _size, bool _flush);
- bool flush();
+ bool flush(endpoint_type _target);
public:
void connect_cbk(boost::system::error_code const &_error);
- void send_cbk(boost::system::error_code const &_error, std::size_t _bytes);
+ void send_cbk(std::shared_ptr< buffer_t > _data,
+ 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() = 0;
+ virtual void send_queued(endpoint_type _target, buffer_ptr_t _buffer) = 0;
virtual endpoint_type get_remote() const = 0;
protected:
- typedef std::map< endpoint_type, std::deque< std::vector< byte_t > > > queue_type_t;
- queue_type_t packet_queues_;
- typename queue_type_t::iterator current_queue_;
- std::map< endpoint_type, std::vector< byte_t > > packetizer_;
-
- std::map< client_t, endpoint_type > clients_;
+ std::map< endpoint_type, std::shared_ptr< buffer_t > > packetizer_;
+ std::map< client_t, std::map< session_t, endpoint_type > > clients_;
boost::asio::system_timer flush_timer_;
endpoint_type local_;
std::mutex mutex_;
-
-private:
- bool set_next_queue();
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/tcp_client_endpoint_impl.hpp b/implementation/endpoints/include/tcp_client_endpoint_impl.hpp index d78a8b2..b8db7fa 100644 --- a/implementation/endpoints/include/tcp_client_endpoint_impl.hpp +++ b/implementation/endpoints/include/tcp_client_endpoint_impl.hpp @@ -21,11 +21,12 @@ typedef client_endpoint_impl< class tcp_client_endpoint_impl
: public tcp_client_endpoint_base_impl {
public:
- tcp_client_endpoint_impl(std::shared_ptr< endpoint_host > _host, endpoint_type _local, boost::asio::io_service &_io);
+ tcp_client_endpoint_impl(std::shared_ptr< endpoint_host > _host,
+ endpoint_type _local, boost::asio::io_service &_io);
virtual ~tcp_client_endpoint_impl();
void start();
- void send_queued();
+ void send_queued(buffer_ptr_t _buffer);
void join(const std::string &);
void leave(const std::string &);
diff --git a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp index a2cd635..587071a 100644 --- a/implementation/endpoints/include/tcp_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/tcp_server_endpoint_impl.hpp @@ -31,12 +31,7 @@ public: void start();
void stop();
- void restart();
- void receive();
-
- const uint8_t * get_buffer() const;
-
- void send_queued();
+ void send_queued(endpoint_type _target, std::shared_ptr< buffer_t > _data);
endpoint_type get_remote() const;
void join(const std::string &);
@@ -47,6 +42,12 @@ public: unsigned short get_port() const;
bool is_udp() const;
+ // dummies to implement endpoint_impl interface
+ // TODO: think about a better design!
+ void receive();
+ void restart();
+ const uint8_t * get_buffer() const;
+
private:
class connection
: public boost::enable_shared_from_this< connection > {
@@ -60,21 +61,20 @@ private: void start();
void stop();
- void send_queued();
- const uint8_t * get_buffer() const;
+ void send_queued(buffer_ptr_t _buffer);
private:
connection(tcp_server_endpoint_impl *_owner);
void send_magic_cookie();
tcp_server_endpoint_impl::socket_type socket_;
- buffer_type buffer_;
tcp_server_endpoint_impl *server_;
std::vector< byte_t > message_;
private:
- void receive_cbk(boost::system::error_code const &_error, std::size_t _bytes);
+ void receive_cbk(buffer_ptr_t _buffer,
+ boost::system::error_code const &_error, std::size_t _bytes);
};
boost::asio::ip::tcp::acceptor acceptor_;
diff --git a/implementation/endpoints/include/udp_client_endpoint_impl.hpp b/implementation/endpoints/include/udp_client_endpoint_impl.hpp index 4ca8762..e89035e 100644 --- a/implementation/endpoints/include/udp_client_endpoint_impl.hpp +++ b/implementation/endpoints/include/udp_client_endpoint_impl.hpp @@ -33,12 +33,12 @@ class udp_client_endpoint_impl : virtual public udp_client_endpoint_base_impl {
public:
- udp_client_endpoint_impl(
- std::shared_ptr< endpoint_host > _host, endpoint_type _remote, boost::asio::io_service &_io);
+ udp_client_endpoint_impl(std::shared_ptr< endpoint_host > _host,
+ endpoint_type _remote, boost::asio::io_service &_io);
virtual ~udp_client_endpoint_impl();
void start();
- void send_queued();
+ void send_queued(buffer_ptr_t _buffer);
void join(const std::string &_multicast_address);
void leave(const std::string &_multicast_address);
@@ -46,9 +46,6 @@ public: private:
void connect();
void receive();
-
-private:
- endpoint_type remote_;
};
} // namespace vsomeip
diff --git a/implementation/endpoints/include/udp_server_endpoint_impl.hpp b/implementation/endpoints/include/udp_server_endpoint_impl.hpp index b0e8fb9..17d9ed5 100644 --- a/implementation/endpoints/include/udp_server_endpoint_impl.hpp +++ b/implementation/endpoints/include/udp_server_endpoint_impl.hpp @@ -28,7 +28,8 @@ class udp_server_endpoint_impl : public udp_server_endpoint_base_impl {
public:
- udp_server_endpoint_impl(std::shared_ptr< endpoint_host > _host, endpoint_type _local, boost::asio::io_service &_io);
+ udp_server_endpoint_impl(std::shared_ptr< endpoint_host > _host,
+ endpoint_type _local, boost::asio::io_service &_io);
virtual ~udp_server_endpoint_impl();
void start();
@@ -39,7 +40,7 @@ public: const uint8_t * get_buffer() const;
- void send_queued();
+ void send_queued(endpoint_type _target, buffer_ptr_t _buffer);
endpoint_type get_remote() const;
void join(const std::string &_multicast_address);
@@ -51,10 +52,10 @@ public: bool is_udp() const;
public:
- void receive_cbk(boost::system::error_code const &_error, std::size_t _size);
+ void receive_cbk(buffer_ptr_t _buffer,
+ boost::system::error_code const &_error, std::size_t _size);
private:
- buffer_type buffer_;
socket_type socket_;
endpoint_type remote_;
diff --git a/implementation/endpoints/src/client_endpoint_impl.cpp b/implementation/endpoints/src/client_endpoint_impl.cpp index 5369bc6..2d5ad48 100644 --- a/implementation/endpoints/src/client_endpoint_impl.cpp +++ b/implementation/endpoints/src/client_endpoint_impl.cpp @@ -6,6 +6,7 @@ #include <chrono>
#include <iomanip>
+#include <sstream>
#include <boost/asio/buffer.hpp>
#include <boost/asio/ip/tcp.hpp>
@@ -32,6 +33,7 @@ client_endpoint_impl< Protocol, MaxBufferSize >::client_endpoint_impl( connect_timer_(_io),
flush_timer_(_io),
remote_(_remote),
+ packetizer_(std::make_shared< buffer_t >()),
connect_timeout_(VSOMEIP_DEFAULT_CONNECT_TIMEOUT), // TODO: use config variable
is_connected_(false) {
}
@@ -41,11 +43,6 @@ client_endpoint_impl< Protocol, MaxBufferSize >::~client_endpoint_impl() { }
template < typename Protocol, int MaxBufferSize >
-const uint8_t * client_endpoint_impl< Protocol, MaxBufferSize >::get_buffer() const {
- return buffer_.data();
-}
-
-template < typename Protocol, int MaxBufferSize >
bool client_endpoint_impl< Protocol, MaxBufferSize >::is_client() const {
return true;
}
@@ -66,24 +63,24 @@ 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_);
-
- bool is_queue_empty(packet_queue_.empty());
-
- if (packetizer_.size() + _size > MaxBufferSize) {
- packet_queue_.push_back(packetizer_);
- packetizer_.clear();
- if (is_queue_empty && is_connected_)
- send_queued();
+#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();
+#endif
+ if (packetizer_->size() + _size > MaxBufferSize) {
+ send_queued(packetizer_);
+ packetizer_ = std::make_shared< buffer_t >();
}
- packetizer_.insert(packetizer_.end(), _data, _data + _size);
+ packetizer_->insert(packetizer_->end(), _data, _data + _size);
if (_flush) {
flush_timer_.cancel();
- packet_queue_.push_back(packetizer_);
- packetizer_.clear();
- if (is_queue_empty && is_connected_)
- send_queued();
+ send_queued(packetizer_);
+ packetizer_ = std::make_shared< buffer_t >();
} else {
flush_timer_.expires_from_now(
std::chrono::milliseconds(VSOMEIP_DEFAULT_FLUSH_TIMEOUT)); // TODO: use config variable
@@ -103,10 +100,9 @@ template < typename Protocol, int MaxBufferSize > bool client_endpoint_impl< Protocol, MaxBufferSize >::flush() {
bool is_successful(true);
- if (!packetizer_.empty()) {
- packet_queue_.push_back(packetizer_);
- packetizer_.clear();
- send_queued();
+ if (!packetizer_->empty()) {
+ send_queued(packetizer_);
+ packetizer_ = std::make_shared< buffer_t >();
} else {
is_successful = false;
}
@@ -117,7 +113,6 @@ bool client_endpoint_impl< Protocol, MaxBufferSize >::flush() { template < typename Protocol, int MaxBufferSize >
void client_endpoint_impl< Protocol, MaxBufferSize >::connect_cbk(
boost::system::error_code const &_error) {
-
if (_error) {
socket_.close();
@@ -145,10 +140,8 @@ void client_endpoint_impl< Protocol, MaxBufferSize >::connect_cbk( if (!is_connected_) {
is_connected_ = true;
this->host_->on_connect(this->shared_from_this());
- if (!packet_queue_.empty()) {
- send_queued();
- }
}
+
receive();
}
}
@@ -156,7 +149,6 @@ void client_endpoint_impl< Protocol, MaxBufferSize >::connect_cbk( template < typename Protocol, int MaxBufferSize >
void client_endpoint_impl< Protocol, MaxBufferSize >::wait_connect_cbk(
boost::system::error_code const &_error) {
-
if (!_error) {
connect();
}
@@ -164,20 +156,19 @@ void client_endpoint_impl< Protocol, MaxBufferSize >::wait_connect_cbk( template < typename Protocol, int MaxBufferSize >
void client_endpoint_impl< Protocol, MaxBufferSize >::send_cbk(
+ buffer_ptr_t _buffer,
boost::system::error_code const &_error, std::size_t _bytes) {
-
- if (!_error && _bytes > 0) {
- packet_queue_.pop_front();
-
- if (!packet_queue_.empty()) {
- send_queued();
- }
- } else {
- if (_error == boost::asio::error::broken_pipe) {
- is_connected_ = false;
- socket_.close();
- connect();
- }
+#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();
+#endif
+ if (_error == boost::asio::error::broken_pipe) {
+ is_connected_ = false;
+ socket_.close();
+ connect();
}
}
@@ -191,17 +182,23 @@ void client_endpoint_impl< Protocol, MaxBufferSize >::flush_cbk( template < typename Protocol, int MaxBufferSize >
void client_endpoint_impl< Protocol, MaxBufferSize >::receive_cbk(
+ buffer_ptr_t _buffer,
boost::system::error_code const &_error, std::size_t _bytes) {
- static uint32_t message_counter = 0;
-
if (!_error && 0 < _bytes) {
- const uint8_t *buffer = get_buffer();
- message_.insert(message_.end(), buffer, buffer + _bytes);
+#if 0
+ std::stringstream msg;
+ msg << "cei::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();
+#endif
+ 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) {
this->host_->on_message(&message_[0], current_message_size, this);
diff --git a/implementation/endpoints/src/local_client_endpoint_impl.cpp b/implementation/endpoints/src/local_client_endpoint_impl.cpp index 64764c8..5b18316 100644 --- a/implementation/endpoints/src/local_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/local_client_endpoint_impl.cpp @@ -5,10 +5,12 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <iomanip>
+#include <sstream>
#include <boost/asio/write.hpp>
#include <vsomeip/defines.hpp>
+#include <vsomeip/logger.hpp>
#include "../include/endpoint_host.hpp"
#include "../include/local_client_endpoint_impl.hpp"
@@ -39,18 +41,29 @@ void local_client_endpoint_impl::connect() { }
void local_client_endpoint_impl::receive() {
+ std::shared_ptr< buffer_t > its_data
+ = std::make_shared< buffer_t >(VSOMEIP_MAX_LOCAL_MESSAGE_SIZE);
socket_.async_receive(
- boost::asio::buffer(buffer_),
+ boost::asio::buffer(*its_data),
std::bind(
&local_client_endpoint_impl::receive_cbk,
std::dynamic_pointer_cast< local_client_endpoint_impl >(shared_from_this()),
+ its_data,
std::placeholders::_1,
std::placeholders::_2
)
);
}
-void local_client_endpoint_impl::send_queued() {
+void local_client_endpoint_impl::send_queued(buffer_ptr_t _buffer) {
+#if 0
+ std::stringstream msg;
+ msg << "lce<" << this << ">::sq: ";
+ for (std::size_t i = 0; i < _data->size(); i++)
+ msg << std::setw(2) << std::setfill('0') << std::hex << (int)(*_buffer)[i] << " ";
+ msg << std::endl;
+#endif
+
static byte_t its_start_tag[] = { 0x67, 0x37, 0x6D, 0x07 };
static byte_t its_end_tag[] = { 0x07, 0x6D, 0x37, 0x67 };
@@ -68,22 +81,13 @@ void local_client_endpoint_impl::send_queued() { )
);
-#if 0
- std::cout << "lce(s): ";
- for (std::size_t i = 0; i < packet_queue_.front().size(); i++)
- std::cout << std::setw(2) << std::setfill('0') << std::hex << (int)packet_queue_.front()[i] << " ";
- std::cout << std::endl;
-#endif
-
boost::asio::async_write(
socket_,
- boost::asio::buffer(
- &packet_queue_.front()[0],
- packet_queue_.front().size()
- ),
+ boost::asio::buffer(*_buffer),
std::bind(
&client_endpoint_impl::send_cbk,
this->shared_from_this(),
+ _buffer,
std::placeholders::_1,
std::placeholders::_2
)
@@ -118,7 +122,9 @@ void local_client_endpoint_impl::send_tag_cbk( }
void local_client_endpoint_impl::receive_cbk(
+ buffer_ptr_t _buffer,
boost::system::error_code const &_error, std::size_t _bytes) {
+ VSOMEIP_ERROR << "Local endpoints must not receive messages!";
}
} // namespace vsomeip
diff --git a/implementation/endpoints/src/local_server_endpoint_impl.cpp b/implementation/endpoints/src/local_server_endpoint_impl.cpp index e0f25bc..f9fb4a2 100644 --- a/implementation/endpoints/src/local_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/local_server_endpoint_impl.cpp @@ -7,9 +7,12 @@ #include <deque>
#include <iomanip>
#include <iostream>
+#include <sstream>
#include <boost/asio/write.hpp>
+#include <vsomeip/logger.hpp>
+
#include "../include/endpoint_host.hpp"
#include "../include/local_server_endpoint_impl.hpp"
@@ -43,10 +46,10 @@ void local_server_endpoint_impl::stop() { }
-void local_server_endpoint_impl::send_queued() {
- auto connection_iterator = connections_.find(current_queue_->first);
+void local_server_endpoint_impl::send_queued(endpoint_type _target, std::shared_ptr< buffer_t > _data) {
+ auto connection_iterator = connections_.find(_target);
if (connection_iterator != connections_.end())
- connection_iterator->second->send_queued();
+ connection_iterator->second->send_queued(_data);
}
void local_server_endpoint_impl::receive() {
@@ -57,10 +60,6 @@ void local_server_endpoint_impl::restart() { current_->start();
}
-const uint8_t * local_server_endpoint_impl::get_buffer() const {
- return current_->get_buffer();
-}
-
local_server_endpoint_impl::endpoint_type local_server_endpoint_impl::get_remote() const {
return current_->get_socket().remote_endpoint();
}
@@ -87,14 +86,14 @@ void local_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();
+ socket_type &new_connection_socket = _connection->get_socket();
+ endpoint_type remote = new_connection_socket.remote_endpoint();
- connections_[remote] = _connection;
- _connection->start();
- }
+ connections_[remote] = _connection;
+ _connection->start();
+ }
- start();
+ start();
}
///////////////////////////////////////////////////////////////////////////////
@@ -113,35 +112,35 @@ local_server_endpoint_impl::socket_type & local_server_endpoint_impl::connection return socket_;
}
-const uint8_t * local_server_endpoint_impl::connection::get_buffer() const {
- return buffer_.data();
-}
-
void local_server_endpoint_impl::connection::start() {
+ buffer_ptr_t its_buffer = std::make_shared< buffer_t >(VSOMEIP_MAX_LOCAL_MESSAGE_SIZE);
socket_.async_receive(
- boost::asio::buffer(buffer_),
+ boost::asio::buffer(*its_buffer),
std::bind(
&local_server_endpoint_impl::connection::receive_cbk,
shared_from_this(),
+ its_buffer,
std::placeholders::_1,
std::placeholders::_2
)
);
}
-void local_server_endpoint_impl::connection::send_queued() {
- std::deque<std::vector<uint8_t>> ¤t_queue
- = server_->current_queue_->second;
-
+void local_server_endpoint_impl::connection::send_queued(buffer_ptr_t _buffer) {
+#if 0
+ std::stringstream msg;
+ msg << "lse::sq: ";
+ for (std::size_t i = 0; i < _buffer->size(); i++)
+ msg << std::setw(2) << std::setfill('0') << std::hex << (int)(*_buffer)[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
+#endif
boost::asio::async_write(
socket_,
- boost::asio::buffer(
- ¤t_queue.front()[0],
- current_queue.front().size()
- ),
+ boost::asio::buffer(*_buffer),
std::bind(
&local_server_endpoint_base_impl::send_cbk,
server_->shared_from_this(),
+ _buffer,
std::placeholders::_1,
std::placeholders::_2
)
@@ -152,22 +151,23 @@ void local_server_endpoint_impl::connection::send_magic_cookie() { }
void local_server_endpoint_impl::connection::receive_cbk(
+ buffer_ptr_t _buffer,
boost::system::error_code const &_error, std::size_t _bytes) {
static std::size_t its_start = -1;
std::size_t its_end;
if (!_error && 0 < _bytes) {
- const uint8_t *buffer = get_buffer();
- message_.insert(message_.end(), buffer, buffer + _bytes);
-
#if 0
- std::cout << "lse(r): ";
+ std::stringstream msg;
+ msg << "lse::c<" << this << ">rcb: ";
for (std::size_t i = 0; i < _bytes; i++)
- std::cout << std::setw(2) << std::setfill('0') << std::hex << (int)get_buffer()[i] << " ";
- std::cout << std::endl;
+ msg << std::setw(2) << std::setfill('0') << std::hex << (int)(*_buffer)[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
#endif
+ message_.insert(message_.end(), _buffer->begin(), _buffer->begin() + _bytes);
+
do {
if (its_start == -1) {
its_start = 0;
diff --git a/implementation/endpoints/src/server_endpoint_impl.cpp b/implementation/endpoints/src/server_endpoint_impl.cpp index c26180b..f41c0ec 100644 --- a/implementation/endpoints/src/server_endpoint_impl.cpp +++ b/implementation/endpoints/src/server_endpoint_impl.cpp @@ -4,12 +4,16 @@ // 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 <sstream>
+
#include <boost/asio/buffer.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <boost/asio/ip/udp.hpp>
#include <boost/asio/local/stream_protocol.hpp>
#include <vsomeip/defines.hpp>
+#include <vsomeip/logger.hpp>
#include "../include/server_endpoint_impl.hpp"
#include "../../configuration/include/internal.hpp"
@@ -20,7 +24,6 @@ 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),
- current_queue_(packet_queues_.end()),
flush_timer_(_io) {
}
@@ -32,61 +35,64 @@ bool server_endpoint_impl< Protocol, MaxBufferSize >::is_client() const { 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();
+#endif
bool is_sent(false);
- if (VSOMEIP_CLIENT_POS_MAX < _size) {
+ if (VSOMEIP_SESSION_POS_MAX < _size) {
std::unique_lock< std::mutex > its_lock(mutex_);
client_t its_client;
std::memcpy(&its_client, &_data[VSOMEIP_CLIENT_POS_MIN], sizeof(client_t));
-
- auto found_target = clients_.find(its_client);
- if (found_target != clients_.end()) {
- bool is_queue_empty(packet_queues_.empty());
-
- endpoint_type its_target = found_target->second;
-
- // find queue and packetizer (buffer)
- std::deque< std::vector< uint8_t > >& target_packet_queue
- = packet_queues_[its_target];
- std::vector< uint8_t >& target_packetizer
- = packetizer_[its_target];
-
- // if the current_queue is not yet set, set it to newly created one
- if (current_queue_ == packet_queues_.end())
- current_queue_ = packet_queues_.find(its_target);
-
- if (target_packetizer.size() + _size > MaxBufferSize) {
- target_packet_queue.push_back(target_packetizer);
- target_packetizer.clear();
-
- if (is_queue_empty)
- send_queued();
+ 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()) {
+ endpoint_type its_target = found_session->second;
+
+ // find queue and packetizer (buffer)
+ std::shared_ptr< buffer_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< 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< 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< 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
+ )
+ );
+ }
+ is_sent = true;
}
-
- target_packetizer.insert(target_packetizer.end(), _data, _data + _size);
-
- if (_flush) {
- flush_timer_.cancel();
-
- target_packet_queue.push_back(target_packetizer);
- target_packetizer.clear();
-
- if (is_queue_empty)
- send_queued();
- } 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
- )
- );
- }
- is_sent = true;
}
}
@@ -94,73 +100,42 @@ bool server_endpoint_impl< Protocol, MaxBufferSize >::send( }
template < typename Protocol, int MaxBufferSize >
-bool server_endpoint_impl< Protocol, MaxBufferSize >::flush() {
+bool server_endpoint_impl< Protocol, MaxBufferSize >::flush(endpoint_type _target) {
bool is_flushed = false;
-#if 0
+ std::unique_lock< std::mutex > its_lock(mutex_);
auto i = packetizer_.find(_target);
- if (i != packetizer_.end() && !i->second.empty()) {
- std::deque< std::vector< uint8_t > >& target_packet_queue
- = packet_queues_[i->first];
- target_packet_queue.push_back(i->second);
- i->second.clear();
-
- flushed = true;
+ if (i != packetizer_.end() && !i->second->empty()) {
+ send_queued(_target, i->second);
+ i->second = std::make_shared< buffer_t >();
+ is_flushed = true;
}
- if (is_successful)
- send_queued();
-#endif
return is_flushed;
}
template < typename Protocol, int MaxBufferSize >
-bool server_endpoint_impl< Protocol, MaxBufferSize >::set_next_queue() {
- if (current_queue_->second.empty())
- current_queue_ = packet_queues_.erase(current_queue_);
-
- if (packet_queues_.empty())
- return false;
-
- if (current_queue_ == packet_queues_.end())
- current_queue_ = packet_queues_.begin();
-
- if (!current_queue_->second.empty())
- return true;
-
- auto saved_current_queue = current_queue_;
- do {
- current_queue_++;
- if (current_queue_ == packet_queues_.end())
- current_queue_ = packet_queues_.begin();
- } while (current_queue_->second.empty() &&
- current_queue_ != saved_current_queue);
-
- return !current_queue_->second.empty();
-}
-
-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(
+ buffer_ptr_t _buffer,
boost::system::error_code const &_error, std::size_t _bytes) {
-
- if (!_error) {
- current_queue_->second.pop_front();
- bool is_message_available(set_next_queue());
- if (is_message_available) {
- send_queued();
- }
- }
+#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();
+#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);
+ (void)flush(_target);
}
}
@@ -170,4 +145,3 @@ template class server_endpoint_impl< boost::asio::ip::tcp, VSOMEIP_MAX_TCP_MESSA template class server_endpoint_impl< boost::asio::ip::udp, VSOMEIP_MAX_UDP_MESSAGE_SIZE >;
} // namespace vsomeip
-
diff --git a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp index e30abb4..b65de32 100644 --- a/implementation/endpoints/src/tcp_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/tcp_client_endpoint_impl.cpp @@ -24,14 +24,6 @@ tcp_client_endpoint_impl::tcp_client_endpoint_impl( tcp_client_endpoint_impl::~tcp_client_endpoint_impl() {
}
-//const endpoint * tcp_client_impl::get_local_endpoint() const {
-// return vsomeip::factory::get_instance()->get_endpoint(
-// socket_.local_endpoint().address().to_string(),
-// socket_.local_endpoint().port(),
-// ip_protocol::TCP
-// );
-//}
-
void tcp_client_endpoint_impl::start() {
connect();
}
@@ -54,30 +46,30 @@ void tcp_client_endpoint_impl::connect() { }
void tcp_client_endpoint_impl::receive() {
+ std::shared_ptr< buffer_t > its_data
+ = std::make_shared< buffer_t >(VSOMEIP_MAX_TCP_MESSAGE_SIZE);
socket_.async_receive(
- boost::asio::buffer(buffer_),
+ boost::asio::buffer(*its_data),
std::bind(
&tcp_client_endpoint_base_impl::receive_cbk,
shared_from_this(),
+ its_data,
std::placeholders::_1,
std::placeholders::_2
)
);
}
-void tcp_client_endpoint_impl::send_queued() {
+void tcp_client_endpoint_impl::send_queued(buffer_ptr_t _buffer) {
if (has_enabled_magic_cookies_)
send_magic_cookie();
-
boost::asio::async_write(
socket_,
- boost::asio::buffer(
- &packet_queue_.front()[0],
- packet_queue_.front().size()
- ),
+ boost::asio::buffer(*_buffer),
std::bind(
&tcp_client_endpoint_base_impl::send_cbk,
shared_from_this(),
+ _buffer,
std::placeholders::_1,
std::placeholders::_2
)
@@ -89,7 +81,7 @@ void tcp_client_endpoint_impl::send_magic_cookie() { 0x00, 0x00, 0x00, 0x08,
0xDE, 0xAD, 0xBE, 0xEF,
0x01, 0x01, 0x01, 0x00 };
-
+/*
std::vector<uint8_t>& current_packet = packet_queue_.front();
if (VSOMEIP_MAX_TCP_MESSAGE_SIZE - current_packet.size() >=
@@ -101,7 +93,7 @@ void tcp_client_endpoint_impl::send_magic_cookie() { );
} else {
VSOMEIP_WARNING << "Packet full. Cannot insert magic cookie!";
- }
+ } */
}
void tcp_client_endpoint_impl::join(const std::string &) {
diff --git a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp index f095c75..68f63f1 100644 --- a/implementation/endpoints/src/tcp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/tcp_server_endpoint_impl.cpp @@ -5,9 +5,12 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <deque>
+#include <iomanip>
#include <boost/asio/write.hpp>
+#include <vsomeip/logger.hpp>
+
#include "../include/endpoint_host.hpp"
#include "../include/tcp_server_endpoint_impl.hpp"
#include "../../utility/include/utility.hpp"
@@ -19,7 +22,7 @@ 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) {
+ acceptor_(_io, _local), current_(0) {
is_supporting_magic_cookies_ = true;
}
@@ -46,22 +49,10 @@ void tcp_server_endpoint_impl::stop() { acceptor_.close();
}
-void tcp_server_endpoint_impl::receive() {
- // intentionally left empty
-}
-
-void tcp_server_endpoint_impl::restart() {
- current_->start();
-}
-
-const uint8_t * tcp_server_endpoint_impl::get_buffer() const {
- return current_->get_buffer();
-}
-
-void tcp_server_endpoint_impl::send_queued() {
- auto connection_iterator = connections_.find(current_queue_->first);
+void tcp_server_endpoint_impl::send_queued(endpoint_type _target, std::shared_ptr< buffer_t > _data) {
+ auto connection_iterator = connections_.find(_target);
if (connection_iterator != connections_.end())
- connection_iterator->second->send_queued();
+ connection_iterator->second->send_queued(_data);
}
tcp_server_endpoint_impl::endpoint_type tcp_server_endpoint_impl::get_remote() const {
@@ -130,16 +121,14 @@ tcp_server_endpoint_impl::socket_type & tcp_server_endpoint_impl::connection::ge return socket_;
}
-const uint8_t * tcp_server_endpoint_impl::connection::get_buffer() const {
- return buffer_.data();
-}
-
void tcp_server_endpoint_impl::connection::start() {
+ buffer_ptr_t its_buffer = std::make_shared< buffer_t >(VSOMEIP_MAX_TCP_MESSAGE_SIZE);
socket_.async_receive(
- boost::asio::buffer(buffer_),
+ 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
)
@@ -150,22 +139,17 @@ void tcp_server_endpoint_impl::connection::stop() { socket_.close();
}
-void tcp_server_endpoint_impl::connection::send_queued() {
+void tcp_server_endpoint_impl::connection::send_queued(buffer_ptr_t _buffer) {
if (server_->has_enabled_magic_cookies_)
send_magic_cookie();
- std::deque<std::vector<uint8_t>> ¤t_queue
- = server_->current_queue_->second;
-
boost::asio::async_write(
socket_,
- boost::asio::buffer(
- ¤t_queue.front()[0],
- current_queue.front().size()
- ),
+ boost::asio::buffer(*_buffer),
std::bind(
&tcp_server_endpoint_base_impl::send_cbk,
server_->shared_from_this(),
+ _buffer,
std::placeholders::_1,
std::placeholders::_2
)
@@ -177,7 +161,7 @@ void tcp_server_endpoint_impl::connection::send_magic_cookie() { 0x00, 0x00, 0x00, 0x08,
0xDE, 0xAD, 0xBE, 0xEF,
0x01, 0x01, 0x02, 0x00 };
-
+/*
std::vector<uint8_t>& current_packet
= server_->current_queue_->second.front();
@@ -188,14 +172,19 @@ void tcp_server_endpoint_impl::connection::send_magic_cookie() { data,
data + sizeof(data)
);
- }
+ } */
}
void tcp_server_endpoint_impl::connection::receive_cbk(
+ buffer_ptr_t _buffer,
boost::system::error_code const &_error, std::size_t _bytes) {
if (!_error && 0 < _bytes) {
- const uint8_t *buffer = get_buffer();
- message_.insert(message_.end(), buffer, buffer + _bytes);
+#if 0
+ for (std::size_t i = 0; i < _bytes; ++i)
+ std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)_buffer[i] << " ";
+ std::cout << std::endl;
+#endif
+ message_.insert(message_.end(), _buffer->begin(), _buffer->begin() + _bytes);
bool has_full_message;
do {
@@ -205,7 +194,9 @@ void tcp_server_endpoint_impl::connection::receive_cbk( 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));
- server_->clients_[its_client] = socket_.remote_endpoint();
+ 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_);
@@ -213,10 +204,17 @@ void tcp_server_endpoint_impl::connection::receive_cbk( }
} while (has_full_message);
- server_->restart();
- } else {
- server_->receive();
+ start();
}
}
+// Dummies
+void tcp_server_endpoint_impl::receive() {
+ // intentionally left empty
+}
+
+void tcp_server_endpoint_impl::restart() {
+ // intentionally left empty
+}
+
} // namespace vsomeip
diff --git a/implementation/endpoints/src/udp_client_endpoint_impl.cpp b/implementation/endpoints/src/udp_client_endpoint_impl.cpp index 0c882c6..d95c59d 100644 --- a/implementation/endpoints/src/udp_client_endpoint_impl.cpp +++ b/implementation/endpoints/src/udp_client_endpoint_impl.cpp @@ -4,6 +4,9 @@ // 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 <sstream>
+
#include <boost/asio/ip/multicast.hpp>
#include <vsomeip/logger.hpp>
@@ -20,14 +23,6 @@ udp_client_endpoint_impl::udp_client_endpoint_impl( udp_client_endpoint_impl::~udp_client_endpoint_impl() {
}
-//const endpoint * udp_client_endpoint_impl::get_local_endpoint() const {
-// return vsomeip::factory::get_instance()->get_endpoint(
-// socket_.local_endpoint().address().to_string(),
-// socket_.local_endpoint().port(),
-// ip_protocol::UDP
-// );
-//}
-
void udp_client_endpoint_impl::connect() {
socket_.async_connect(
remote_,
@@ -40,34 +35,41 @@ void udp_client_endpoint_impl::connect() { }
void udp_client_endpoint_impl::start() {
- socket_.open(remote_.protocol());
+ socket_.open(boost::asio::ip::udp::v4());
connect();
receive();
}
-void udp_client_endpoint_impl::send_queued() {
- VSOMEIP_DEBUG << "UDP CLIENT SENDING";
+void udp_client_endpoint_impl::send_queued(buffer_ptr_t _buffer) {
+#if 0
+ std::stringstream msg;
+ msg << "ucei<" << this << ">::sq: ";
+ 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
socket_.async_send(
- boost::asio::buffer(
- &packet_queue_.front()[0],
- packet_queue_.front().size()
- ),
+ boost::asio::buffer(*_buffer),
std::bind(
&udp_client_endpoint_base_impl::send_cbk,
shared_from_this(),
+ _buffer,
std::placeholders::_1,
std::placeholders::_2
)
);
+ receive();
}
void udp_client_endpoint_impl::receive() {
+ buffer_ptr_t its_buffer = std::make_shared< buffer_t >(VSOMEIP_MAX_UDP_MESSAGE_SIZE);
socket_.async_receive_from(
- boost::asio::buffer(buffer_),
+ boost::asio::buffer(*its_buffer),
remote_,
std::bind(
&udp_client_endpoint_base_impl::receive_cbk,
shared_from_this(),
+ its_buffer,
std::placeholders::_1,
std::placeholders::_2
)
diff --git a/implementation/endpoints/src/udp_server_endpoint_impl.cpp b/implementation/endpoints/src/udp_server_endpoint_impl.cpp index a1ef866..806f435 100644 --- a/implementation/endpoints/src/udp_server_endpoint_impl.cpp +++ b/implementation/endpoints/src/udp_server_endpoint_impl.cpp @@ -5,10 +5,13 @@ // file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <iomanip>
+#include <sstream>
#include <boost/asio/ip/address.hpp>
#include <boost/asio/ip/multicast.hpp>
+#include <vsomeip/logger.hpp>
+
#include "../include/endpoint_host.hpp"
#include "../include/udp_server_endpoint_impl.hpp"
#include "../../message/include/byteorder.hpp"
@@ -22,7 +25,6 @@ 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) {
-
boost::asio::socket_base::broadcast option(true);
socket_.set_option(option);
}
@@ -38,12 +40,14 @@ void udp_server_endpoint_impl::stop() { }
void udp_server_endpoint_impl::receive() {
+ buffer_ptr_t its_buffer = std::make_shared< buffer_t >(VSOMEIP_MAX_UDP_MESSAGE_SIZE);
socket_.async_receive_from(
- boost::asio::buffer(buffer_),
+ boost::asio::buffer(*its_buffer),
remote_,
std::bind(
&udp_server_endpoint_impl::receive_cbk,
std::dynamic_pointer_cast< udp_server_endpoint_impl >(shared_from_this()),
+ its_buffer,
std::placeholders::_1,
std::placeholders::_2
)
@@ -54,20 +58,21 @@ void udp_server_endpoint_impl::restart() { receive();
}
-const uint8_t * udp_server_endpoint_impl::get_buffer() const {
- return buffer_.data();
-}
-
-void udp_server_endpoint_impl::send_queued() {
+void udp_server_endpoint_impl::send_queued(endpoint_type _target, std::shared_ptr< buffer_t > _data) {
+#if 0
+ std::stringstream msg;
+ msg << "usei::sq: ";
+ for (std::size_t i = 0; i < _data->size(); ++i)
+ msg << std::hex << std::setw(2) << std::setfill('0') << (int)(*_data)[i] << " ";
+ VSOMEIP_DEBUG << msg.str();
+#endif
socket_.async_send_to(
- boost::asio::buffer(
- ¤t_queue_->second.front()[0],
- current_queue_->second.front().size()
- ),
- current_queue_->first,
+ boost::asio::buffer(*_data),
+ _target,
std::bind(
&udp_server_endpoint_base_impl::send_cbk,
shared_from_this(),
+ _data,
std::placeholders::_1,
std::placeholders::_2
)
@@ -135,15 +140,18 @@ bool udp_server_endpoint_impl::is_udp() const { }
// 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) {
-#if 1
- for (std::size_t i = 0; i < _bytes; ++i)
- std::cout << std::setw(2) << std::setfill('0') << (int)get_buffer()[i] << " ";
- std::cout << std::endl;
+void udp_server_endpoint_impl::receive_cbk(
+ buffer_ptr_t _buffer,
+ boost::system::error_code const &_error, std::size_t _bytes) {
+#if 0
+ std::stringstream msg;
+ msg << "usei::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();
#endif
- const uint8_t *buffer = get_buffer();
- message_.insert(message_.end(), buffer, buffer + _bytes);
+ if (!_error && 0 < _bytes) {
+ message_.insert(message_.end(), _buffer->begin(), _buffer->begin() + _bytes);
bool has_full_message;
do {
@@ -153,7 +161,9 @@ void udp_server_endpoint_impl::receive_cbk(boost::system::error_code const &_err 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));
- clients_[its_client] = remote_;
+ session_t its_session;
+ std::memcpy(&its_session, &message_[VSOMEIP_SESSION_POS_MIN], sizeof(session_t));
+ clients_[its_client][its_session] = remote_;
}
this->host_->on_message(&message_[0], current_message_size, this);
diff --git a/implementation/examples/client-sample.cpp b/implementation/examples/client-sample.cpp deleted file mode 100644 index 9d43f1f..0000000 --- a/implementation/examples/client-sample.cpp +++ /dev/null @@ -1,102 +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 <chrono> -#include <iomanip> -#include <iostream> -#include <thread> - -#include <vsomeip/vsomeip.hpp> - -#include "sample-ids.hpp" - -class client_sample { -public: - client_sample() - : app_(vsomeip::runtime::get()->create_application()), - request_(vsomeip::runtime::get()->create_request()) { - } - - void init() { - app_->init(); - 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_->offer_service(OTHER_SAMPLE_SERVICE_ID, OTHER_SAMPLE_INSTANCE_ID); - app_->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID); - app_->register_message_handler( - vsomeip::VSOMEIP_ANY_SERVICE, SAMPLE_INSTANCE_ID, vsomeip::VSOMEIP_ANY_METHOD, - std::bind(&client_sample::on_message, - this, - std::placeholders::_1)); - - request_->set_service(SAMPLE_SERVICE_ID); - request_->set_instance(SAMPLE_INSTANCE_ID); - request_->set_method(SAMPLE_METHOD_ID); - - 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 < 10; ++i) its_payload_data.push_back(i % 256); - its_payload->set_data(its_payload_data); - request_->set_payload(its_payload); - } - - 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 (SAMPLE_SERVICE_ID == _service && SAMPLE_INSTANCE_ID == _instance) { - send(); - } - } - - void on_message(std::shared_ptr< vsomeip::message > &_response) { - VSOMEIP_INFO << "Received a response from Service [" - << std::setw(4) << std::setfill('0') << std::hex << _response->get_service() - << "." - << std::setw(4) << std::setfill('0') << std::hex << _response->get_instance() - << "] to Client/Session [" - << std::setw(4) << std::setfill('0') << std::hex << _response->get_client() - << "/" - << std::setw(4) << std::setfill('0') << std::hex << _response->get_session() - << "]"; - - send(); - } - - void send() { - app_->send(request_); - VSOMEIP_INFO << "Client/Session [" - << std::setw(4) << std::setfill('0') << std::hex << request_->get_client() - << "/" - << std::setw(4) << std::setfill('0') << std::hex << request_->get_session() - << "] sent a request to Service [" - << std::setw(4) << std::setfill('0') << std::hex << request_->get_service() - << "." - << std::setw(4) << std::setfill('0') << std::hex << request_->get_instance() - << "]"; - } - -private: - std::shared_ptr< vsomeip::application > app_; - std::shared_ptr< vsomeip::message > request_; -}; - - -int main(int argc, char **argv) { - client_sample its_sample; - its_sample.init(); - its_sample.start(); - return 0; -} diff --git a/implementation/message/src/deserializer.cpp b/implementation/message/src/deserializer.cpp index ebd2793..c6d3b70 100644 --- a/implementation/message/src/deserializer.cpp +++ b/implementation/message/src/deserializer.cpp @@ -183,7 +183,7 @@ void deserializer::reset() { remaining_ = data_.size();
}
-#ifdef VSOMEIP_DEBUG
+#ifdef VSOMEIP_DEBUG_
void deserializer::show_data() const {
std::cout << "("
<< std::hex << std::setw(2) << std::setfill('0') << (int)*position_ << ", "
diff --git a/implementation/routing/include/routing_manager_host.hpp b/implementation/routing/include/routing_manager_host.hpp index 5e5d6ff..58a8ce9 100644 --- a/implementation/routing/include/routing_manager_host.hpp +++ b/implementation/routing/include/routing_manager_host.hpp @@ -11,6 +11,8 @@ #include <boost/asio/io_service.hpp> +#include <vsomeip/error.hpp> + namespace vsomeip { class configuration; @@ -28,7 +30,7 @@ public: virtual void on_availability(service_t _service, instance_t _instance, bool _is_available) const = 0; virtual void on_event(event_type_e _event) = 0; virtual void on_message(std::shared_ptr< message > _message) = 0; - virtual void on_error() = 0; + virtual void on_error(error_code_e _error) = 0; }; } // namespace vsomeip diff --git a/implementation/routing/include/routing_manager_impl.hpp b/implementation/routing/include/routing_manager_impl.hpp index f947c97..f6637d6 100644 --- a/implementation/routing/include/routing_manager_impl.hpp +++ b/implementation/routing/include/routing_manager_impl.hpp @@ -124,7 +124,7 @@ public: uint16_t _port, const std::string &_protocol); private: - void on_message(const byte_t *_data, length_t _length, instance_t _instance); + void 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); diff --git a/implementation/routing/include/routing_manager_stub.hpp b/implementation/routing/include/routing_manager_stub.hpp index 83bd1e9..134797f 100644 --- a/implementation/routing/include/routing_manager_stub.hpp +++ b/implementation/routing/include/routing_manager_stub.hpp @@ -36,13 +36,14 @@ public: void on_disconnect(std::shared_ptr< endpoint > _endpoint); void on_message(const byte_t *_data, const length_t _length, endpoint *_receiver); + void on_offer_service(client_t _client, service_t _service, instance_t _instance); + private: void broadcast(std::vector< byte_t > &_command) const; void on_register_application(client_t _client); void on_deregister_application(client_t _client); - void on_offer_service(client_t _client, service_t _service, instance_t _instance); void on_stop_offer_service(client_t _client, service_t _service, instance_t _instance); void broadcast_routing_info(); diff --git a/implementation/routing/src/routing_manager_impl.cpp b/implementation/routing/src/routing_manager_impl.cpp index 3c49294..7c333b2 100644 --- a/implementation/routing/src/routing_manager_impl.cpp +++ b/implementation/routing/src/routing_manager_impl.cpp @@ -6,6 +6,7 @@ #include <iomanip> #include <memory> +#include <sstream> #include <vsomeip/configuration.hpp> #include <vsomeip/constants.hpp> @@ -57,12 +58,6 @@ void routing_manager_impl::init() { its_max_message_size = VSOMEIP_MAX_UDP_MESSAGE_SIZE; serializer_->create_data(its_max_message_size); - if (!configuration_->is_service_discovery_enabled()) { - for (auto s : configuration_->get_remote_services()) { - VSOMEIP_DEBUG << "Remote service loaded [" - << std::hex << s.first << "." << s.second << "]"; - } - } // TODO: Only instantiate the stub if needed stub_ = std::make_shared< routing_manager_stub >(this); @@ -103,9 +98,9 @@ void routing_manager_impl::stop() { void routing_manager_impl::offer_service(client_t _client, service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor, ttl_t _ttl) { -#if 1 - std::cout << "RM: Client [ " << std::hex << _client << "] offers service [" - << std::hex << _service << "." << _instance << "]" << std::endl; +#if 0 + VSOMEIP_DEBUG << "RM: Client [ " << std::hex << _client << "] offers service [" + << std::hex << _service << "." << _instance << "]"; #endif // Local route local_services_[_service][_instance] = _client; @@ -116,7 +111,7 @@ void routing_manager_impl::offer_service(client_t _client, if (its_info->get_major() == _major && its_info->get_minor() == _minor) { its_info->set_ttl(_ttl); } else { - host_->on_error(); + host_->on_error(error_code_e::SERVICE_PROPERTY_MISMATCH); } } else { create_service(_service, _instance, _major, _minor, _ttl); @@ -186,7 +181,7 @@ void routing_manager_impl::request_service(client_t _client, if ((_major > its_info->get_major()) || (_major == its_info->get_major() && _minor > its_info->get_minor()) || (_ttl > its_info->get_ttl())) { - host_->on_error(); // TODO: Service locally available, but not with the specified properties + host_->on_error(error_code_e::SERVICE_PROPERTY_MISMATCH); } else { its_info->add_client(_client); } @@ -231,15 +226,7 @@ void routing_manager_impl::send(client_t _client, 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]); bool is_request = utility::is_request(_data[VSOMEIP_MESSAGE_TYPE_POS]); -#if 1 - std::cout << "Message [" - << std::hex << its_service << "." << _instance - << "] " - << (is_request ? "from " : "to ") - << "client [" - << std::hex << its_client - << "]" << std::endl; -#endif + if (_size > VSOMEIP_MESSAGE_TYPE_POS) { if (is_request) { its_target = find_local(its_service, _instance); @@ -262,7 +249,7 @@ void routing_manager_impl::send(client_t _client, // 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)) { - on_message(_data, _size, _instance); + deliver_message(_data, _size, _instance); } else { if (is_request) { its_target = find_remote_client(its_service, _instance, _reliable); @@ -272,7 +259,21 @@ void routing_manager_impl::send(client_t _client, VSOMEIP_ERROR << "Routing error. Client from remote service could not be found!"; } } else { - VSOMEIP_ERROR << "Routing error. Routing to remote clients not yet implemented!"; + serviceinfo *its_info = find_service(its_service, _instance); + if (its_info) { + if (_reliable) { + its_target = its_info->get_reliable_endpoint(); + } else { + its_target = its_info->get_unreliable_endpoint(); + } + if (its_target) { + 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!"; + } } } } @@ -285,11 +286,33 @@ void routing_manager_impl::set(client_t its_client, } void routing_manager_impl::on_message(const byte_t *_data, length_t _size, endpoint *_receiver) { +#if 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(); +#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]); instance_t its_instance = find_instance(its_service, _receiver); if (its_instance != VSOMEIP_ANY_INSTANCE) { - on_message(_data, _size, its_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!"; } } else { //send_error(); // TODO: send error "malformed message" @@ -328,14 +351,7 @@ void routing_manager_impl::on_disconnect(std::shared_ptr< endpoint > _endpoint) } } -void routing_manager_impl::on_message(const byte_t *_data, length_t _size, instance_t _instance) { -#if 0 - std::cout << "rmi::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; -#endif - +void routing_manager_impl::deliver_message(const byte_t *_data, length_t _size, instance_t _instance) { deserializer_->set_data(_data, _size); std::shared_ptr< message > its_message(deserializer_->deserialize_message()); if (its_message) { @@ -420,7 +436,6 @@ serviceinfo * routing_manager_impl::find_service( void routing_manager_impl::create_service( service_t _service, instance_t _instance, major_version_t _major, minor_version_t _minor, ttl_t _ttl) { - if (configuration_) { std::shared_ptr< serviceinfo > its_info(std::make_shared< serviceinfo >(_major, _minor, _ttl)); @@ -453,10 +468,10 @@ void routing_manager_impl::create_service( 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!" + host_->on_error(error_code_e::PORT_CONFIGURATION_MISSING); } } else { - host_->on_error(); // TODO: Define configuration error! + host_->on_error(error_code_e::CONFIGURATION_MISSING); } } @@ -484,7 +499,7 @@ std::shared_ptr< endpoint > routing_manager_impl::create_client_endpoint( its_endpoint->start(); } catch (std::exception &e) { - host_->on_error(); // Define error for "Server endpoint could not be created. Reason: ... + host_->on_error(error_code_e::CLIENT_ENDPOINT_CREATION_FAILED); } return its_endpoint; @@ -538,7 +553,7 @@ std::shared_ptr< endpoint > routing_manager_impl::create_server_endpoint(uint16_ its_endpoint->start(); } catch (std::exception &e) { - host_->on_error(); // Define error for "Server endpoint could not be created. Reason: ... + host_->on_error(error_code_e::SERVER_ENDPOINT_CREATION_FAILED); } return its_endpoint; @@ -652,23 +667,34 @@ std::shared_ptr< endpoint > routing_manager_impl::find_remote_client( void routing_manager_impl::init_routing_info() { VSOMEIP_INFO << "Service Discovery disabled. Using static routing information."; for (auto i : configuration_->get_remote_services()) { + std::shared_ptr< serviceinfo > its_info(std::make_shared< serviceinfo >( + VSOMEIP_DEFAULT_MAJOR, VSOMEIP_DEFAULT_MINOR, VSOMEIP_DEFAULT_TTL)); + std::string its_address = configuration_->get_address(i.first, i.second); uint16_t its_reliable_port = configuration_->get_reliable_port(i.first, i.second); uint16_t its_unreliable_port = configuration_->get_unreliable_port(i.first, i.second); if (VSOMEIP_INVALID_PORT != its_reliable_port) { - VSOMEIP_DEBUG << "Configuring [" << std::hex << i.first << "." << i.second - << "] --> (TCP:" << its_address << ":" << std::dec << its_reliable_port << ")"; - remote_services_[i.first][i.second][true] = create_client_endpoint(its_address, its_reliable_port, true); + VSOMEIP_DEBUG << "Routing info: [" << std::hex << i.first << "." << i.second + << "] -> TCP:" << its_address << ":" << std::dec << its_reliable_port; + std::shared_ptr< endpoint > its_endpoint(create_client_endpoint(its_address, its_reliable_port, true)); + remote_services_[i.first][i.second][true] = its_endpoint; + service_instances_[i.first][its_endpoint.get()] = i.second; + its_info->set_reliable_endpoint(its_endpoint); } if (VSOMEIP_INVALID_PORT != its_unreliable_port) { - VSOMEIP_DEBUG << "Configuring [" << std::hex << i.first << "." << i.second - << "] --> (UDP:" << its_address << ":" << std::dec << its_unreliable_port << ")"; - remote_services_[i.first][i.second][false] = create_client_endpoint(its_address, its_unreliable_port, false); + VSOMEIP_DEBUG << "Routing info: [" << std::hex << i.first << "." << i.second + << "] --> UDP:" << its_address << ":" << std::dec << its_unreliable_port; + std::shared_ptr< endpoint > its_endpoint(create_client_endpoint(its_address, its_unreliable_port, false)); + remote_services_[i.first][i.second][false] = its_endpoint; + service_instances_[i.first][its_endpoint.get()] = i.second; + its_info->set_reliable_endpoint(its_endpoint); } if (VSOMEIP_INVALID_PORT != its_reliable_port || VSOMEIP_INVALID_PORT != its_unreliable_port) { + services_[i.first][i.second] = its_info; + stub_->on_offer_service(VSOMEIP_ROUTING_CLIENT, i.first, i.second); host_->on_availability(i.first, i.second, true); } } diff --git a/implementation/routing/src/routing_manager_proxy.cpp b/implementation/routing/src/routing_manager_proxy.cpp index 601f6bf..2092c0d 100644 --- a/implementation/routing/src/routing_manager_proxy.cpp +++ b/implementation/routing/src/routing_manager_proxy.cpp @@ -51,11 +51,8 @@ void routing_manager_proxy::init() { serializer_->create_data(its_max_message_size); - std::string its_sender_path(VSOMEIP_BASE_PATH + VSOMEIP_ROUTING_ENDPOINT); - sender_ = std::make_shared< local_client_endpoint_impl >( - shared_from_this(), - boost::asio::local::stream_protocol::endpoint(its_sender_path), - io_); + std::stringstream its_sender_path; + sender_ = create_local(VSOMEIP_ROUTING_CLIENT); std::stringstream its_client; its_client << VSOMEIP_BASE_PATH << std::hex << client_; @@ -66,7 +63,6 @@ void routing_manager_proxy::init() { boost::asio::local::stream_protocol::endpoint(its_client.str()), io_); - VSOMEIP_DEBUG << "Routing to " << its_sender_path; VSOMEIP_DEBUG << "Listening at " << its_client.str(); } @@ -274,7 +270,6 @@ void routing_manager_proxy::on_message( std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)_data[i] << " "; std::cout << std::endl; #endif - byte_t its_command; client_t its_client; length_t its_length; @@ -364,8 +359,6 @@ void routing_manager_proxy::on_routing_info(const byte_t *_data, uint32_t _size) if (its_client != client_) local_services_[its_service][its_instance] = its_client; - - host_->on_availability(its_service, its_instance, true); } i += its_services_size; @@ -473,7 +466,6 @@ std::shared_ptr< endpoint > routing_manager_proxy::create_local(client_t _client io_); local_endpoints_[_client] = its_endpoint; - its_endpoint->start(); return its_endpoint; } @@ -482,6 +474,7 @@ std::shared_ptr< endpoint > routing_manager_proxy::find_or_create_local(client_t std::shared_ptr< endpoint > its_endpoint(find_local(_client)); if (0 == its_endpoint) { its_endpoint = create_local(_client); + its_endpoint->start(); } return its_endpoint; } diff --git a/implementation/routing/src/routing_manager_stub.cpp b/implementation/routing/src/routing_manager_stub.cpp index 74fd286..07d60b5 100644 --- a/implementation/routing/src/routing_manager_stub.cpp +++ b/implementation/routing/src/routing_manager_stub.cpp @@ -29,12 +29,14 @@ routing_manager_stub::~routing_manager_stub() { } void routing_manager_stub::init() { - std::string its_endpoint_path(VSOMEIP_BASE_PATH + VSOMEIP_ROUTING_ENDPOINT); - ::unlink(its_endpoint_path.c_str()); - VSOMEIP_DEBUG << "Routing endpoint at " << its_endpoint_path; + std::stringstream its_endpoint_path; + its_endpoint_path << VSOMEIP_BASE_PATH << VSOMEIP_ROUTING_CLIENT; + ::unlink(its_endpoint_path.str().c_str()); + + VSOMEIP_DEBUG << "Routing endpoint at " << its_endpoint_path.str(); endpoint_ = std::make_shared< local_server_endpoint_impl >( shared_from_this(), - boost::asio::local::stream_protocol::endpoint(its_endpoint_path), + boost::asio::local::stream_protocol::endpoint(its_endpoint_path.str()), io_ ); } @@ -50,8 +52,9 @@ void routing_manager_stub::stop() { watchdog_timer_.cancel(); endpoint_->stop(); - std::string its_endpoint_path(VSOMEIP_BASE_PATH + VSOMEIP_ROUTING_ENDPOINT); - ::unlink(its_endpoint_path.c_str()); + std::stringstream its_endpoint_path; + its_endpoint_path << VSOMEIP_BASE_PATH << VSOMEIP_ROUTING_CLIENT; + ::unlink(its_endpoint_path.str().c_str()); } routing_manager * routing_manager_stub::get_manager() { @@ -187,7 +190,6 @@ void routing_manager_stub::on_deregister_application(client_t _client) { void routing_manager_stub::on_offer_service( client_t _client, service_t _service, instance_t _instance) { - routing_info_[_client].second[_service].insert(_instance); broadcast_routing_info(); } @@ -243,6 +245,9 @@ void routing_manager_stub::send_routing_info(client_t _client) { std::memcpy(&its_command[its_size_pos], &its_entry_size, sizeof(uint32_t)); } + + + its_size -= VSOMEIP_COMMAND_PAYLOAD_POS; std::memcpy(&its_command[VSOMEIP_COMMAND_SIZE_POS_MIN], &its_size, sizeof(its_size)); its_size += VSOMEIP_COMMAND_PAYLOAD_POS; @@ -264,9 +269,11 @@ void routing_manager_stub::broadcast_routing_info() { void routing_manager_stub::broadcast(std::vector< byte_t > &_command) const { for (auto a : routing_info_) { - std::shared_ptr< endpoint > its_endpoint = routing_->find_local(a.first); - if (its_endpoint) { - its_endpoint->send(&_command[0], _command.size(), true); + if (a.first > 0) { + std::shared_ptr< endpoint > its_endpoint = routing_->find_local(a.first); + if (its_endpoint) { + its_endpoint->send(&_command[0], _command.size(), true); + } } } } @@ -320,10 +327,11 @@ void routing_manager_stub::check_watchdog() { std::list< client_t > lost; for (auto i : routing_info_) { - 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); - + if (i.first > 0) { + 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); + } } } @@ -356,5 +364,4 @@ void routing_manager_stub::send_application_lost(std::list< client_t > &_lost) { broadcast(its_command); } - } // namespace vsomeip diff --git a/implementation/runtime/include/application_impl.hpp b/implementation/runtime/include/application_impl.hpp index 7ef6b0b..c70a5d4 100644 --- a/implementation/runtime/include/application_impl.hpp +++ b/implementation/runtime/include/application_impl.hpp @@ -94,7 +94,7 @@ public: void on_event(event_type_e _event); void on_availability(service_t _service, instance_t _instance, bool _is_available) const; void on_message(std::shared_ptr< message > _message); - void on_error(); + void on_error(error_code_e _error); // service_discovery_host routing_manager * get_routing_manager() const; diff --git a/implementation/runtime/src/application_impl.cpp b/implementation/runtime/src/application_impl.cpp index 838627d..dd6230e 100644 --- a/implementation/runtime/src/application_impl.cpp +++ b/implementation/runtime/src/application_impl.cpp @@ -301,8 +301,8 @@ void application_impl::on_message(std::shared_ptr< message > _message) { } } -void application_impl::on_error() { - std::cerr << "ERROR" << std::endl; +void application_impl::on_error(error_code_e _error) { + std::cerr << "ERROR " << (int)_error << std::endl; } // Interface "service_discovery_host" diff --git a/interface/vsomeip/constants.hpp b/interface/vsomeip/constants.hpp index 36b5064..b183653 100644 --- a/interface/vsomeip/constants.hpp +++ b/interface/vsomeip/constants.hpp @@ -18,7 +18,7 @@ const std::string VSOMEIP_BASE_PATH = "/tmp/vsomeip-"; const major_version_t VSOMEIP_DEFAULT_MAJOR = 0x01; const minor_version_t VSOMEIP_DEFAULT_MINOR = 0x000000; -const ttl_t VSOMEIP_DEFAULT_TTL = 3600; +const ttl_t VSOMEIP_DEFAULT_TTL = 0xFFFFFF; // basically means "forever" const std::string VSOMEIP_DEFAULT_MULTICAST = "224.0.0.0"; const uint16_t VSOMEIP_DEFAULT_PORT = 30500; diff --git a/interface/vsomeip/error.hpp b/interface/vsomeip/error.hpp new file mode 100644 index 0000000..dd435b7 --- /dev/null +++ b/interface/vsomeip/error.hpp @@ -0,0 +1,23 @@ +// 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_ERROR_HPP +#define VSOMEIP_ERROR_HPP + +namespace vsomeip { + +enum class error_code_e : uint8_t { + CONFIGURATION_MISSING, + PORT_CONFIGURATION_MISSING, + CLIENT_ENDPOINT_CREATION_FAILED, + SERVER_ENDPOINT_CREATION_FAILED, + SERVICE_PROPERTY_MISMATCH +}; + +} // namespace vsomeip + +#endif // VSOMEIP_ERROR_HPP + diff --git a/implementation/test/configuration-test.cpp b/test/configuration-test.cpp index 14369b0..14369b0 100644 --- a/implementation/test/configuration-test.cpp +++ b/test/configuration-test.cpp |