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

239 lines
7.7 KiB
C++
Executable File

/**
* Handler emergency call from tetra radio
* $Id$
* $HeadURL$
* $Author$
* Created by Astrid Müller, SGAS, 2018-02-23
*/
#include "handler_emergency_call.h"
#include "initialization.h"
#include "handler_configure_alarms.h"
#include "object_emergency_call.h"
#include "alm_db.h"
#include <DDS/DTS/generic_dts.h>
#include <QJsonObject>
#include <QJsonDocument>
#include <QDebug>
namespace AlarmManagement
{
HandlerEmergencyCall::HandlerEmergencyCall(const std::shared_ptr<HandlerConfigureAlarms> &configAlarmHandler,
Initialization *mainHandler)
: QObject()
, EmergencyCallAcknowledgeRequestHandler(mainHandler->dds()->ftsAlm())
, m_mainHandler(mainHandler)
, m_configAlarmHandler(configAlarmHandler)
, m_logger(getLogger("HandlerEmergencyCall"))
{
}
HandlerEmergencyCall::~HandlerEmergencyCall()
{
}
bool HandlerEmergencyCall::init()
{
INFO_LOG(m_logger) << "Start HandlerEmergencyCall.";
auto dtcTab = m_mainHandler->dds()->dtcTab();
connect(dtcTab.get(), &TrainingAreaBase::Interface::Dtc::emergencyCallChanged,
this, &HandlerEmergencyCall::onEmergencyCallChanged);
connect(m_mainHandler->dds()->dtcAlm().get(), &AlarmManagement::Interface::Dtc::acknowledgeSOSInAllExercisesChanged,
this, &HandlerEmergencyCall::onAcknowledgeSOSInExercises);
// create and init Object
bool bRet = true;
auto cbEmergencyCall = [this, &bRet](const Database::AlmEmergencyCall &data)
{
WARNING_LOG(m_logger)<<" ALM_EMERGENCY " << "Reading from DB AlmEmergencyCall with id = " << data.id;
if (!this->isExerciseValidForEmergencyCall() && !data.expired)
return;
ObjectEmergencyCall *ifs(new ObjectEmergencyCall(m_mainHandler));
Core::FunctionReplyObject ret = ifs->createObject(data);
if (ret.error())
{
delete ifs;
ERROR_LOG(m_logger) << ret();
bRet = false;
return;
}
m_emergencyObjMap.insert(ifs->getId(), ifs);
};
if (!m_mainHandler->db()->select(cbEmergencyCall) || !bRet)
{
ERROR_LOG(m_logger) <<"Error reading data from database 'alm_emergency_call!";
return false;
}
return true;
}
bool HandlerEmergencyCall::createEmergencyCallObject(const AlarmManagement::AlmEmergencyCall &data)
{
if (!isNewEmergencyCall(data) || std::isnan(data.position().lat()))
return false;
Database::AlmEmergencyCall newData;
newData.id = 0;
newData.operatorId = 0;
newData.sampleTime = data.sampleTime();
newData.incomingTime = data.sampleTime();
newData.expired = false;
newData.issi = data.issi();
newData.position.setX(data.position().lon());
newData.position.setY(data.position().lat());
newData.comment = QStringLiteral("");
newData.name = QStringLiteral("");
ObjectEmergencyCall *ifs(new ObjectEmergencyCall(m_mainHandler, this));
Core::FunctionReplyObject ret = ifs->createObject(newData);
if (ret.error())
{
delete ifs;
ERROR_LOG(m_logger)<< ret();
return false;
}
WARNING_LOG(m_logger)<< "Entry createEmergencyCallObject in the DB id: "<<ifs->getData().id<<" issi: "<<ifs->getData().issi<<" expired: "<<ifs->getData().expired;
m_emergencyObjMap.insert(ifs->getId(), ifs);
return true;
}
void HandlerEmergencyCall::onEmergencyCallAcknowledgeRequest(const rti::core::SampleIdentity &cookie, const EmergencyCallAcknowledgeRequest &request)
{
WARNING_LOG(m_logger) << "[onEmergencyCallAcknowledgeRequest] request: " << request;
Core::FunctionReplyObject ret = emergencyCallAcknowledgeRequest(request);
if (ret.error())
WARNING_LOG(m_logger)<< ret();
if (request.expired())
{
AcknowledgeSOSInAllExercises ackInEx;
ackInEx.id(request.id());
ackInEx.timestamp(request.timestamp());
ackInEx.incomingTime(request.incomingTime());
ackInEx.name(request.name());
ackInEx.issi(request.issi());
ackInEx.operatorId(request.operatorId());
ackInEx.comment(request.comment());
ackInEx.expired(request.expired());
WARNING_LOG(m_logger) << "onEmergencyCallAcknowledgeRequest: issi: "<<ackInEx.issi();
m_mainHandler->dds()->publishSOS()->write(ackInEx);
}
m_mainHandler->dds()->ftsAlm()->emergencyCallAcknowledgeReply(cookie,ret);
}
Core::FunctionReplyObject HandlerEmergencyCall::emergencyCallAcknowledgeRequest(const EmergencyCallAcknowledgeRequest &request)
{
ObjectEmergencyCall *ifs = nullptr;
for(auto _ifs : qAsConst(m_emergencyObjMap))
{
auto data = _ifs->getData();
if (data.issi == request.issi()
&& data.incomingTime == request.incomingTime()
&& !data.expired)
{
ifs = _ifs;
break;
}
}
if (ifs == nullptr)
{
WARNING_LOG(m_logger)<<" Couldn't acknowledge SOS with issi: " <<request.issi()<< ": already acknowledged or issi doesn't exist.";
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "already acknowledged or issi(%1) couldn't be found")).arg(request.issi());
}
if (ifs->getData().expired) // if already expired do nothing
{
WARNING_LOG(m_logger) << "SOS Already expired do nothing";
return Core::FunctionReplyObject(ifs->getData().id);
}
WARNING_LOG(m_logger) << "emergencyCallAcknowledgeRequest: issi found!: "<<request.issi()<<" ifs->state: "<<ifs->getData().expired;
Database::AlmEmergencyCall newData(ifs->getData());
newData.expired = true;
newData.issi = request.issi();
newData.sampleTime = request.timestamp();
newData.deleted = request.timestamp();
newData.operatorId = request.operatorId();
newData.name = QString::fromStdString(request.name());
newData.comment = QString::fromStdString(request.comment());
return ifs->updateObject(newData);
}
bool HandlerEmergencyCall::isExerciseValidForEmergencyCall() const
{
const auto &exmDtc = m_mainHandler->dds()->dtcExm();
exmDtc->waitForHistoricalDataExercise();
const ExerciseManagement::Exercise exercise = exmDtc->exercise(m_mainHandler->dds()->exerciseId());
if (exercise.state() != ExerciseManagement::ExerciseState::Started
&& exercise.state() != ExerciseManagement::ExerciseState::Paused)
return false;
return true;
}
bool HandlerEmergencyCall::isNewEmergencyCall(const AlmEmergencyCall &newdata)
{
for(const auto &ifs : qAsConst(m_emergencyObjMap))
{
const auto &data = ifs->getData();
if (data.issi == newdata.issi()
&& data.incomingTime == newdata.incomingTime()
&& !data.expired)
{
WARNING_LOG(m_logger)<<" SOS EXISTS and not yet quit! issi: "<<data.issi<<" incomingTime: "<<data.incomingTime<<" expired: "<<data.expired;
return false;
}
}
return true;
}
void HandlerEmergencyCall::onEmergencyCallChanged(const TrainingAreaBase::EmergencyCall &data, DataModification modType)
{
if (modType == DataModification::eRemoved || !isExerciseValidForEmergencyCall())
return;
AlarmManagement::AlmEmergencyCall emc;
emc.id(0);
emc.operatorId(0); // global
emc.sampleTime(data.sampleTime());
emc.incomingTime(data.sampleTime());
emc.expired(false);
emc.issi(data.equipmentNumber());
Core::GeoPosition position;
position.lat(data.position().lat());
position.lon(data.position().lon());
emc.position(position);
createEmergencyCallObject(emc);
}
void HandlerEmergencyCall::onAcknowledgeSOSInExercises(const AcknowledgeSOSInAllExercises &data, DataModification modType)
{
DEBUG_LOG(m_logger)<< "onAcknowledgeSOSInExercises START ";
Q_UNUSED(modType)
EmergencyCallAcknowledgeRequest request;
request.comment(data.comment());
request.expired(data.expired());
request.id(data.id());
request.issi(data.issi());
request.incomingTime(data.incomingTime());
request.name(data.name());
request.timestamp(data.timestamp());
request.operatorId(data.operatorId());
emergencyCallAcknowledgeRequest(request);
DEBUG_LOG(m_logger)<< "onAcknowledgeEmergencyInExercises END ";
}
} // namespace AlarmManagement