From 5a40f51085e2132bf91eccdd37e1a8dabe588efd Mon Sep 17 00:00:00 2001 From: Eddy Pedroni Date: Thu, 24 Jul 2025 10:34:13 +0200 Subject: Rough implementation of autoconnect --- daemon/src/connection_manager.cpp | 52 +++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 7 deletions(-) (limited to 'daemon/src/connection_manager.cpp') diff --git a/daemon/src/connection_manager.cpp b/daemon/src/connection_manager.cpp index ac4c6cb..faad061 100644 --- a/daemon/src/connection_manager.cpp +++ b/daemon/src/connection_manager.cpp @@ -3,9 +3,10 @@ #include "device_connection.h" #include "udevw/include/udevw.hpp" +#include #include -#include +#include namespace midi_router { @@ -36,8 +37,8 @@ Connection_Manager::Connection_Manager(Device_Map const & device_map, Submitter for (auto const & [name, id] : device_map) { m_connections[id] = std::make_unique(id, name, submitter, callback); - m_connections[id]->open(); } + refresh_devices(true, false); } Connection_Manager::~Connection_Manager() = default; @@ -51,13 +52,50 @@ Connection_Manager::get_sender(Device_Id const & device) const void Connection_Manager::detect_devices() { - while (true) + auto udev = udevw::Udev::create(); + auto monitor = udevw::Monitor::create_from_netlink(udev, "udev"); + monitor.filter_add_match_subsystem("sound"); // devtype = nullptr implied + monitor.enable_receiving(); + + int fd = monitor.get_fd(); + for (;;) { + fd_set fds; + FD_ZERO(&fds); + FD_SET(fd, &fds); + + if (select(fd +1, &fds, nullptr, nullptr, nullptr) > 0 && FD_ISSET(fd, &fds)) { + auto device = monitor.receive_device(); + + auto action = device.get_action(); + if (!action) continue; + + bool add = *action == "add"; + bool remove = *action == "remove"; + refresh_devices(add, remove); + } + } +} + +void +Connection_Manager::refresh_devices([[maybe_unused]] bool add, [[maybe_unused]] bool remove) +{ + // collect currently connected devices + RtMidiIn enumerator {}; + std::map port_map {}; + for (std::size_t i = 0; i < enumerator.getPortCount(); ++i) + { + std::string name = enumerator.getPortName(i); + port_map[i] = name; + } + + for (auto & [id, device] : m_connections) { - std::cout << "Polling for devices\n"; - std::this_thread::sleep_for(std::chrono::seconds(1)); - for (auto && [id, connection] : m_connections) + for (auto const & [port, name] : port_map) { - connection->open(); + if (name.contains(device->device_name)) + { + device->reconnect(port); + } } } } -- cgit v1.2.3