#include "ovCMessagingServer.h" #include "ovCMessagingImpl.hpp" namespace Communication { MessagingServer::~MessagingServer() { this->close(); m_Server->release(); } bool MessagingServer::accept() { this->reset(); if (this->isConnected()) { // A connection is already done to a client this->setLastError(Socket_ClientAlreadyConnected); return false; } if (!m_Server->isReadyToReceive()) { this->setLastError(Socket_NoIncomingClientConnection); return false; } m_Client = m_Server->accept(); if (m_Client == nullptr) { this->setLastError(Socket_NoIncomingClientConnection); return false; } this->setConnection(m_Client); this->startSyncing(); if (!impl->m_ConnectionID.empty()) { // The server has to verify that the client is the one that is waited. So the server wait the authentication packet. const std::chrono::time_point startClock = std::chrono::system_clock::now(); std::string connectionID; uint64_t id = 0; bool isAuthReceived = false; while (std::chrono::duration_cast(std::chrono::system_clock::now() - startClock).count() < 10) { if (this->popAuthentication(id, connectionID)) { isAuthReceived = true; if (connectionID != impl->m_ConnectionID) { this->pushError(Error_AuthenticationFail, id); this->close(); this->setLastError(BadAuthenticationReceived); return false; } break; } std::this_thread::sleep_for(std::chrono::milliseconds(10)); } if (!isAuthReceived) { this->pushError(Error_AuthenticationRequested, id); this->close(); this->setLastError(NoAuthenticationReceived); return false; } } if (!this->pushMessage(CommunicationProtocolVersionMessage(s_CommunicationProtocol_MajorVersion, s_CommunicationProtocol_MinorVersion))) { // Error set in the function const ELibraryError error = this->getLastError(); this->close(); this->setLastError(error); return false; } if (!this->pushMessage(impl->m_BoxDesc)) { // Error set in the function const ELibraryError error = this->getLastError(); this->close(); this->setLastError(error); return false; } return true; } bool MessagingServer::close() { this->pushMessage(EndMessage()); this->stopSyncing(); bool errorRaised = false; if (m_Client != nullptr) { if (!m_Client->close()) { errorRaised = true; this->setLastError(Socket_FailedToCloseConnection); } m_Client->release(); m_Client = nullptr; } if (!m_Server->close()) { this->setLastError(Socket_FailedToCloseConnection); errorRaised = true; } return !errorRaised; } bool MessagingServer::addParameter(const uint64_t id, const size_t type, const std::string& name, const std::string& value) const { return impl->m_BoxDesc.addParameter(id, type, name, value); } bool MessagingServer::addInput(const uint64_t id, const size_t type, const std::string& name) const { return impl->m_BoxDesc.addInput(id, type, name); } bool MessagingServer::addOutput(const uint64_t id, const size_t type, const std::string& name) const { return impl->m_BoxDesc.addOutput(id, type, name); } bool MessagingServer::popLog(uint64_t& packetId, ELogLevel& type, std::string& message) { return CMessaging::popLog(packetId, type, message); } bool MessagingServer::popEBML(uint64_t& packetId, size_t& index, uint64_t& startTime, uint64_t& endTime, std::shared_ptr>& ebml) { return CMessaging::popEBML(packetId, index, startTime, endTime, ebml); } bool MessagingServer::pushError(const EError error, const uint64_t guiltyId) const { return this->pushMessage(ErrorMessage(error, guiltyId)); } bool MessagingServer::pushEBML(const size_t index, const uint64_t startTime, const uint64_t endTime, const std::shared_ptr>& ebml) const { return this->pushMessage(EBMLMessage(index, startTime, endTime, ebml)); } } // namespace Communication