From d4cf2c3b4f3f564b947f152cbbc0909fbeb2cace Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Micha=C3=ABl=20Celerier?= Date: Thu, 7 Nov 2024 20:05:17 -0500 Subject: [PATCH] [sockets] Clarify the various socket types; allow oscquery to expose multiple kind of OSC servers --- examples/Dataflow/SynthOSC.cpp | 6 +- examples/Editor/example_graph.cpp | 2 +- examples/Network/Mqtt_publication.cpp | 2 +- examples/Network/asio/OSC_playback.cpp | 7 +- examples/Network/udp/OSC_send_receive.cpp | 4 +- src/ossia/dataflow/nodes/gain.hpp | 2 +- src/ossia/dataflow/nodes/rand_float.hpp | 2 +- src/ossia/dataflow/nodes/sine.hpp | 2 +- .../oscquery/detail/get_query_parser.hpp | 17 +- .../network/oscquery/detail/json_writer.hpp | 15 +- .../oscquery/detail/json_writer_detail.cpp | 81 +++++-- .../oscquery/detail/json_writer_detail.hpp | 3 +- src/ossia/network/sockets/configuration.hpp | 29 ++- src/ossia/network/sockets/tcp_socket.hpp | 6 +- src/ossia/network/sockets/udp_socket.hpp | 6 +- src/ossia/preset/cue.cpp | 6 +- src/ossia/protocols/artnet/e131_protocol.cpp | 7 +- src/ossia/protocols/artnet/e131_protocol.hpp | 4 +- .../protocols/coap/coap_client_protocol.cpp | 2 +- .../protocols/coap/coap_client_protocol.hpp | 2 +- src/ossia/protocols/mqtt/mqtt_protocol.cpp | 4 +- src/ossia/protocols/mqtt/mqtt_protocol.hpp | 2 +- src/ossia/protocols/osc/osc_factory.cpp | 16 +- src/ossia/protocols/osc/osc_factory.hpp | 15 +- .../protocols/osc/osc_generic_protocol.hpp | 8 +- .../oscquery/oscquery_client_asio.hpp | 5 +- .../oscquery/oscquery_mirror_asio.cpp | 4 +- .../oscquery/oscquery_server_asio.cpp | 223 +++++++++++------- .../oscquery/oscquery_server_asio.hpp | 67 ++++-- tests/Network/MultiplexTest.cpp | 30 +-- tests/Network/OSCQueryTest.cpp | 3 +- tests/Network/OSC_TCP_SizeTest.cpp | 4 +- tests/Network/OSC_TCP_SlipTest.cpp | 4 +- tests/Network/OSC_UDPTest.cpp | 8 +- 34 files changed, 387 insertions(+), 211 deletions(-) diff --git a/examples/Dataflow/SynthOSC.cpp b/examples/Dataflow/SynthOSC.cpp index cf08c15a16f..3a1c0cba7cf 100644 --- a/examples/Dataflow/SynthOSC.cpp +++ b/examples/Dataflow/SynthOSC.cpp @@ -77,9 +77,9 @@ int main(int argc, char** argv) ossia::net::make_osc_protocol( ctx, {conf::HOST, conf::OSC1_1, conf::SLIP, ossia::net::udp_configuration{ - {ossia::net::receive_socket_configuration{ - {.host = "0.0.0.0", .port = listen_port}}, - ossia::net::send_socket_configuration{{"127.0.0.1", 9977}}}}}), + {ossia::net::inbound_socket_configuration{ + .bind = "0.0.0.0", .port = listen_port}, + ossia::net::outbound_socket_configuration{"127.0.0.1", 9977}}}}), "P"}; auto b = [](const std::string s, const ossia::value& val) { diff --git a/examples/Editor/example_graph.cpp b/examples/Editor/example_graph.cpp index 018ff492f12..bec21ad12b9 100644 --- a/examples/Editor/example_graph.cpp +++ b/examples/Editor/example_graph.cpp @@ -103,7 +103,7 @@ struct my_node final : ossia::graph_node m_outlets.push_back(new ossia::value_outlet); } - std::string label() const noexcept override { return "my_node"; } + std::string label() const noexcept override { return "my_node"; } void run(const ossia::token_request& t, ossia::exec_state_facade) noexcept override { if(auto a_float = pop_value(this->root_inputs()[0])) diff --git a/examples/Network/Mqtt_publication.cpp b/examples/Network/Mqtt_publication.cpp index 03f1bdc6090..ac94a4bcd36 100644 --- a/examples/Network/Mqtt_publication.cpp +++ b/examples/Network/Mqtt_publication.cpp @@ -23,7 +23,7 @@ int main(int argc, char** argv) auto ctx = std::make_shared(); ossia::net::mqtt5_configuration conf{ - ossia::net::tcp_configuration{{.host = "127.0.0.1", .port = 1883}}}; + ossia::net::tcp_client_configuration{{.host = "127.0.0.1", .port = 1883}}}; auto proto = std::make_unique(ctx, conf); ossia::net::generic_device device{std::move(proto), "P"}; diff --git a/examples/Network/asio/OSC_playback.cpp b/examples/Network/asio/OSC_playback.cpp index a14febf4445..ae85912adff 100644 --- a/examples/Network/asio/OSC_playback.cpp +++ b/examples/Network/asio/OSC_playback.cpp @@ -184,9 +184,10 @@ int main(int argc, char** argv) // Create the OSC device auto ctx = std::make_shared(); auto protocol = ossia::net::make_osc_protocol( - ctx, {.transport = ossia::net::udp_configuration{ - {.local = {}, - .remote = ossia::net::send_socket_configuration{"127.0.0.1", 4456}}}}); + ctx, + {.transport = ossia::net::udp_configuration{ + {.local = {}, + .remote = ossia::net::outbound_socket_configuration{"127.0.0.1", 4456}}}}); ossia::net::generic_device device{std::move(protocol), "B"}; diff --git a/examples/Network/udp/OSC_send_receive.cpp b/examples/Network/udp/OSC_send_receive.cpp index a526d5cc4e7..25349d21bdd 100644 --- a/examples/Network/udp/OSC_send_receive.cpp +++ b/examples/Network/udp/OSC_send_receive.cpp @@ -15,7 +15,7 @@ void send_main() .version = conf::OSC1_1, .transport = ossia::net::udp_configuration{ {.local = std::nullopt, - .remote = ossia::net::send_socket_configuration{{"127.0.0.1", 1234}}}}}; + .remote = ossia::net::outbound_socket_configuration{"127.0.0.1", 1234}}}}; ossia::net::generic_device device{ ossia::net::make_osc_protocol(ctx, mirror_config), "P"}; @@ -39,7 +39,7 @@ void receive_main() .mode = conf::HOST, .version = conf::OSC1_1, .transport = ossia::net::udp_configuration{ - {.local = ossia::net::receive_socket_configuration{{"0.0.0.0", 1234}}, + {.local = ossia::net::inbound_socket_configuration{"0.0.0.0", 1234}, .remote = std::nullopt}}}; ossia::net::generic_device device{ diff --git a/src/ossia/dataflow/nodes/gain.hpp b/src/ossia/dataflow/nodes/gain.hpp index 073f181b90c..7c844f3d433 100644 --- a/src/ossia/dataflow/nodes/gain.hpp +++ b/src/ossia/dataflow/nodes/gain.hpp @@ -18,7 +18,7 @@ struct gain_node final : public ossia::nonowning_graph_node m_outlets.push_back(&audio_out); } - std::string label() const noexcept override { return "gain"; } + std::string label() const noexcept override { return "gain"; } void run(const ossia::token_request& t, ossia::exec_state_facade st) noexcept override { auto& vals = gain_in.target()->get_data(); diff --git a/src/ossia/dataflow/nodes/rand_float.hpp b/src/ossia/dataflow/nodes/rand_float.hpp index e2c865e2882..368a6f54202 100644 --- a/src/ossia/dataflow/nodes/rand_float.hpp +++ b/src/ossia/dataflow/nodes/rand_float.hpp @@ -18,7 +18,7 @@ struct rand_float final : public ossia::nonowning_graph_node m_outlets.push_back(&value_out); } - std::string label() const noexcept override { return "rand_float"; } + std::string label() const noexcept override { return "rand_float"; } void run(const ossia::token_request& t, ossia::exec_state_facade e) noexcept override { thread_local std::mt19937 gen; diff --git a/src/ossia/dataflow/nodes/sine.hpp b/src/ossia/dataflow/nodes/sine.hpp index d881ab30bf3..3c5e227bece 100644 --- a/src/ossia/dataflow/nodes/sine.hpp +++ b/src/ossia/dataflow/nodes/sine.hpp @@ -24,7 +24,7 @@ struct sine final : public ossia::nonowning_graph_node m_outlets.push_back(&audio_out); } - std::string label() const noexcept override { return "sine"; } + std::string label() const noexcept override { return "sine"; } void run(const ossia::token_request& t, ossia::exec_state_facade st) noexcept override { auto& vals = freq_in.target()->get_data(); diff --git a/src/ossia/network/oscquery/detail/get_query_parser.hpp b/src/ossia/network/oscquery/detail/get_query_parser.hpp index e1bf5d108c9..e8d71bc9ef3 100644 --- a/src/ossia/network/oscquery/detail/get_query_parser.hpp +++ b/src/ossia/network/oscquery/detail/get_query_parser.hpp @@ -155,8 +155,23 @@ class get_query_answerer auto& socket = sockets.get_socket(); std::string local_client_ip = socket.local_endpoint().address().to_string(); + + auto transports = [&]() -> std::vector { + if constexpr(requires { proto.get_osc_port(); }) + { + ossia::net::udp_server_configuration conf; + conf.bind = ""; + conf.port = proto.get_osc_port(); + return {conf}; + } + else + { + return proto.get_transports(); + } + }; + return oscquery::json_writer::query_host_info( - proto.get_device().get_name(), proto.get_osc_port(), local_client_ip, + proto.get_device().get_name(), transports(), local_client_ip, proto.get_ws_port()); } } diff --git a/src/ossia/network/oscquery/detail/json_writer.hpp b/src/ossia/network/oscquery/detail/json_writer.hpp index 804531d16ca..5a36d169b6c 100644 --- a/src/ossia/network/oscquery/detail/json_writer.hpp +++ b/src/ossia/network/oscquery/detail/json_writer.hpp @@ -2,7 +2,7 @@ #include #include #include - +#include namespace ossia { namespace net @@ -24,8 +24,9 @@ class OSSIA_EXPORT json_writer static string_t device_info(int port); static string_t query_host_info( - const std::string& name, const int osc_port, const std::string& local_ip, - int ws_port); + std::string_view name, + const std::vector& osc_port, + std::string_view local_ip, int ws_port); // Format interface // Queries @@ -71,10 +72,10 @@ class OSSIA_EXPORT json_writer static string_t path_changed(const ossia::net::node_base& n); //! Sent when a node is being removed - static string_t path_removed(const std::string& path); + static string_t path_removed(std::string_view path); //! Sent when a node is renamed - static string_t path_renamed(const std::string& old_path, const std::string& new_path); + static string_t path_renamed(std::string_view old_path, std::string_view new_path); static string_t attributes_changed(const ossia::net::node_base& n, std::string_view attribute); @@ -97,9 +98,9 @@ class OSSIA_EXPORT json_writer path_added_impl(detail::json_writer_impl& p, const ossia::net::node_base& n); static void path_changed_impl(detail::json_writer_impl& p, const ossia::net::node_base& n); - static void path_removed_impl(writer_t& wr, const std::string& path); + static void path_removed_impl(writer_t& wr, std::string_view path); static void path_renamed_impl( - json_writer::writer_t& wr, const std::string& path, const std::string& old); + json_writer::writer_t& wr, std::string_view path, std::string_view old); static void attribute_changed_impl( detail::json_writer_impl& p, const ossia::net::node_base& n, std::string_view attribute); diff --git a/src/ossia/network/oscquery/detail/json_writer_detail.cpp b/src/ossia/network/oscquery/detail/json_writer_detail.cpp index e54bf8f6416..e99988f3892 100644 --- a/src/ossia/network/oscquery/detail/json_writer_detail.cpp +++ b/src/ossia/network/oscquery/detail/json_writer_detail.cpp @@ -116,9 +116,9 @@ void json_writer_impl::writeValue(bool i) const { writer.Bool(i); } -void json_writer_impl::writeValue(const std::string& i) const +void json_writer_impl::writeValue(std::string_view i) const { - writer.String(i); + writer.String(i.data(), i.size()); } void json_writer_impl::writeValue(const repetition_filter& i) const { @@ -375,7 +375,7 @@ void json_writer::path_changed_impl(detail::json_writer_impl& p, const net::node wr.EndObject(); } -void json_writer::path_removed_impl(json_writer::writer_t& wr, const std::string& path) +void json_writer::path_removed_impl(json_writer::writer_t& wr, std::string_view path) { wr.StartObject(); @@ -383,13 +383,13 @@ void json_writer::path_removed_impl(json_writer::writer_t& wr, const std::string write_json(wr, detail::path_removed()); write_json_key(wr, detail::data()); - wr.String(path); + write_json(wr, path); wr.EndObject(); } void json_writer::path_renamed_impl( - json_writer::writer_t& wr, const std::string& old_path, const std::string& new_path) + json_writer::writer_t& wr, std::string_view old_path, std::string_view new_path) { wr.StartObject(); @@ -491,26 +491,75 @@ json_writer::string_t json_writer::device_info(int port) return buf; } -json_writer::string_t json_writer::query_host_info( - const std::string& name, const int osc_port, const std::string& local_ip, - int ws_port) +struct transport_visitor { + json_writer::writer_t& wr; + void operator()(const ossia::net::udp_server_configuration& v) const noexcept + { + wr.Key("OSC_PORT"); + wr.Int(v.port); + wr.Key("OSC_TRANSPORT"); + wr.String("UDP"); + } + + void operator()(const ossia::net::tcp_server_configuration& v) const noexcept + { + wr.Key("OSC_PORT"); + wr.Int(v.port); + wr.Key("OSC_TRANSPORT"); + wr.String("TCP"); + } + void operator()(const ossia::net::unix_dgram_server_configuration& v) const noexcept + { + wr.Key("OSC_PORT"); + wr.String(v.fd); + wr.Key("OSC_TRANSPORT"); + wr.String("UNIX_DATAGRAM"); + } + void operator()(const ossia::net::unix_stream_server_configuration& v) const noexcept + { + wr.Key("OSC_PORT"); + wr.String(v.fd); + wr.Key("OSC_TRANSPORT"); + wr.String("UNIX_STREAM"); + } + void operator()(const ossia::net::serial_configuration& v) const noexcept + { + wr.Key("OSC_PORT"); + wr.String(v.port); + wr.Key("OSC_TRANSPORT"); + wr.String("SERIAL"); + } + void operator()(const ossia::net::ws_server_configuration& v) const noexcept + { + wr.Key("OSC_PORT"); + wr.Int(v.port); + wr.Key("OSC_TRANSPORT"); + wr.String("WEBSOCKET"); + } +}; +json_writer::string_t json_writer::query_host_info( + std::string_view name, + const std::vector& osc_port, + std::string_view local_ip, int ws_port) +{ string_t buf; writer_t wr(buf); wr.StartObject(); wr.Key("NAME"); - wr.String(name); + write_json(wr, name); + wr.Key("WS_IP"); - wr.String(local_ip); + write_json(wr, local_ip); wr.Key("WS_PORT"); wr.Int(ws_port); - wr.Key("OSC_PORT"); - wr.Int(osc_port); - wr.Key("OSC_TRANSPORT"); - wr.String("UDP"); + for(auto& v : osc_port) + { + ossia::visit(transport_visitor{wr}, v); + } wr.Key("EXTENSIONS"); wr.StartObject(); @@ -658,7 +707,7 @@ json_writer::string_t json_writer::path_changed(const net::node_base& n) return buf; } -json_writer::string_t json_writer::path_removed(const std::string& path) +json_writer::string_t json_writer::path_removed(std::string_view path) { string_t buf; writer_t wr(buf); @@ -669,7 +718,7 @@ json_writer::string_t json_writer::path_removed(const std::string& path) } json_writer::string_t -json_writer::path_renamed(const std::string& old_path, const std::string& new_path) +json_writer::path_renamed(std::string_view old_path, std::string_view new_path) { string_t buf; writer_t wr(buf); diff --git a/src/ossia/network/oscquery/detail/json_writer_detail.hpp b/src/ossia/network/oscquery/detail/json_writer_detail.hpp index e2ffaccddfd..562169e771b 100644 --- a/src/ossia/network/oscquery/detail/json_writer_detail.hpp +++ b/src/ossia/network/oscquery/detail/json_writer_detail.hpp @@ -1,6 +1,7 @@ #pragma once #include #include + namespace ossia::oscquery::detail { //! Implementation of the JSON serialisation mechanism for oscquery @@ -21,7 +22,7 @@ struct json_writer_impl void writeValue(float i) const; void writeValue(double i) const; void writeValue(bool i) const; - void writeValue(const std::string& i) const; + void writeValue(std::string_view i) const; void writeValue(const ossia::repetition_filter& i) const; void writeValue(const ossia::net::instance_bounds& i) const; diff --git a/src/ossia/network/sockets/configuration.hpp b/src/ossia/network/sockets/configuration.hpp index 6c411e25943..661ece07c28 100644 --- a/src/ossia/network/sockets/configuration.hpp +++ b/src/ossia/network/sockets/configuration.hpp @@ -25,18 +25,16 @@ struct receive_fd_configuration : fd_configuration { }; -struct socket_configuration +struct outbound_socket_configuration { std::string host; uint16_t port{}; bool broadcast{}; }; - -struct send_socket_configuration : socket_configuration -{ -}; -struct receive_socket_configuration : socket_configuration +struct inbound_socket_configuration { + std::string bind; + uint16_t port{}; }; struct double_fd_configuration @@ -47,8 +45,8 @@ struct double_fd_configuration struct double_socket_configuration { - std::optional local; - std::optional remote; + std::optional local; + std::optional remote; }; struct serial_configuration @@ -102,7 +100,20 @@ struct udp_configuration : double_socket_configuration { }; -struct tcp_configuration : socket_configuration +struct tcp_client_configuration : outbound_socket_configuration +{ +}; + +struct udp_server_configuration : inbound_socket_configuration +{ +}; +struct tcp_server_configuration : inbound_socket_configuration +{ +}; +struct unix_dgram_server_configuration : receive_fd_configuration +{ +}; +struct unix_stream_server_configuration : receive_fd_configuration { }; } diff --git a/src/ossia/network/sockets/tcp_socket.hpp b/src/ossia/network/sockets/tcp_socket.hpp index 4a09b5f0569..8315812266e 100644 --- a/src/ossia/network/sockets/tcp_socket.hpp +++ b/src/ossia/network/sockets/tcp_socket.hpp @@ -47,11 +47,11 @@ class tcp_server using socket = typename proto::socket; using listener = tcp_listener; - tcp_server(const socket_configuration& conf, boost::asio::io_context& ctx) + tcp_server(const inbound_socket_configuration& conf, boost::asio::io_context& ctx) : m_context{ctx} , m_acceptor{ boost::asio::make_strand(ctx), - proto::endpoint{boost::asio::ip::make_address(conf.host), conf.port}} + proto::endpoint{boost::asio::ip::make_address(conf.bind), conf.port}} { } @@ -65,7 +65,7 @@ class tcp_client using proto = boost::asio::ip::tcp; using socket = typename proto::socket; - tcp_client(const socket_configuration& conf, boost::asio::io_context& ctx) + tcp_client(const outbound_socket_configuration& conf, boost::asio::io_context& ctx) : m_context{ctx} , m_endpoint{boost::asio::ip::make_address(conf.host), conf.port} , m_socket{boost::asio::make_strand(ctx)} diff --git a/src/ossia/network/sockets/udp_socket.hpp b/src/ossia/network/sockets/udp_socket.hpp index 920e0e1ac27..1257c175035 100644 --- a/src/ossia/network/sockets/udp_socket.hpp +++ b/src/ossia/network/sockets/udp_socket.hpp @@ -25,9 +25,9 @@ class udp_receive_socket { } - udp_receive_socket(const socket_configuration& conf, boost::asio::io_context& ctx) + udp_receive_socket(const inbound_socket_configuration& conf, boost::asio::io_context& ctx) : m_context{ctx} - , m_endpoint{boost::asio::ip::make_address(conf.host), conf.port} + , m_endpoint{boost::asio::ip::make_address(conf.bind), conf.port} , m_socket{boost::asio::make_strand(ctx)} { } @@ -94,7 +94,7 @@ class udp_send_socket using proto = boost::asio::ip::udp; public: - udp_send_socket(const socket_configuration& conf, boost::asio::io_context& ctx) + udp_send_socket(const outbound_socket_configuration& conf, boost::asio::io_context& ctx) : m_context{ctx} , m_endpoint{boost::asio::ip::make_address(conf.host), conf.port} , m_socket{boost::asio::make_strand(ctx)} diff --git a/src/ossia/preset/cue.cpp b/src/ossia/preset/cue.cpp index 9d511440417..3dcebd2bbd9 100644 --- a/src/ossia/preset/cue.cpp +++ b/src/ossia/preset/cue.cpp @@ -135,7 +135,7 @@ struct priority_sort struct protocol_safe_mode_enabler { #if defined(OSSIA_PROTOCOL_OSCQUERY) - std::vector> + std::vector> protocols{}; #endif @@ -143,7 +143,7 @@ struct protocol_safe_mode_enabler { #if defined(OSSIA_PROTOCOL_OSCQUERY) auto& proto = root.get_device().get_protocol(); - if(auto oscq = dynamic_cast(&proto)) + if(auto oscq = dynamic_cast(&proto)) { protocols.emplace_back(oscq, oscq->force_ws()); oscq->set_force_ws(true); @@ -153,7 +153,7 @@ struct protocol_safe_mode_enabler for(auto& proto : mplex->get_protocols()) { if(auto oscq - = dynamic_cast(proto.get())) + = dynamic_cast(proto.get())) { protocols.emplace_back(oscq, oscq->force_ws()); oscq->set_force_ws(true); diff --git a/src/ossia/protocols/artnet/e131_protocol.cpp b/src/ossia/protocols/artnet/e131_protocol.cpp index 36d94361fb8..f18c55e2a67 100644 --- a/src/ossia/protocols/artnet/e131_protocol.cpp +++ b/src/ossia/protocols/artnet/e131_protocol.cpp @@ -134,7 +134,7 @@ static_assert(sizeof(e131_packet) == 638); namespace ossia::net { static boost::asio::ip::address_v4 -e131_host(const dmx_config& conf, const ossia::net::socket_configuration& socket) +e131_host(const dmx_config& conf, const ossia::net::outbound_socket_configuration& socket) { if(conf.multicast) { @@ -148,7 +148,7 @@ e131_host(const dmx_config& conf, const ossia::net::socket_configuration& socket e131_protocol::e131_protocol( ossia::net::network_context_ptr ctx, const dmx_config& conf, - const ossia::net::socket_configuration& socket) + const ossia::net::outbound_socket_configuration& socket) : dmx_output_protocol_base{ctx, conf} , m_socket{e131_host(conf, socket), socket.port, ctx->context} { @@ -206,10 +206,11 @@ void e131_protocol::update_function() e131_input_protocol::e131_input_protocol( ossia::net::network_context_ptr ctx, const dmx_config& conf, - const ossia::net::socket_configuration& socket) + const ossia::net::inbound_socket_configuration& socket) : dmx_input_protocol_base{ctx, conf} , m_socket{socket, ctx->context} { + // FIXME we need to join the multicast group if(conf.frequency < 1 || conf.frequency > 44) throw std::runtime_error("DMX 512 update frequency must be in the range [1, 44] Hz"); diff --git a/src/ossia/protocols/artnet/e131_protocol.hpp b/src/ossia/protocols/artnet/e131_protocol.hpp index a22177d9e17..e5185a2e058 100644 --- a/src/ossia/protocols/artnet/e131_protocol.hpp +++ b/src/ossia/protocols/artnet/e131_protocol.hpp @@ -17,7 +17,7 @@ class OSSIA_EXPORT e131_protocol final : public ossia::net::dmx_output_protocol_ e131_protocol( ossia::net::network_context_ptr, const dmx_config& conf, - const ossia::net::socket_configuration& socket); + const ossia::net::outbound_socket_configuration& socket); ~e131_protocol(); @@ -36,7 +36,7 @@ class OSSIA_EXPORT e131_input_protocol final : public ossia::net::dmx_input_prot e131_input_protocol( ossia::net::network_context_ptr, const dmx_config& conf, - const ossia::net::socket_configuration& socket); + const ossia::net::inbound_socket_configuration& socket); ~e131_input_protocol(); diff --git a/src/ossia/protocols/coap/coap_client_protocol.cpp b/src/ossia/protocols/coap/coap_client_protocol.cpp index 9527a056943..c1274174e20 100644 --- a/src/ossia/protocols/coap/coap_client_protocol.cpp +++ b/src/ossia/protocols/coap/coap_client_protocol.cpp @@ -329,7 +329,7 @@ coap_client_protocol::coap_client_protocol( } } - void operator()(const ossia::net::tcp_configuration& conf) + void operator()(const ossia::net::tcp_client_configuration& conf) { self.m_host += "coap+tcp://"; self.m_host += conf.host; diff --git a/src/ossia/protocols/coap/coap_client_protocol.hpp b/src/ossia/protocols/coap/coap_client_protocol.hpp index f3dce75b5ef..769cce4fdf6 100644 --- a/src/ossia/protocols/coap/coap_client_protocol.hpp +++ b/src/ossia/protocols/coap/coap_client_protocol.hpp @@ -17,7 +17,7 @@ using strand_type = decltype(boost::asio::make_strand(std::declval())); struct coap_client_configuration { - ossia::variant + ossia::variant transport; }; struct coap_client; diff --git a/src/ossia/protocols/mqtt/mqtt_protocol.cpp b/src/ossia/protocols/mqtt/mqtt_protocol.cpp index 5223b655d65..d24e431d80c 100644 --- a/src/ossia/protocols/mqtt/mqtt_protocol.cpp +++ b/src/ossia/protocols/mqtt/mqtt_protocol.cpp @@ -49,7 +49,7 @@ struct mqtt5_client : mqtt5_client_base { if constexpr(std::is_same_v) { - auto& conf = ossia::get(m_conf.transport); + auto& conf = ossia::get(m_conf.transport); client.brokers(conf.host, conf.port).async_run(boost::asio::detached); } else if constexpr(std::is_same_v) @@ -175,7 +175,7 @@ static auto make_mqtt_client(const mqtt5_configuration& conf, strand_type& stran struct { strand_type& strand; - std::unique_ptr operator()(const tcp_configuration& tcp) + std::unique_ptr operator()(const tcp_client_configuration& tcp) { return std::make_unique>(strand); } diff --git a/src/ossia/protocols/mqtt/mqtt_protocol.hpp b/src/ossia/protocols/mqtt/mqtt_protocol.hpp index f1a707db6fa..55e70f583c9 100644 --- a/src/ossia/protocols/mqtt/mqtt_protocol.hpp +++ b/src/ossia/protocols/mqtt/mqtt_protocol.hpp @@ -15,7 +15,7 @@ using strand_type struct mqtt5_configuration { - ossia::variant transport; + ossia::variant transport; }; struct mqtt5_client_base; diff --git a/src/ossia/protocols/osc/osc_factory.cpp b/src/ossia/protocols/osc/osc_factory.cpp index 4b02368abac..e8a809841d3 100644 --- a/src/ossia/protocols/osc/osc_factory.cpp +++ b/src/ossia/protocols/osc/osc_factory.cpp @@ -43,7 +43,7 @@ make_osc_protocol_impl(network_context_ptr&& ctx, osc_protocol_configuration&& c return {}; } - auto operator()(ossia::net::tcp_configuration&& conf) const + auto operator()(ossia::net::tcp_client_configuration&& conf) const -> std::unique_ptr { if(config.framing == conf::SIZE_PREFIX) @@ -56,6 +56,12 @@ make_osc_protocol_impl(network_context_ptr&& ctx, osc_protocol_configuration&& c std::move(ctx), conf); } + auto operator()(ossia::net::tcp_server_configuration&& conf) const + -> std::unique_ptr + { + return {}; + } + auto operator()(ossia::net::unix_dgram_configuration&& conf) const -> std::unique_ptr { @@ -148,7 +154,13 @@ make_osc_protocol_impl(network_context_ptr&& ctx, osc_protocol_configuration&& c return {}; } - auto operator()(ossia::net::tcp_configuration&& conf) const + auto operator()(ossia::net::tcp_client_configuration&& conf) const + -> std::unique_ptr + { + return {}; + } + + auto operator()(ossia::net::tcp_server_configuration&& conf) const -> std::unique_ptr { if(config.framing == conf::SIZE_PREFIX) diff --git a/src/ossia/protocols/osc/osc_factory.hpp b/src/ossia/protocols/osc/osc_factory.hpp index 2751a91efc6..9f050fcc1cd 100644 --- a/src/ossia/protocols/osc/osc_factory.hpp +++ b/src/ossia/protocols/osc/osc_factory.hpp @@ -6,6 +6,15 @@ namespace ossia::net { +using osc_server_configuration = ossia::variant< + udp_server_configuration, tcp_server_configuration, unix_dgram_server_configuration, + unix_stream_server_configuration, serial_configuration, ws_server_configuration>; + +using osc_transport_configuration = ossia::variant< + udp_configuration, tcp_client_configuration, tcp_server_configuration, + unix_dgram_configuration, unix_stream_configuration, serial_configuration, + ws_client_configuration, ws_server_configuration>; + struct osc_protocol_configuration { // libossia semantic level: host can change any parameter, mirror can only @@ -31,11 +40,7 @@ struct osc_protocol_configuration SLIP } framing{SLIP}; - ossia::variant< - udp_configuration, tcp_configuration, unix_dgram_configuration, - unix_stream_configuration, serial_configuration, ws_client_configuration, - ws_server_configuration> - transport; + osc_transport_configuration transport; }; using osc_protocol_base = can_learn; diff --git a/src/ossia/protocols/osc/osc_generic_protocol.hpp b/src/ossia/protocols/osc/osc_generic_protocol.hpp index 9914cc2dfea..38697294598 100644 --- a/src/ossia/protocols/osc/osc_generic_protocol.hpp +++ b/src/ossia/protocols/osc/osc_generic_protocol.hpp @@ -54,8 +54,8 @@ class osc_generic_bidir_protocol : public can_learn } osc_generic_bidir_protocol( - network_context_ptr ctx, const send_socket_configuration& send_conf, - const receive_socket_configuration& recv_conf) + network_context_ptr ctx, const outbound_socket_configuration& send_conf, + const inbound_socket_configuration& recv_conf) : can_learn{flags{SupportsMultiplex}} , m_ctx{std::move(ctx)} , m_id{*this} @@ -74,7 +74,7 @@ class osc_generic_bidir_protocol : public can_learn } osc_generic_bidir_protocol( - network_context_ptr ctx, const send_socket_configuration& send_conf) + network_context_ptr ctx, const outbound_socket_configuration& send_conf) : can_learn{flags{SupportsMultiplex}} , m_ctx{std::move(ctx)} , m_id{*this} @@ -84,7 +84,7 @@ class osc_generic_bidir_protocol : public can_learn } osc_generic_bidir_protocol( - network_context_ptr ctx, const receive_socket_configuration& recv_conf) + network_context_ptr ctx, const inbound_socket_configuration& recv_conf) : can_learn{flags{SupportsMultiplex}} , m_ctx{std::move(ctx)} , m_id{*this} diff --git a/src/ossia/protocols/oscquery/oscquery_client_asio.hpp b/src/ossia/protocols/oscquery/oscquery_client_asio.hpp index 1e7e56be17d..492f09469b7 100644 --- a/src/ossia/protocols/oscquery/oscquery_client_asio.hpp +++ b/src/ossia/protocols/oscquery/oscquery_client_asio.hpp @@ -54,10 +54,11 @@ struct oscquery_client } void - open_osc_sender(ossia::oscquery_asio::oscquery_server_protocol& proto, uint16_t port) + open_osc_sender(ossia::oscquery_asio::oscquery_server_protocol_base& proto, uint16_t port) { osc_socket = std::make_unique( - ossia::net::socket_configuration{client_ip, port}, proto.m_context->context); + ossia::net::outbound_socket_configuration{client_ip, port}, + proto.m_context->context); osc_socket->connect(); } }; diff --git a/src/ossia/protocols/oscquery/oscquery_mirror_asio.cpp b/src/ossia/protocols/oscquery/oscquery_mirror_asio.cpp index 1b0c87a05e7..9e9b49210c4 100644 --- a/src/ossia/protocols/oscquery/oscquery_mirror_asio.cpp +++ b/src/ossia/protocols/oscquery/oscquery_mirror_asio.cpp @@ -510,7 +510,7 @@ void oscquery_mirror_asio_protocol::start_websockets() void oscquery_mirror_asio_protocol::start_osc() { m_oscServer = std::make_unique( - ossia::net::socket_configuration{"0.0.0.0", (uint16_t)m_osc_port}, + ossia::net::inbound_socket_configuration{"0.0.0.0", (uint16_t)m_osc_port}, this->m_ctx->context); m_oscServer->open(); m_osc_port = m_oscServer->m_socket.local_endpoint().port(); @@ -621,7 +621,7 @@ bool oscquery_mirror_asio_protocol::on_text_ws_message( const auto& server_host = asio_to_ip(*m_host_info.osc_ip); uint16_t server_port = uint16_t(*m_host_info.osc_port); m_oscSender = std::make_unique( - ossia::net::socket_configuration{server_host, server_port}, + ossia::net::outbound_socket_configuration{server_host, server_port}, this->m_ctx->context); m_oscSender->connect(); uint16_t local_server_port = m_oscServer->m_socket.local_endpoint().port(); diff --git a/src/ossia/protocols/oscquery/oscquery_server_asio.cpp b/src/ossia/protocols/oscquery/oscquery_server_asio.cpp index f9eddf57d19..646a539c9f9 100644 --- a/src/ossia/protocols/oscquery/oscquery_server_asio.cpp +++ b/src/ossia/protocols/oscquery/oscquery_server_asio.cpp @@ -57,16 +57,15 @@ is_same(const oscquery_client& clt, const ossia::net::message_origin_identifier& return (uintptr_t)clt.connection.lock().get() == id.identifier; } -oscquery_server_protocol::oscquery_server_protocol( - ossia::net::network_context_ptr ctx, uint16_t osc_port, uint16_t ws_port, +oscquery_server_protocol_base::oscquery_server_protocol_base( + ossia::net::network_context_ptr ctx, + const std::vector& conf, uint16_t ws_port, bool forceWS) : protocol_base{flags{SupportsMultiplex}} , m_context{std::move(ctx)} - , m_oscServer{std::make_unique( - ossia::net::socket_configuration{"0.0.0.0", osc_port}, m_context->context)} , m_websocketServer{std::make_unique( m_context->context)} - , m_oscPort{osc_port} + , m_oscConf{conf} , m_wsPort{ws_port} , m_forceWS{forceWS} { @@ -98,37 +97,38 @@ oscquery_server_protocol::oscquery_server_protocol( }); } -oscquery_server_protocol::~oscquery_server_protocol() +oscquery_server_protocol_base::~oscquery_server_protocol_base() { if(m_device) { auto& dev = *m_device; - dev.on_node_created.disconnect<&oscquery_server_protocol::on_nodeCreated>(this); - dev.on_node_removing.disconnect<&oscquery_server_protocol::on_nodeRemoved>(this); - dev.on_parameter_created.disconnect<&oscquery_server_protocol::on_parameterChanged>( + dev.on_node_created.disconnect<&oscquery_server_protocol_base::on_nodeCreated>(this); + dev.on_node_removing.disconnect<&oscquery_server_protocol_base::on_nodeRemoved>( this); - dev.on_parameter_removing.disconnect<&oscquery_server_protocol::on_parameterChanged>( - this); - dev.on_attribute_modified.disconnect<&oscquery_server_protocol::on_attributeChanged>( - this); - dev.on_node_renamed.disconnect<&oscquery_server_protocol::on_nodeRenamed>(this); + dev.on_parameter_created + .disconnect<&oscquery_server_protocol_base::on_parameterChanged>(this); + dev.on_parameter_removing + .disconnect<&oscquery_server_protocol_base::on_parameterChanged>(this); + dev.on_attribute_modified + .disconnect<&oscquery_server_protocol_base::on_attributeChanged>(this); + dev.on_node_renamed.disconnect<&oscquery_server_protocol_base::on_nodeRenamed>(this); } stop(); } -bool oscquery_server_protocol::pull(net::parameter_base&) +bool oscquery_server_protocol_base::pull(net::parameter_base&) { //! The server cannot pull because it can have multiple clients. return false; } -std::future oscquery_server_protocol::pull_async(net::parameter_base&) +std::future oscquery_server_protocol_base::pull_async(net::parameter_base&) { // Do nothing return {}; } -void oscquery_server_protocol::request(net::parameter_base&) +void oscquery_server_protocol_base::request(net::parameter_base&) { // Do nothing } @@ -144,7 +144,7 @@ struct ws_client_socket } }; -bool oscquery_server_protocol::write_impl(std::string_view data, bool critical) +bool oscquery_server_protocol_base::write_impl(std::string_view data, bool critical) { // Push to all clients if(!critical) @@ -177,7 +177,7 @@ bool oscquery_server_protocol::write_impl(std::string_view data, bool critical) } template -bool oscquery_server_protocol::push_impl(const T& addr, const ossia::value& v) +bool oscquery_server_protocol_base::push_impl(const T& addr, const ossia::value& v) { using namespace ossia::net; using namespace ossia::oscquery; @@ -240,18 +240,18 @@ bool oscquery_server_protocol::push_impl(const T& addr, const ossia::value& v) return false; } -bool oscquery_server_protocol::push( +bool oscquery_server_protocol_base::push( const net::parameter_base& addr, const ossia::value& v) { return push_impl(addr, v); } -bool oscquery_server_protocol::push_raw(const net::full_parameter_data& addr) +bool oscquery_server_protocol_base::push_raw(const net::full_parameter_data& addr) { return push_impl(addr, addr.value()); } -bool oscquery_server_protocol::push_bundle( +bool oscquery_server_protocol_base::push_bundle( const std::vector& addresses) { using namespace ossia::net; @@ -266,7 +266,7 @@ bool oscquery_server_protocol::push_bundle( return false; } -bool oscquery_server_protocol::push_raw_bundle( +bool oscquery_server_protocol_base::push_raw_bundle( const std::vector& addresses) { using namespace ossia::net; @@ -281,7 +281,7 @@ bool oscquery_server_protocol::push_raw_bundle( return false; } -bool oscquery_server_protocol::echo_incoming_message( +bool oscquery_server_protocol_base::echo_incoming_message( const net::message_origin_identifier& id, const net::parameter_base& addr, const ossia::value& val) { @@ -351,7 +351,7 @@ bool oscquery_server_protocol::echo_incoming_message( return true; } -bool oscquery_server_protocol::observe(net::parameter_base& address, bool enable) +bool oscquery_server_protocol_base::observe(net::parameter_base& address, bool enable) { if(enable) { @@ -365,30 +365,31 @@ bool oscquery_server_protocol::observe(net::parameter_base& address, bool enable return true; } -bool oscquery_server_protocol::observe_quietly(net::parameter_base& addr, bool b) +bool oscquery_server_protocol_base::observe_quietly(net::parameter_base& addr, bool b) { return observe(addr, b); } -bool oscquery_server_protocol::update(net::node_base&) +bool oscquery_server_protocol_base::update(net::node_base&) { return false; } -void oscquery_server_protocol::set_device(net::device_base& dev) +void oscquery_server_protocol_base::set_device(net::device_base& dev) { if(m_device) { auto& old = *m_device; - old.on_node_created.disconnect<&oscquery_server_protocol::on_nodeCreated>(this); - old.on_node_removing.disconnect<&oscquery_server_protocol::on_nodeRemoved>(this); - dev.on_parameter_created.disconnect<&oscquery_server_protocol::on_parameterChanged>( + old.on_node_created.disconnect<&oscquery_server_protocol_base::on_nodeCreated>(this); + old.on_node_removing.disconnect<&oscquery_server_protocol_base::on_nodeRemoved>( this); - dev.on_parameter_removing.disconnect<&oscquery_server_protocol::on_parameterChanged>( - this); - old.on_attribute_modified.disconnect<&oscquery_server_protocol::on_attributeChanged>( - this); - old.on_node_renamed.disconnect<&oscquery_server_protocol::on_nodeRenamed>(this); + dev.on_parameter_created + .disconnect<&oscquery_server_protocol_base::on_parameterChanged>(this); + dev.on_parameter_removing + .disconnect<&oscquery_server_protocol_base::on_parameterChanged>(this); + old.on_attribute_modified + .disconnect<&oscquery_server_protocol_base::on_attributeChanged>(this); + old.on_node_renamed.disconnect<&oscquery_server_protocol_base::on_nodeRenamed>(this); ossia::net::visit_parameters( old.get_root_node(), @@ -399,14 +400,15 @@ void oscquery_server_protocol::set_device(net::device_base& dev) } m_device = &dev; - dev.on_node_created.connect<&oscquery_server_protocol::on_nodeCreated>(this); - dev.on_node_removing.connect<&oscquery_server_protocol::on_nodeRemoved>(this); - dev.on_parameter_created.connect<&oscquery_server_protocol::on_parameterChanged>(this); - dev.on_parameter_removing.connect<&oscquery_server_protocol::on_parameterChanged>( + dev.on_node_created.connect<&oscquery_server_protocol_base::on_nodeCreated>(this); + dev.on_node_removing.connect<&oscquery_server_protocol_base::on_nodeRemoved>(this); + dev.on_parameter_created.connect<&oscquery_server_protocol_base::on_parameterChanged>( + this); + dev.on_parameter_removing.connect<&oscquery_server_protocol_base::on_parameterChanged>( this); - dev.on_attribute_modified.connect<&oscquery_server_protocol::on_attributeChanged>( + dev.on_attribute_modified.connect<&oscquery_server_protocol_base::on_attributeChanged>( this); - dev.on_node_renamed.connect<&oscquery_server_protocol::on_nodeRenamed>(this); + dev.on_node_renamed.connect<&oscquery_server_protocol_base::on_nodeRenamed>(this); update_zeroconf(); @@ -417,23 +419,10 @@ void oscquery_server_protocol::set_device(net::device_base& dev) }); m_websocketServer->listen(m_wsPort); - - m_oscServer->open(); - m_oscServer->receive( - [this](const char* data, std::size_t sz) { process_raw_osc_data(data, sz); }); } -void oscquery_server_protocol::stop() +void oscquery_server_protocol_base::stop() { - try - { - m_oscServer->close(); - } - catch(...) - { - logger().error("Error when stopping osc server"); - } - try { lock_t lock(m_clientsMutex); @@ -463,12 +452,13 @@ void oscquery_server_protocol::stop() } } -void oscquery_server_protocol::set_force_ws(bool forceWS) noexcept +void oscquery_server_protocol_base::set_force_ws(bool forceWS) noexcept { m_forceWS.store(forceWS, std::memory_order_relaxed); } -oscquery_client* oscquery_server_protocol::find_client(const connection_handler& hdl) +oscquery_client* +oscquery_server_protocol_base::find_client(const connection_handler& hdl) { lock_t lock(m_clientsMutex); @@ -511,7 +501,7 @@ static auto& querySetterMap() return map; } -void oscquery_server_protocol::add_node( +void oscquery_server_protocol_base::add_node( std::string_view parent_path, const string_map& parameters) { // /foo/bar/baz?ADD_NODE=tutu&VALUE="[hi]" @@ -540,25 +530,26 @@ void oscquery_server_protocol::add_node( m_device->on_add_node_requested(std::string(parent_path), address); } -void oscquery_server_protocol::remove_node( +void oscquery_server_protocol_base::remove_node( std::string_view path, const std::string& node) { m_device->on_remove_node_requested(std::string(path), node); } -void oscquery_server_protocol::rename_node( +void oscquery_server_protocol_base::rename_node( std::string_view path, const std::string& new_name) { m_device->on_rename_node_requested(std::string(path), new_name); } -void oscquery_server_protocol::process_raw_osc_data(const char* data, std::size_t sz) +void oscquery_server_protocol_base::process_raw_osc_data( + const char* data, std::size_t sz) { auto on_message = [this](auto&& msg) { this->on_osc_message(msg); }; ossia::net::osc_packet_processor{on_message}(data, sz); } -void oscquery_server_protocol::on_osc_message(const oscpack::ReceivedMessage& m) +void oscquery_server_protocol_base::on_osc_message(const oscpack::ReceivedMessage& m) try { // TODO @@ -577,7 +568,7 @@ catch(...) logger().error("oscquery_server_protocol::on_OSCMessage: error."); } -void oscquery_server_protocol::on_connectionOpen(const connection_handler& hdl) +void oscquery_server_protocol_base::on_connectionOpen(const connection_handler& hdl) try { auto con = m_websocketServer->impl().get_con_from_hdl(hdl); @@ -606,7 +597,7 @@ catch(...) logger().error("oscquery_server_protocol::on_connectionOpen: error."); } -void oscquery_server_protocol::on_connectionClosed(const connection_handler& hdl) +void oscquery_server_protocol_base::on_connectionClosed(const connection_handler& hdl) { { lock_t lock(m_clientsMutex); @@ -622,7 +613,7 @@ void oscquery_server_protocol::on_connectionClosed(const connection_handler& hdl onClientDisconnected(con->get_remote_endpoint()); } -void oscquery_server_protocol::on_nodeCreated(const net::node_base& n) +void oscquery_server_protocol_base::on_nodeCreated(const net::node_base& n) try { const auto mess = ossia::oscquery::json_writer::path_added(n); @@ -642,7 +633,7 @@ catch(...) logger().error("oscquery_server_protocol::on_nodeCreated: error."); } -void oscquery_server_protocol::on_nodeRemoved(const net::node_base& n) +void oscquery_server_protocol_base::on_nodeRemoved(const net::node_base& n) try { const auto mess = ossia::oscquery::json_writer::path_removed(n.osc_address()); @@ -662,12 +653,13 @@ catch(...) logger().error("oscquery_server_protocol::on_nodeRemoved: error."); } -void oscquery_server_protocol::on_parameterChanged(const ossia::net::parameter_base& p) +void oscquery_server_protocol_base::on_parameterChanged( + const ossia::net::parameter_base& p) { on_attributeChanged(p.get_node(), ossia::net::text_value_type()); } -void oscquery_server_protocol::on_attributeChanged( +void oscquery_server_protocol_base::on_attributeChanged( const net::node_base& n, std::string_view attr) try { @@ -687,7 +679,7 @@ catch(...) logger().error("oscquery_server_protocol::on_attributeChanged: error."); } -void oscquery_server_protocol::on_nodeRenamed( +void oscquery_server_protocol_base::on_nodeRenamed( const net::node_base& n, std::string oldname) try { @@ -733,7 +725,7 @@ catch(...) logger().error("oscquery_server_protocol::on_nodeRenamed: error."); } -void oscquery_server_protocol::update_zeroconf() +void oscquery_server_protocol_base::update_zeroconf() { try { @@ -748,23 +740,9 @@ void oscquery_server_protocol::update_zeroconf() { logger().error("oscquery_server_protocol::update_zeroconf: error."); } - - try - { - m_zeroconfServerOSC = net::make_zeroconf_server( - get_device().get_name(), "_osc._udp", "", m_oscPort, 0); - } - catch(const std::exception& e) - { - logger().error("oscquery_server_protocol::update_zeroconf: {}", e.what()); - } - catch(...) - { - logger().error("oscquery_server_protocol::update_zeroconf: error."); - } } -ossia::net::server_reply oscquery_server_protocol::on_text_ws_message( +ossia::net::server_reply oscquery_server_protocol_base::on_text_ws_message( const connection_handler& hdl, const std::string& message) { if(m_logger.inbound_logger) @@ -795,11 +773,80 @@ ossia::net::server_reply oscquery_server_protocol::on_text_ws_message( return {}; } -ossia::net::server_reply oscquery_server_protocol::on_binary_ws_message( - const oscquery_server_protocol::connection_handler& hdl, const std::string& message) +ossia::net::server_reply oscquery_server_protocol_base::on_binary_ws_message( + const oscquery_server_protocol_base::connection_handler& hdl, + const std::string& message) { // TODO here we know where the message comes from, can be used for id process_raw_osc_data(message.data(), message.size()); return {}; } + +oscquery_server_protocol::oscquery_server_protocol( + ossia::net::network_context_ptr ctx, uint16_t osc_port, uint16_t ws_port, + bool forceWS) + : oscquery_server_protocol_base{ctx, {ossia::net::udp_server_configuration{{{}, osc_port}}}, ws_port, forceWS} + , m_oscServer{std::make_unique( + ossia::net::inbound_socket_configuration{"0.0.0.0", osc_port}, + m_context->context)} +{ +} + +void oscquery_server_protocol::set_device(ossia::net::device_base& dev) +{ + oscquery_server_protocol_base::set_device(dev); + + m_oscServer->open(); + m_oscServer->receive( + [this](const char* data, std::size_t sz) { process_raw_osc_data(data, sz); }); +} + +void oscquery_server_protocol::update_zeroconf() +{ + try + { + int port = ossia::get(m_oscConf[0]).port; + m_zeroconfServerOSC + = net::make_zeroconf_server(get_device().get_name(), "_osc._udp", "", port, 0); + } + catch(const std::exception& e) + { + logger().error("oscquery_server_protocol::update_zeroconf: {}", e.what()); + } + catch(...) + { + logger().error("oscquery_server_protocol::update_zeroconf: error."); + } +} + +void oscquery_server_protocol::stop() +{ + try + { + m_oscServer->close(); + } + catch(...) + { + logger().error("Error when stopping osc server"); + } + oscquery_server_protocol_base::stop(); +} + +oscquery_server_protocol::~oscquery_server_protocol() +{ + if(m_device) + { + auto& dev = *m_device; + dev.on_node_created.disconnect<&oscquery_server_protocol::on_nodeCreated>(this); + dev.on_node_removing.disconnect<&oscquery_server_protocol::on_nodeRemoved>(this); + dev.on_parameter_created.disconnect<&oscquery_server_protocol::on_parameterChanged>( + this); + dev.on_parameter_removing.disconnect<&oscquery_server_protocol::on_parameterChanged>( + this); + dev.on_attribute_modified.disconnect<&oscquery_server_protocol::on_attributeChanged>( + this); + dev.on_node_renamed.disconnect<&oscquery_server_protocol::on_nodeRenamed>(this); + } + stop(); +} } diff --git a/src/ossia/protocols/oscquery/oscquery_server_asio.hpp b/src/ossia/protocols/oscquery/oscquery_server_asio.hpp index b5cb9e44093..3f5c746d501 100644 --- a/src/ossia/protocols/oscquery/oscquery_server_asio.hpp +++ b/src/ossia/protocols/oscquery/oscquery_server_asio.hpp @@ -1,4 +1,5 @@ #pragma once +#include #include #include #include @@ -7,8 +8,7 @@ #include #include #include - -#include +#include #include @@ -41,7 +41,7 @@ namespace oscquery_asio struct oscquery_client; using clients = std::vector>; //! Implementation of an oscquery server. -class OSSIA_EXPORT oscquery_server_protocol final : public ossia::net::protocol_base +class OSSIA_EXPORT oscquery_server_protocol_base : public ossia::net::protocol_base { friend struct oscquery_client; friend class ossia::oscquery::query_answerer; @@ -50,10 +50,17 @@ class OSSIA_EXPORT oscquery_server_protocol final : public ossia::net::protocol_ public: using connection_handler = std::weak_ptr; - oscquery_server_protocol( - ossia::net::network_context_ptr ctx, uint16_t osc_port = 1234, - uint16_t ws_port = 5678, bool forceWS = false); - ~oscquery_server_protocol() override; + + // Use oscquery_server_protocol_with_osc + explicit oscquery_server_protocol_base( + ossia::net::network_context_ptr ctx, uint16_t, uint16_t) + = delete; + + oscquery_server_protocol_base( + ossia::net::network_context_ptr ctx, + const std::vector& conf, uint16_t ws_port, + bool forceWS); + ~oscquery_server_protocol_base() override; bool pull(net::parameter_base&) override; std::future pull_async(net::parameter_base&) override; @@ -73,17 +80,27 @@ class OSSIA_EXPORT oscquery_server_protocol final : public ossia::net::protocol_ void stop() override; ossia::net::device_base& get_device() const noexcept { return *m_device; } - int get_osc_port() const noexcept { return m_oscPort; } - int get_ws_port() const noexcept { return m_wsPort; } bool force_ws() const noexcept { return m_forceWS.load(std::memory_order_relaxed); } void set_force_ws(bool forceWS) noexcept; + const std::vector& + get_transports() const noexcept + { + return m_oscConf; + } + Nano::Signal onClientConnected; Nano::Signal onClientDisconnected; -private: +protected: + explicit oscquery_server_protocol_base(ossia::net::network_context_ptr ctx) = delete; + + // OSC callback + void on_osc_message(const oscpack::ReceivedMessage& m); + void process_raw_osc_data(const char* data, std::size_t sz); + // List of connected clients oscquery_client* find_client(const connection_handler& hdl); @@ -91,10 +108,6 @@ class OSSIA_EXPORT oscquery_server_protocol final : public ossia::net::protocol_ void remove_node(std::string_view path, const std::string& node); void rename_node(std::string_view node, const std::string& new_name); - // OSC callback - void on_osc_message(const oscpack::ReceivedMessage& m); - void process_raw_osc_data(const char* data, std::size_t sz); - // Websocket callbacks void on_connectionOpen(const connection_handler& hdl); void on_connectionClosed(const connection_handler& hdl); @@ -121,12 +134,12 @@ class OSSIA_EXPORT oscquery_server_protocol final : public ossia::net::protocol_ ossia::net::network_context_ptr m_context; - struct osc_receiver_impl; - std::unique_ptr m_oscServer; std::unique_ptr m_websocketServer; net::zeroconf_server m_zeroconfServerWS; - net::zeroconf_server m_zeroconfServerOSC; + + // What we expose over OSC + std::vector m_oscConf; // Listening status of the local software net::listened_parameters m_listening; @@ -141,11 +154,29 @@ class OSSIA_EXPORT oscquery_server_protocol final : public ossia::net::protocol_ mutex_t m_clientsMutex; // The local ports - uint16_t m_oscPort{}; uint16_t m_wsPort{}; // Will only send changes through WS std::atomic_bool m_forceWS{}; }; + +class OSSIA_EXPORT oscquery_server_protocol : public oscquery_server_protocol_base +{ +public: + struct osc_receiver_impl; + explicit oscquery_server_protocol( + ossia::net::network_context_ptr ctx, uint16_t osc_port = 1234, + uint16_t ws_port = 5678, bool forceWS = false); + ~oscquery_server_protocol(); + + void update_zeroconf(); + void set_device(net::device_base& dev) override; + void stop() override; + +private: + std::unique_ptr m_oscServer; + + net::zeroconf_server m_zeroconfServerOSC; +}; } } diff --git a/tests/Network/MultiplexTest.cpp b/tests/Network/MultiplexTest.cpp index 1d8bfba2b55..ca4b4ea3f5f 100644 --- a/tests/Network/MultiplexTest.cpp +++ b/tests/Network/MultiplexTest.cpp @@ -35,7 +35,7 @@ TEST_CASE("test_oscquery_osc_out", "test_oscquery_osc_out") .version = conf::OSC1_1, .transport = ossia::net::udp_configuration{ {.local = std::nullopt, - .remote = ossia::net::send_socket_configuration{{"127.0.0.1", shared}}}}}); + .remote = ossia::net::outbound_socket_configuration{"127.0.0.1", shared}}}}); auto oscquery = std::make_unique(ctx); auto multiplex = std::make_unique(); @@ -45,8 +45,9 @@ TEST_CASE("test_oscquery_osc_out", "test_oscquery_osc_out") device.set_echo(true); - const auto udp_conf = ossia::net:: - udp_configuration{{.local = ossia::net::receive_socket_configuration{{"0.0.0.0", shared}}, .remote = std::nullopt}}; + const auto udp_conf = ossia::net::udp_configuration{ + {.local = ossia::net::inbound_socket_configuration{"0.0.0.0", shared}, + .remote = std::nullopt}}; ossia::net::generic_device remote{ ossia::net::make_osc_protocol( ctx, @@ -109,7 +110,7 @@ TEST_CASE("test_oscquery_osc_large", "test_oscquery_osc_large") .version = conf::OSC1_1, .transport = ossia::net::udp_configuration{ {.local = std::nullopt, - .remote = ossia::net::send_socket_configuration{{"127.0.0.1", shared}}}}}); + .remote = ossia::net::outbound_socket_configuration{"127.0.0.1", shared}}}}); auto oscquery = std::make_unique(ctx); auto multiplex = std::make_unique(); @@ -141,7 +142,7 @@ TEST_CASE("test_multiplex_remove", "test_multiplex_remove") .version = conf::OSC1_1, .transport = ossia::net::udp_configuration{ {.local = std::nullopt, - .remote = ossia::net::send_socket_configuration{{"127.0.0.1", shared}}}}}); + .remote = ossia::net::outbound_socket_configuration{"127.0.0.1", shared}}}}); auto oscquery = std::make_unique(ctx); auto multiplex = std::make_unique(); @@ -154,8 +155,9 @@ TEST_CASE("test_multiplex_remove", "test_multiplex_remove") device.set_echo(true); - const auto udp_conf = ossia::net:: - udp_configuration{{.local = ossia::net::receive_socket_configuration{{"0.0.0.0", shared}}, .remote = std::nullopt}}; + const auto udp_conf = ossia::net::udp_configuration{ + {.local = ossia::net::inbound_socket_configuration{"0.0.0.0", shared}, + .remote = std::nullopt}}; ossia::net::generic_device remote{ ossia::net::make_osc_protocol( ctx, @@ -195,13 +197,13 @@ TEST_CASE("test_multiplex_remove", "test_multiplex_remove") //create a new OSC connection using conf = ossia::net::osc_protocol_configuration; auto o = ossia::net::make_osc_protocol( - ctx, - {.mode = conf::HOST, - .version = conf::OSC1_1, - .framing = conf::SLIP, - .transport = ossia::net::udp_configuration{ - {.local = std::nullopt, - .remote = ossia::net::send_socket_configuration{{"127.0.0.1", shared}}}}}); + ctx, {.mode = conf::HOST, + .version = conf::OSC1_1, + .framing = conf::SLIP, + .transport = ossia::net::udp_configuration{ + {.local = std::nullopt, + .remote = ossia::net::outbound_socket_configuration{ + {"127.0.0.1", shared}}}}}); proto->expose_to(std::move(o)); } diff --git a/tests/Network/OSCQueryTest.cpp b/tests/Network/OSCQueryTest.cpp index ec231db3600..0c73c1940f6 100644 --- a/tests/Network/OSCQueryTest.cpp +++ b/tests/Network/OSCQueryTest.cpp @@ -1168,8 +1168,7 @@ TEST_CASE("test_oscquery_osc_to_ws", "test_oscquery_osc_to_ws") .version = conf::OSC1_1, .transport = ossia::net::udp_configuration{ {.local = std::nullopt, - .remote = ossia::net::send_socket_configuration{{"127.0.0.1", shared}}}}}); - + .remote = ossia::net::outbound_socket_configuration{"127.0.0.1", shared}}}}); //server change goes to mirror server_param->push_value(2.0f); diff --git a/tests/Network/OSC_TCP_SizeTest.cpp b/tests/Network/OSC_TCP_SizeTest.cpp index 1399d018261..44941dfbb5c 100644 --- a/tests/Network/OSC_TCP_SizeTest.cpp +++ b/tests/Network/OSC_TCP_SizeTest.cpp @@ -17,7 +17,7 @@ auto make_client(ossia::net::network_context_ptr ctx) using conf = ossia::net::osc_protocol_configuration; auto proto = ossia::net::make_osc_protocol( ctx, {conf::MIRROR, conf::OSC1_1, conf::SIZE_PREFIX, - ossia::net::tcp_configuration{{"127.0.0.1", 1234}}}); + ossia::net::tcp_client_configuration{"127.0.0.1", 1234}}); return proto; } @@ -26,7 +26,7 @@ auto make_server(ossia::net::network_context_ptr ctx) using conf = ossia::net::osc_protocol_configuration; auto proto = ossia::net::make_osc_protocol( ctx, {conf::HOST, conf::OSC1_1, conf::SIZE_PREFIX, - ossia::net::tcp_configuration{{"0.0.0.0", 1234}}}); + ossia::net::tcp_server_configuration{"0.0.0.0", 1234}}); return proto; } diff --git a/tests/Network/OSC_TCP_SlipTest.cpp b/tests/Network/OSC_TCP_SlipTest.cpp index 0e727d45782..7c223350cf9 100644 --- a/tests/Network/OSC_TCP_SlipTest.cpp +++ b/tests/Network/OSC_TCP_SlipTest.cpp @@ -17,7 +17,7 @@ auto make_client(ossia::net::network_context_ptr ctx) using conf = ossia::net::osc_protocol_configuration; return ossia::net::make_osc_protocol( ctx, {conf::MIRROR, conf::OSC1_1, conf::SLIP, - ossia::net::tcp_configuration{{"127.0.0.1", 1234}}}); + ossia::net::tcp_client_configuration{"127.0.0.1", 1234}}); } auto make_server(ossia::net::network_context_ptr ctx) @@ -25,7 +25,7 @@ auto make_server(ossia::net::network_context_ptr ctx) using conf = ossia::net::osc_protocol_configuration; return ossia::net::make_osc_protocol( ctx, {conf::HOST, conf::OSC1_1, conf::SLIP, - ossia::net::tcp_configuration{"0.0.0.0", 1234}}); + ossia::net::tcp_server_configuration{"0.0.0.0", 1234}}); } TEST_CASE("test_comm_osc_tcp_server_client", "test_comm_osc_tcp_server_client") diff --git a/tests/Network/OSC_UDPTest.cpp b/tests/Network/OSC_UDPTest.cpp index 51b36e0937f..7b6a5086179 100644 --- a/tests/Network/OSC_UDPTest.cpp +++ b/tests/Network/OSC_UDPTest.cpp @@ -14,12 +14,12 @@ using namespace ossia; #include using conf = ossia::net::udp_configuration; -using recv_sock = ossia::net::receive_socket_configuration; -using send_sock = ossia::net::send_socket_configuration; +using recv_sock = ossia::net::inbound_socket_configuration; +using send_sock = ossia::net::outbound_socket_configuration; static const conf server_conf - = conf{{recv_sock{{"0.0.0.0", 4478}}, send_sock{{"127.0.0.1", 9875}}}}; + = conf{{recv_sock{"0.0.0.0", 4478}, send_sock{"127.0.0.1", 9875}}}; static const conf client_conf - = conf{{recv_sock{{"0.0.0.0", 9875}}, send_sock{{"127.0.0.1", 4478}}}}; + = conf{{recv_sock{"0.0.0.0", 9875}, send_sock{"127.0.0.1", 4478}}}; TEST_CASE("test_comm_osc_udp_simple", "test_comm_osc_udp_simple") { using namespace ossia::net;