diff options
Diffstat (limited to 'daemon/src/connection_manager.cpp')
-rw-r--r-- | daemon/src/connection_manager.cpp | 52 |
1 files changed, 45 insertions, 7 deletions
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 <rtmidi/RtMidi.h> #include <iostream> -#include <chrono> +#include <map> 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<Device_Connection>(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<std::size_t, std::string> 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); + } } } } |