/** * The UasHandler class manages all Uas related function topics and holds classes for * further Uas data. * $Id$ * $HeadURL$ * $Author$ * Created by Hannes Fritsche, ESZS, 2025-04-08 */ #include "uas_handler.h" #include "uas.h" #include #include "main_handler.h" #include "ParticipantHandling/participant.h" #include namespace ParticipantManagement { namespace UasHandling { //------------------------------------------------------------------------------------------ UasHandler::UasHandler(MainHandler *mainHandler) : QObject() , CreateModifyUasRequestHandler(mainHandler->exAnyFts()) , RemoveUasRequestHandler(mainHandler->exAnyFts()) , m_mainHandler(mainHandler) , m_logger(getLogger("UasHandler")) { m_mainHandler->exAnyFts()->enableCreateModifyUas(); m_mainHandler->exAnyFts()->enableRemoveUas(); } //------------------------------------------------------------------------------------------ UasHandler::~UasHandler() { qDeleteAll(m_uass); } //------------------------------------------------------------------------------------------ bool UasHandler::init() { qDeleteAll(m_uass); m_uass.clear(); m_mainHandler->exAnyDts()->enableUAS(); QVector uasVec; // read parties from db if (!m_mainHandler->db()->select(uasVec)) { ERROR_LOG(m_logger) << "Error while reading Uas data from database"; return false; } for (const Database::PpmUas ¤tUas : qAsConst(uasVec)) { UasHandling::Uas *newUas = new UasHandling::Uas(currentUas); m_uass.insert(currentUas.id, newUas); m_mainHandler->exAnyDts()->publish(newUas->toDdsUas()); } //now the exercise part m_exmDtc = ExerciseManagement::Interface::Dtc::create(m_mainHandler->dds()); connect(m_exmDtc.get(), &ExerciseManagement::Interface::Dtc::exerciseChanged, this, &UasHandler::onExerciseChanged); if (!m_exmDtc->enableExercise()) { ERROR_LOG(m_logger) << "Could not enable Topic 'Exercise' of EXM DTC"; return false; } //now connect to ppm connect(m_mainHandler->ddsHandler()->dtc().get(), &Interface::Dtc::uASRadioLinkConnectionStatusChanged, this , &UasHandler::onUASRadioLinkConnectionStatusChanged); m_mainHandler->ddsHandler()->dtc()->enableUASRadioLinkConnectionStatus(); return true; } //------------------------------------------------------------------------------------------ void UasHandler::onCreateModifyUasRequest(const rti::core::SampleIdentity &cookie, const CreateModifyUasRequest &request) { Core::FunctionReplyObject reply = request.id() == 0 ? createUas(request) : modifyUas(request); m_mainHandler->exAnyFts()->createModifyUasReply(cookie, reply); } void UasHandler::onRemoveUasRequest(const rti::core::SampleIdentity &cookie, const RemoveUasRequest &request) { DEBUG_LOG(m_logger) << "onRemoveUasRequest: " << request; auto ret = removeUas(request); if (ret.error()) WARNING_LOG(m_logger) << ret(); m_mainHandler->exAnyFts()->removeUasReply(cookie, ret); } Core::FunctionReplyObject UasHandler::removeUas(const RemoveUasRequest &request) { DEBUG_LOG(m_logger) << "onRemoveUasRequest " << request; if (request.id() < 0) return Core::FunctionReplyObject(tr_lts("dds", "Got request to delete an UAS, but no valid UAS id to delete")); UasHandling::Uas *uasToDelete = m_uass.value(request.id()); if (!uasToDelete) return Core::FunctionReplyObject(tr_lts("dds", "Could not delete UAS with id %1, because no UAS with that id exists")) .arg(request.id()); if (uasToDelete->participantId() > 0) return Core::FunctionReplyObject(tr_lts("dds", "Not possible to delete a UAS in use")); DEBUG_LOG(m_logger) << "Removing UAS with ID " << request.id(); return removeUas(uasToDelete); } //------------------------------------------------------------------------------------------ Core::FunctionReplyObject UasHandler::removeUas(UasHandling::Uas *uasToDelete) { const int uasId = uasToDelete->id(); // delete from db if (!m_mainHandler->db()->removePpmUas(uasId)) return Core::FunctionReplyObject(tr_lts("dds", "Error removing UAS with id %1 from database")).arg(uasId); // delete from dds m_mainHandler->exAnyDts()->removeUASByKey(uasId); // delete from map m_uass.remove(uasId); delete uasToDelete; return Core::FunctionReplyObject(uasId); } //------------------------------------------------------------------------------------------ Core::FunctionReplyObject UasHandler::createUas(const CreateModifyUasRequest &request) { DEBUG_LOG(m_logger) << LOGFUNCTION; // cant check here as we dont have access to all party participants /* if (request.participantId() > 0 && !isUasParticipant(request.participantId())) { QString error = QStringLiteral("Participant with id %1 is no Uas participant.").arg(request.participantId()); ERROR_LOG(m_logger) << error; return Core::FunctionReplyObject(error.toStdString().c_str()); }*/ Database::PpmUas dbUas; dbUas.deviceIdentifier = QString::fromStdString(request.deviceIdentifier()); dbUas.uasStateId = ProjectDataManagement::UasState::Undefined; dbUas.participantId = request.participantId(); dbUas.exerciseId = request.exerciseId(); dbUas.hostname = QString::fromStdString(request.hostname()); dbUas.hostport = request.hostport(); dbUas.useTcp = request.useTcp(); if (hostNameHostPortExists(dbUas.hostname, dbUas.hostport, -1)) return Core::FunctionReplyObject(tr_lts("dds", "Hostname with Port %1:%2 already exists")) .arg(dbUas.hostname).arg(dbUas.hostport); if (!m_mainHandler->db()->insert(dbUas)) { QString error = QStringLiteral("Could not insert Uas into database"); ERROR_LOG(m_logger) << error; return Core::FunctionReplyObject(error.toStdString().c_str()); } UasHandling::Uas *newUas = new UasHandling::Uas(dbUas); m_uass.insert(newUas->id(), newUas); m_mainHandler->exAnyDts()->publish(newUas->toDdsUas()); return Core::FunctionReplyObject(); } //------------------------------------------------------------------------------------------ Core::FunctionReplyObject UasHandler::modifyUas(const CreateModifyUasRequest &request) { if (!m_uass.contains(request.id())) { QString error = QStringLiteral("Uas topic with id %1 not present. Not possible to modify it.").arg(request.id()); ERROR_LOG(m_logger) << error; return Core::FunctionReplyObject(error.toStdString().c_str()); } Uas *uas = m_uass.value(request.id()); // Check if Hostname and Hostport already existing if (hostNameHostPortExists(QString::fromStdString(request.hostname()), request.hostport(), uas->id())) return Core::FunctionReplyObject(tr_lts("dds", "Hostname with Port %1:%2 already exists")) .arg(request.hostname()).arg(request.hostport()); if (!uas->hasChanges(request)) { QString error = QStringLiteral("There are no changes in modify request."); ERROR_LOG(m_logger) << error; return Core::FunctionReplyObject(error.toStdString().c_str()); } //can't check here)) /* if (request.participantId() > 0 && !isUasParticipant(request.participantId())) { QString error = QStringLiteral("Participant with id %1 is no Uas participant.").arg(request.participantId()); ERROR_LOG(m_logger) << error; return Core::FunctionReplyObject(error.toStdString().c_str()); } */ m_mainHandler->exAnyDts()->publish(uas->toDdsUas()); m_mainHandler->db()->update(uas->toDbUas()); return Core::FunctionReplyObject(); } //------------------------------------------------------------------------------------------ bool UasHandler::isUasParticipant(int participantId) const { const ParticipantManagement::ParticipantHandling::Participant *PARTICIPANT = m_mainHandler->participantHandler()->participantById(participantId); if (PARTICIPANT == nullptr) { WARNING_LOG(m_logger) << "Got invalid participantId " << participantId; return false; } const int TYPE_ID = PARTICIPANT->typeId(); return m_mainHandler->ddsHandler()->dtc()->isTypeUas(TYPE_ID); } void UasHandler::onExerciseChanged(const ExerciseManagement::Exercise &data, DataModification mod) { Q_UNUSED(mod) if (data.state() != ExerciseManagement::ExerciseState::Stopped && data.state() != ExerciseManagement::ExerciseState::Terminated && data.state() != ExerciseManagement::ExerciseState::Unknown ) return; //Unlink for (auto uas : m_uass) { auto uasData = uas->toDdsUas(); if (uasData.exerciseId() != data.id()) continue; uas->unlinkUas(); m_mainHandler->exAnyDts()->publish(uas->toDdsUas()); m_mainHandler->db()->update(uas->toDbUas()); } } void UasHandler::onUASRadioLinkConnectionStatusChanged(const UASRadioLinkConnectionStatus &data, DataModification mod) { if (data.id() <= 0) return; if (!m_uass.contains(data.id())) return; auto uas = m_uass.value(data.id()); if (mod == DataModification::eRemoved) uas->setState(ProjectDataManagement::UasState::Undefined); else uas->setState(data.uasState()); m_mainHandler->exAnyDts()->publish(uas->toDdsUas()); m_mainHandler->db()->update(uas->toDbUas()); } bool UasHandler::hostNameHostPortExists(const QString &hostname, int hostport, int uasId) { for (Uas *uas : qAsConst(m_uass)) { if (uas->id() == uasId) continue; if (uas->compareHostname(hostname) && uas->compareHostPort(hostport)) return true; } return false; } } // namespace UasHandling } // namespace ParticipantManagement