Files
qt5-legatus-legacy/Lts/Services/ParticipantManagement/UasHandling/uas_handler.cpp
T
2026-08-13 18:33:10 +02:00

298 lines
9.3 KiB
C++
Executable File

/**
* 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 <ngldb/db_service_handler.h>
#include "main_handler.h"
#include "ParticipantHandling/participant.h"
#include <QJsonDocument>
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<Database::PpmUas> 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 &currentUas : 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