335 lines
12 KiB
C++
Executable File
335 lines
12 KiB
C++
Executable File
/**
|
|
* Handle the mapping real aircraft <-> participant in exercise
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Christian Ehrlicher, SLSE, 2018-08-02
|
|
*/
|
|
|
|
#include "handler_nasat_aircraft_participant.h"
|
|
#include "handler_nasat_aircraft.h"
|
|
#include "initialization.h"
|
|
#include "dds_handler.h"
|
|
#include "handler_participant.h"
|
|
#include <GuezNasat/gna_db.h>
|
|
#include <QTimer>
|
|
|
|
namespace GuezNasat
|
|
{
|
|
Database::NasatAircraftParticipant toDb(const NasatAircraftParticipant &dds)
|
|
{
|
|
Database::NasatAircraftParticipant ret;
|
|
ret.id = dds.id();
|
|
ret.nasatAircraftId = dds.nasatAircraftId();
|
|
ret.exerciseId = dds.exerciseId();
|
|
ret.participantId = dds.participantId();
|
|
return ret;
|
|
}
|
|
|
|
NasatAircraftParticipant fromDb(const Database::NasatAircraftParticipant &db)
|
|
{
|
|
NasatAircraftParticipant ret;
|
|
ret.id(db.id);
|
|
ret.nasatAircraftId(db.nasatAircraftId);
|
|
ret.exerciseId(db.exerciseId);
|
|
ret.participantId(db.participantId);
|
|
return ret;
|
|
}
|
|
|
|
HandlerNasatAircraftParticipant::HandlerNasatAircraftParticipant(Initialization *mainHandler)
|
|
: QObject()
|
|
, Interface::Fts::ModifyNasatAircraftParticipantRequestHandler(mainHandler->dds()->fts())
|
|
, m_mainHandler(mainHandler)
|
|
, m_dts(mainHandler->dds()->dts())
|
|
, m_fts(mainHandler->dds()->fts())
|
|
, m_db(mainHandler->db())
|
|
, m_logger(getLogger("HandlerNasatAircraftParticipant"))
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " START";
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
|
|
}
|
|
|
|
HandlerNasatAircraftParticipant::~HandlerNasatAircraftParticipant()
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " START";
|
|
for (const auto &data : qAsConst(m_nasatAircraftParticipants))
|
|
m_dts->removeNasatAircraftByKey(data.id());
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " END";
|
|
}
|
|
|
|
bool HandlerNasatAircraftParticipant::init()
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " START";
|
|
|
|
auto cb = [this](const Database::NasatAircraftParticipant & data)
|
|
{
|
|
const auto dds(fromDb(data));
|
|
DEBUG_LOG(m_logger) << "m_nasatAircraftParticipants.insert(" << dds.id() << ")";
|
|
m_nasatAircraftParticipants.insert(dds.id(), dds);
|
|
m_dts->publish(dds);
|
|
m_mainHandler->handlerParticipant()->onNasatAircraftParticipantCreated(dds);
|
|
};
|
|
m_db->select(cb);
|
|
|
|
// Most likely, the exercises are empty on normal startup of serviceManagement
|
|
// since ExerciseManagement is started later...
|
|
auto exmDtc = m_mainHandler->dds()->exmDtc();
|
|
connect(exmDtc.get(), &ExerciseManagement::Interface::Dtc::exerciseChanged,
|
|
this, &HandlerNasatAircraftParticipant::onExerciseChanged, Qt::UniqueConnection);
|
|
|
|
exmDtc->exercises([this](const ExerciseManagement::Exercise &exercise) {
|
|
onExerciseChanged(exercise, DataModification::eAdded);
|
|
});
|
|
|
|
dumpNasatAircraftParticipants();
|
|
dumpExercises();
|
|
|
|
// exercises are started one by one. So try 30
|
|
QTimer::singleShot(30000, this, [this]() { // 30000 -> 30sec
|
|
dumpNasatAircraftParticipants();
|
|
dumpExercises();
|
|
});
|
|
|
|
DEBUG_LOG(m_logger) << "HandlerNasatAircraftParticipant init done";
|
|
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " START";
|
|
return true;
|
|
}
|
|
|
|
void HandlerNasatAircraftParticipant::dumpNasatAircraftParticipants()
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, size=" << m_nasatAircraftParticipants.size();
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " --------------------------------------";
|
|
|
|
auto it = m_nasatAircraftParticipants.begin();
|
|
while (it != m_nasatAircraftParticipants.end())
|
|
{
|
|
const auto &id = it.key();
|
|
const auto &nap = it.value();
|
|
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " id=" << id << " - nap=" << nap;
|
|
++it;
|
|
}
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " --------------------------------------";
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " END, size=" << m_nasatAircraftParticipants.size();
|
|
}
|
|
|
|
void HandlerNasatAircraftParticipant::dumpExercises()
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, size=" << m_exercises.size();
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " --------------------------------------";
|
|
|
|
auto it = m_exercises.begin();
|
|
while (it != m_exercises.end())
|
|
{
|
|
const auto &id = it.key();
|
|
const auto &nasatAircraftParticipant = it.value();
|
|
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " id=" << id << " - nasatAircraftParticipant=" << nasatAircraftParticipant;
|
|
++it;
|
|
}
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " --------------------------------------";
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " END, size=" << m_exercises.size();
|
|
}
|
|
|
|
void HandlerNasatAircraftParticipant::aircraftRemoved(int nasatAircraftId)
|
|
{
|
|
auto it = m_nasatAircraftParticipants.begin();
|
|
while (it != m_nasatAircraftParticipants.end())
|
|
{
|
|
const auto &val = it.value();
|
|
if (val.nasatAircraftId() == nasatAircraftId)
|
|
{
|
|
removeNasatAircraftParticipant(val);
|
|
it = m_nasatAircraftParticipants.erase(it);
|
|
}
|
|
else
|
|
++it;
|
|
}
|
|
}
|
|
|
|
void HandlerNasatAircraftParticipant::participantRemoved(int exerciseId, int participantId)
|
|
{
|
|
DEBUG_LOG(m_logger) << "participantRemoved: " << exerciseId << ", " << participantId;
|
|
auto it = m_nasatAircraftParticipants.begin();
|
|
while (it != m_nasatAircraftParticipants.end())
|
|
{
|
|
const auto &val = it.value();
|
|
if (val.participantId() == participantId &&
|
|
val.exerciseId() == exerciseId)
|
|
{
|
|
removeNasatAircraftParticipant(val);
|
|
it = m_nasatAircraftParticipants.erase(it);
|
|
}
|
|
else
|
|
++it;
|
|
}
|
|
}
|
|
|
|
bool isExerciseStateValid(ExerciseManagement::ExerciseState_def::type state)
|
|
{
|
|
switch (state)
|
|
{
|
|
case ExerciseManagement::ExerciseState_def::Created:
|
|
case ExerciseManagement::ExerciseState_def::Paused:
|
|
case ExerciseManagement::ExerciseState_def::Started:
|
|
case ExerciseManagement::ExerciseState_def::Stopped:
|
|
return true;
|
|
case ExerciseManagement::ExerciseState_def::Unknown:
|
|
case ExerciseManagement::ExerciseState_def::Terminated:
|
|
return false;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void HandlerNasatAircraftParticipant::onExerciseChanged(const ExerciseManagement::Exercise &exercise, DataModification modType)
|
|
{
|
|
INFO_LOG(m_logger) << LOGFUNCTION << " START" << " , exercise" << exercise << " , modType" << modType;
|
|
|
|
const int exId = exercise.id();
|
|
switch (modType)
|
|
{
|
|
case DataModification::eAdded:
|
|
{
|
|
m_exercises[exId] = exercise;
|
|
const bool valid = isExerciseStateValid(exercise.state().underlying());
|
|
if (!valid)
|
|
{
|
|
INFO_LOG(m_logger) << LOGFUNCTION << " STATE of exId=" << exId
|
|
<< " , state=" << exercise.state();
|
|
int cnt = removeNapsOfExercise(exId);
|
|
INFO_LOG(m_logger) << LOGFUNCTION << " STATE of exId=" << exId << " not valid : counter of removed naps=" << cnt;
|
|
}
|
|
}
|
|
break;
|
|
case DataModification::eModified:
|
|
{
|
|
const ExerciseManagement::Exercise &exerciseRef = m_exercises[exId];
|
|
if (exerciseRef.state() != exercise.state())
|
|
{
|
|
const bool valid = isExerciseStateValid(exercise.state().underlying());
|
|
if (!valid)
|
|
{
|
|
INFO_LOG(m_logger) << LOGFUNCTION << " STATE change of exId=" << exId
|
|
<< " , old state=" << exerciseRef.state()
|
|
<< " , new state=" << exercise.state();
|
|
int cnt = removeNapsOfExercise(exId);
|
|
INFO_LOG(m_logger) << LOGFUNCTION << " STATE change of exId=" << exId << " : counter of removed naps=" << cnt;
|
|
}
|
|
}
|
|
m_exercises[exId] = exercise;
|
|
}
|
|
break;
|
|
case DataModification::eRemoved:
|
|
{
|
|
int cnt = removeNapsOfExercise(exId);
|
|
INFO_LOG(m_logger) << LOGFUNCTION << " STATE change of Exercise, counter of removed naps=" << cnt;
|
|
|
|
m_exercises.remove(exId);
|
|
}
|
|
break;
|
|
}
|
|
INFO_LOG(m_logger) << LOGFUNCTION << " END" << " , exercise" << exercise << " , modType" << modType;
|
|
}
|
|
|
|
void HandlerNasatAircraftParticipant::removeNasatAircraftParticipant(const NasatAircraftParticipant &val)
|
|
{
|
|
m_mainHandler->handlerParticipant()->onNasatAircraftParticipantRemoved(val);
|
|
// empty -> remove
|
|
m_db->removeNasatAircraftParticipant(val.id());
|
|
m_dts->removeNasatAircraftParticipantByKey(val.id());
|
|
}
|
|
|
|
void HandlerNasatAircraftParticipant::onModifyNasatAircraftParticipantRequest(const rti::core::SampleIdentity &cookie,
|
|
const NasatAircraftParticipant &request)
|
|
{
|
|
DEBUG_LOG(m_logger) << "onModifyNasatAircraftParticipantRequest: " << request;
|
|
auto ret = request.id() <= 0 ? createNasatAircraftParticipantRequest(request) : modifyNasatAircraftParticipantRequest(request);
|
|
if (ret.error())
|
|
WARNING_LOG(m_logger) << ret();
|
|
m_fts->modifyNasatAircraftParticipantReply(cookie, ret);
|
|
}
|
|
|
|
Core::FunctionReplyObject HandlerNasatAircraftParticipant::createNasatAircraftParticipantRequest(const NasatAircraftParticipant &request)
|
|
{
|
|
// create
|
|
Database::NasatAircraftParticipant napDb(toDb(request));
|
|
napDb.id = 0;
|
|
if (!m_db->insert(napDb))
|
|
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Can not create Aircraft Participant connection - error inserting values in database"));
|
|
|
|
// Success, Send Topic to DDS
|
|
const auto dds(fromDb(napDb));
|
|
m_dts->publish(dds);
|
|
m_nasatAircraftParticipants.insert(dds.id(), dds);
|
|
m_mainHandler->handlerParticipant()->onNasatAircraftParticipantCreated(request);
|
|
|
|
return Core::FunctionReplyObject(request.id());
|
|
}
|
|
|
|
Core::FunctionReplyObject HandlerNasatAircraftParticipant::modifyNasatAircraftParticipantRequest(const NasatAircraftParticipant &request)
|
|
{
|
|
auto it = m_nasatAircraftParticipants.find(request.id());
|
|
if (it == m_nasatAircraftParticipants.end())
|
|
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Can not modify Aircraft Participant connection - id %1 not found")).arg(request.id());
|
|
|
|
if (request == *it)
|
|
return Core::FunctionReplyObject(request.id());
|
|
|
|
if ((request.exerciseId() == 0 && request.participantId() == 0) ||
|
|
request.nasatAircraftId() == 0)
|
|
{
|
|
removeNasatAircraftParticipant(it.value());
|
|
m_nasatAircraftParticipants.erase(it);
|
|
return Core::FunctionReplyObject(request.id());
|
|
}
|
|
// modify
|
|
Database::NasatAircraftParticipant napDb(toDb(request));
|
|
if (!m_db->update(napDb))
|
|
return Core::FunctionReplyObject(request.id(), tr_lts("dds", "Can not modify Aircraft Participant connection - error updating values in database"));
|
|
|
|
// remove old subscriber
|
|
m_mainHandler->handlerParticipant()->onNasatAircraftParticipantRemoved(*it);
|
|
const auto dds(fromDb(napDb));
|
|
m_dts->publish(dds);
|
|
m_nasatAircraftParticipants.insert(dds.id(), dds);
|
|
|
|
// Success, Send Topic to DDS
|
|
m_dts->publish(fromDb(napDb));
|
|
|
|
// add new subscriber
|
|
m_mainHandler->handlerParticipant()->onNasatAircraftParticipantCreated(request);
|
|
return Core::FunctionReplyObject(request.id());
|
|
}
|
|
|
|
int HandlerNasatAircraftParticipant::removeNapsOfExercise(int exerciseId)
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " START, exerciseId=" << exerciseId
|
|
<< ", m_nasatAircraftParticipants.size()" << m_nasatAircraftParticipants.size();
|
|
int count = 0;
|
|
QHash<int, NasatAircraftParticipant> napsCopy = m_nasatAircraftParticipants;
|
|
|
|
for (const NasatAircraftParticipant &nap : qAsConst(napsCopy))
|
|
{
|
|
if (nap.exerciseId() == exerciseId)
|
|
{
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " nap has to be removed: nap=" << nap;
|
|
|
|
NasatAircraftParticipant napToTriggerRemoving;
|
|
napToTriggerRemoving.id(nap.id()); // to trigger removing
|
|
napToTriggerRemoving.exerciseId(0); // to trigger removing
|
|
napToTriggerRemoving.participantId(0); // to trigger removing
|
|
napToTriggerRemoving.nasatAircraftId(0); // to trigger removing
|
|
modifyNasatAircraftParticipantRequest(napToTriggerRemoving);
|
|
++count;
|
|
}
|
|
}
|
|
DEBUG_LOG(m_logger) << LOGFUNCTION << " END, exerciseId=" << exerciseId
|
|
<< ", m_nasatAircraftParticipants.size()" << m_nasatAircraftParticipants.size()
|
|
<< ", counter=" << count;
|
|
return count;
|
|
}
|
|
|
|
|
|
} // namespace GuezNasat
|