#include "ReceiveManager.hpp" #include #include #include "behavior/events/audio/AudioEvent.hpp" #include "behavior/events/info/InfoEvent.hpp" #include "behavior/events/pong/PongEvent.hpp" #include "behavior/events/search/SearchEvent.hpp" namespace drp::managers { ReceiveManager::ReceiveManager(const std::shared_ptr& context) { this->context = context; // register the different events type this->registry = { {event::EventType::PONG, std::make_shared()}, {event::EventType::SEARCH, std::make_shared()}, {event::EventType::INFO, std::make_shared()}, {event::EventType::AUDIO, std::make_shared()}, }; } void ReceiveManager::run() const { // prepare space for the sender address sockaddr_storage fromAddress {}; socklen_t fromAddressLength = sizeof(fromAddress); std::array buffer {}; // receive new data const ssize_t size = recvfrom( this->context->socket, buffer.data(), buffer.size(), 0, reinterpret_cast(&fromAddress), &fromAddressLength ); if (size == -1) throw std::runtime_error("[Receiver] Could not receive the packet: " + std::string(strerror(errno))); // deserialize the packet std::vector data(buffer.begin(), buffer.end()); const auto packet = drp::packet::base::Packet::deserialize(data); // if the packet channel is neither 0 (all) nor the current one, ignore it if (packet.channel != 0 && packet.channel != this->context->me.channel) return; // decrypt the packet // TODO(Faraphel): handle exception ? drp::packet::base::PacketContent packetContent = packet.getContent(*this->context); // look for a saved peer with the same address auto remotePeer = std::ranges::find_if( this->context->remotePeers, [&](const std::shared_ptr& remotePeer) { return remotePeer->addressLength == fromAddressLength and std::memcmp(&fromAddress, &remotePeer->address, fromAddressLength) == 0; } ); // if found, update the latest connection date if (remotePeer != this->context->remotePeers.end()) (*remotePeer)->latestConnection = std::chrono::high_resolution_clock::now(); // get the corresponding event class std::shared_ptr event; try { event = this->registry.at(packetContent.eventType); } catch (const std::out_of_range& exception) { std::cerr << "[Receiver] Unsupported event type: " << std::to_string(static_cast(packetContent.eventType)) << std::endl; return; } std::cout << "[Receiver] handling event: " << std::to_string(static_cast(packetContent.eventType)) << std::endl; // ask the event class to handle the event try { event->handle( *this->context, packetContent.data, fromAddress, fromAddressLength ); } catch (const std::exception& exception) { std::cerr << "[Receiver] Unhandled exception: " << exception.what() << std::endl; } } void ReceiveManager::loop() const { while (true) this->run(); } }