- CMakeLists.txt: Include-Pfade von ../ zu . geändert, json.h hinzugefügt - ~95 Dateien: Include-Pfade systematisch korrigiert - LtsUtils/ → LtsUtilsCore/ für alle Core-Header - LtsUtilsGui/LtsUtils/LtsUtilsGui/ → LtsUtilsGui/LtsUtilsGuiDds/ - Logger-API: getLogger() mit const char* Parameter - DataModification: enum class global (nicht im Lts-Namespace) - Participant-Struct: Member mit m_-Präfix - Export-Macro: SVCALMCOMMON_EXPORT statt ALMCOMMON_EXPORT - Signal/Slot-Signaturen korrigiert für Qt6 template matching Build validiert: LtsUtilsCore, LtsUtilsDds, LtsSessionData erfolgreich
811 lines
25 KiB
C++
Executable File
811 lines
25 KiB
C++
Executable File
/**
|
|
* Handler for all oc data at the client
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Philipp Dassow, NLST, 20-02-2018
|
|
*/
|
|
|
|
#include "handler_oc_data.h"
|
|
#include <utility>
|
|
|
|
#include <LtsUtilsCore/dds_vector.h>
|
|
#include <LtsUtils/qbytearray_byteaccess.h>
|
|
|
|
#include "main_handler.h"
|
|
#include "handler_oc_aes_data.h"
|
|
#include "handler_oc_situation_data.h"
|
|
#include "handler_oc_central_aes_data.h"
|
|
#include "settings.h"
|
|
|
|
#include "logger.h"
|
|
|
|
namespace OcSituationClient
|
|
{
|
|
|
|
HandlerOcData::HandlerOcData(MainHandler *mainHandler,
|
|
QObject *parent)
|
|
: QObject(parent)
|
|
, Interface::Fts::SendDemandEvaluationSchemaRequestHandler(mainHandler->dds()->fts())
|
|
, Interface::Fts::SendEvaluationRequestHandler(mainHandler->dds()->fts())
|
|
, Interface::Fts::SendDemandSituationRequestHandler(mainHandler->dds()->fts())
|
|
, Interface::Fts::SendEquipmentErrorRegistrationRequestHandler(mainHandler->dds()->fts())
|
|
, Interface::Fts::SendEquipmentRegistrationRequestHandler(mainHandler->dds()->fts())
|
|
, OcSituationServer::Interface::Fts::SendEquipmentMessageOcRequestHandler(mainHandler->ossFts())
|
|
, m_fts(mainHandler->dds()->fts())
|
|
, m_evlFtc(mainHandler->evlFtc())
|
|
, m_msgDtc(mainHandler->msgDtc())
|
|
, m_msgFtc(mainHandler->msgFtc())
|
|
, m_opmDtc(mainHandler->opmDtc())
|
|
, m_ossFts(mainHandler->ossFts())
|
|
, m_ppmDtc(mainHandler->ppmDtc())
|
|
, m_tabDtc(mainHandler->tabDtc())
|
|
, m_tabDts(mainHandler->tabDts())
|
|
, m_tabFtc(mainHandler->tabFtc())
|
|
, m_tabocDtc(mainHandler->tabocDtc())
|
|
, m_dbHandler(mainHandler->db())
|
|
, m_handlerOcAesData(new HandlerOcAesData(mainHandler, this))
|
|
, m_handlerOcSituationData(new HandlerOcSituationData(mainHandler->dds(), mainHandler->ppmDtc(), mainHandler->ppmFtc(), mainHandler->tabDts(), mainHandler->tabocDtc(), mainHandler->tabocDts(), this))
|
|
, m_handlerOcCentralAesData(new HandlerOcCentralAesData(mainHandler->aesDtc(), mainHandler->aesFtc(), mainHandler->tabocDts(), this))
|
|
, m_situationRequestCycleTimer(new QTimer(this))
|
|
, m_stateInformation({0, 0, 0})
|
|
, m_centerEquipmentId(-2)
|
|
, m_radius(0)
|
|
, m_useFilter(false)
|
|
, m_position(dds::core::optional<Core::GeoPosition2D>())
|
|
, m_licensed(false)
|
|
{}
|
|
|
|
HandlerOcData::~HandlerOcData()
|
|
{
|
|
delete m_handlerOcAesData;
|
|
delete m_handlerOcSituationData;
|
|
delete m_situationRequestCycleTimer;
|
|
}
|
|
|
|
bool HandlerOcData::init()
|
|
{
|
|
// set reset counter
|
|
QVector<Database::OscResetCounter> dataVec;
|
|
// read all reset counter from database
|
|
if (!m_dbHandler->select(dataVec))
|
|
{
|
|
ERROR_LOG(m_logger) << "Error reading reset counter from database!";
|
|
return false;
|
|
}
|
|
|
|
for (const auto &data : std::as_const(dataVec))
|
|
{
|
|
switch (data.aesTypeId)
|
|
{
|
|
case OcSituation::AesType::DangerArea:
|
|
{
|
|
m_stateInformation.resetCounterDangerAreas = data.resetCounter;
|
|
break;
|
|
}
|
|
case OcSituation::AesType::Ied:
|
|
{
|
|
m_stateInformation.resetCounterIeds = data.resetCounter;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
WARNING_LOG(m_logger) << "Reset counter for aes type: " << data.aesTypeId << " read from db is not handled.";
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// EVL FTC enable
|
|
if (!m_evlFtc->enableEvlSchemaModify())
|
|
{
|
|
ERROR_LOG(m_logger) << "Enabling EVL Function-Topics failed.";
|
|
return false;
|
|
}
|
|
|
|
// MSG DTC enable
|
|
if (!m_msgDtc->enableOperatorMessage())
|
|
{
|
|
ERROR_LOG(m_logger) << "Enabling MSG Data-Topics failed.";
|
|
return false;
|
|
}
|
|
connect(m_msgDtc.get(), &Messaging::Interface::Dtc::operatorMessageChanged, this, &HandlerOcData::onOperatorMessageChanged);
|
|
|
|
// MSG FTC enable
|
|
if (!m_msgFtc->enableCreateOperatorMessage() ||
|
|
!m_msgFtc->enableModifyOperatorMessage())
|
|
{
|
|
ERROR_LOG(m_logger) << "Enabling MSG Function-Topics failed.";
|
|
return false;
|
|
}
|
|
|
|
// OPM DTC enable
|
|
if (!m_opmDtc->enableUser())
|
|
{
|
|
ERROR_LOG(m_logger) << "Enabling OPM Data-Topics failed.";
|
|
return false;
|
|
}
|
|
|
|
// OSS FTS enable
|
|
if (!m_ossFts->enableSendEquipmentMessageOc())
|
|
{
|
|
ERROR_LOG(m_logger) << "Enabling OSS Function-Topics failed.";
|
|
return false;
|
|
}
|
|
|
|
// PPM DTC enable
|
|
if (!m_ppmDtc->enableParticipant())
|
|
{
|
|
ERROR_LOG(m_logger) << "Enabling PPM Data-Topics failed.";
|
|
return false;
|
|
}
|
|
|
|
if (!m_ppmDtc->waitForHistoricalDataParticipant(10000))
|
|
{
|
|
ERROR_LOG(m_logger) << "Waiting for historical data PPM-participant failed.";
|
|
return false;
|
|
}
|
|
|
|
// TAB DTC enable
|
|
if (!m_tabDtc->enableOcData())
|
|
{
|
|
ERROR_LOG(m_logger) << "Enabling TAB Data-Topics failed.";
|
|
return false;
|
|
}
|
|
connect(m_tabDtc.get(), &TrainingAreaBase::Interface::Dtc::ocDataChanged, this, &HandlerOcData::onOcDataChanged);
|
|
|
|
// TAB DTC enable
|
|
if (!m_tabDtc->enableEquipmentPosition())
|
|
{
|
|
ERROR_LOG(m_logger) << "Enabling TAB DTS Data-Topics failed.";
|
|
return false;
|
|
}
|
|
|
|
// TAB FTC enable
|
|
if (!m_tabFtc->enableSendOcData())
|
|
{
|
|
ERROR_LOG(m_logger) << "Enabling TAB Function-Topics failed.";
|
|
return false;
|
|
}
|
|
|
|
// TABOC DTC enable
|
|
if (!m_tabocDtc->enableTechnicalStateSfm() ||
|
|
!m_tabocDtc->enableOwnPosition() ||
|
|
!m_tabocDtc->enableSpecificsEquipment())
|
|
{
|
|
ERROR_LOG(m_logger) << "Enabling TABOC Data-Topics failed.";
|
|
return false;
|
|
}
|
|
connect(m_tabocDtc.get(), &TrainingAreaBaseOC::Interface::Dtc::ownPositionChanged, this, &HandlerOcData::onOwnPosition);
|
|
connect(m_tabocDtc.get(), &TrainingAreaBaseOC::Interface::Dtc::technicalStateSfmChanged, this, &HandlerOcData::onTechnicalStateSfmChanged);
|
|
auto cb = [this](const TrainingAreaBaseOC::TechnicalStateSfm & techstate)
|
|
{
|
|
onTechnicalStateSfmChanged(techstate, DataModification::eAdded);
|
|
};
|
|
m_tabocDtc->technicalStateSfms(cb);
|
|
|
|
// handler oc situation data
|
|
if (!m_handlerOcSituationData->init())
|
|
{
|
|
ERROR_LOG(m_logger) << "Initialising HandlerOcSituationData failed.";
|
|
return false;
|
|
}
|
|
|
|
// handler oc central aes data
|
|
if (!m_handlerOcCentralAesData->init())
|
|
{
|
|
ERROR_LOG(m_logger) << "Initialising HandlerOcCentralAesData failed.";
|
|
return false;
|
|
}
|
|
|
|
// Handler aes data
|
|
if (!m_handlerOcAesData->init())
|
|
{
|
|
ERROR_LOG(m_logger) << "Initialising HandlerOcAesData failed.";
|
|
return false;
|
|
}
|
|
|
|
connect(m_situationRequestCycleTimer, &QTimer::timeout, this, &HandlerOcData::situationRequestCycleTimeout);
|
|
m_situationRequestCycleTimer->start(Settings::situationRequestCycleTime());
|
|
|
|
connect(m_opmDtc.get(), &OperatorManagement::Interface::Dtc::userChanged,
|
|
this, &HandlerOcData::onUserChanged);
|
|
|
|
DEBUG_LOG(m_logger) << "Initialisation HandlerOcData succesful.";
|
|
return true;
|
|
}
|
|
|
|
void HandlerOcData::onEvlSchemaModifyReply(const Core::FunctionReplyObject &reply)
|
|
{
|
|
if (reply.error())
|
|
ERROR_LOG(m_logger) << "Schema could not be transmitted to EVL: " << reply.translated();
|
|
else
|
|
DEBUG_LOG(m_logger) << "Schema successfully transmitted to EVL!";
|
|
}
|
|
|
|
void HandlerOcData::onCreateOperatorMessageReply(const Core::FunctionReplyObject &reply)
|
|
{
|
|
if (reply.error())
|
|
ERROR_LOG(m_logger) << "Msg could not be created: " << reply.translated();
|
|
else
|
|
DEBUG_LOG(m_logger) << "Msg created successfully!";
|
|
}
|
|
|
|
void HandlerOcData::onModifyOperatorMessageReply(const Core::FunctionReplyObject &reply)
|
|
{
|
|
if (reply.error())
|
|
ERROR_LOG(m_logger) << "Msg could not be modified: " << reply.translated();
|
|
else
|
|
DEBUG_LOG(m_logger) << "Msg modified successfully!";
|
|
}
|
|
|
|
void HandlerOcData::onSendOcDataReply(const Core::FunctionReplyObject &reply)
|
|
{
|
|
if (reply.error())
|
|
ERROR_LOG(m_logger) << "Oc data could not be send: " << reply.translated();
|
|
else
|
|
DEBUG_LOG(m_logger) << "Oc data send successfully to TAB!";
|
|
}
|
|
|
|
void HandlerOcData::onOcDataChanged(const TrainingAreaBase::OcData &data, DataModification modType)
|
|
{
|
|
if ((modType != DataModification::eAdded) && (modType != DataModification::eModified))
|
|
return;
|
|
|
|
QByteArray payload = LtsUtils::toQByteArray(data.payload());
|
|
unsigned int telegramId;
|
|
|
|
LtsUtils::get1Byte(payload, telegramId);
|
|
|
|
payload.remove(0, 1); // removing telegram ID
|
|
|
|
switch (telegramId)
|
|
{
|
|
case OcSituation::TelegramId::Message:
|
|
{
|
|
handleMessage(payload);
|
|
break;
|
|
}
|
|
case OcSituation::TelegramId::EvaluationSchema:
|
|
{
|
|
handleEvaluationSchema(payload);
|
|
break;
|
|
}
|
|
case OcSituation::TelegramId::SituationData:
|
|
case OcSituation::TelegramId::SituationDataInitial:
|
|
{
|
|
if (m_centerEquipmentId > 0 || m_position.is_set()) // is the situation still requested
|
|
m_handlerOcSituationData->process(payload, telegramId == OcSituation::TelegramId::SituationDataInitial);
|
|
break;
|
|
}
|
|
case OcSituation::TelegramId::CentralAesData:
|
|
case OcSituation::TelegramId::CentralAesDataInitial:
|
|
{
|
|
if (m_centerEquipmentId > 0 || m_position.is_set())
|
|
m_handlerOcCentralAesData->process(payload, telegramId == OcSituation::TelegramId::CentralAesDataInitial);
|
|
break;
|
|
}
|
|
case OcSituation::TelegramId::StateInformation:
|
|
{
|
|
handleStateInformation(payload);
|
|
break;
|
|
}
|
|
case OcSituation::TelegramId::AesItems:
|
|
{
|
|
m_handlerOcAesData->process(payload);
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
INFO_LOG(m_logger) << "OC-data with telegram ID: " << telegramId << " is not handled by HandlerOcData OSC!";
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void HandlerOcData::onTechnicalStateSfmChanged(const TrainingAreaBaseOC::TechnicalStateSfm &data, DataModification modType)
|
|
{
|
|
if ((modType != DataModification::eAdded) && (modType != DataModification::eModified))
|
|
return;
|
|
|
|
if (m_licensed != data.licensed())
|
|
{
|
|
m_licensed = data.licensed();
|
|
if (data.licensed())
|
|
{
|
|
DEBUG_LOG(m_logger) << "Newly licensed -> demanding situation / sending messages";
|
|
demandSituation(true);
|
|
sendNewMessages();
|
|
}
|
|
}
|
|
}
|
|
|
|
void HandlerOcData::onOwnPosition(const TrainingAreaBaseOC::OwnPosition &data, DataModification modType)
|
|
{
|
|
if (modType == DataModification::eRemoved)
|
|
return;
|
|
|
|
TrainingAreaBase::EquipmentPosition out;
|
|
out.sampleTime(data.timeStamp());
|
|
out.position().position(Core::GeoPosition(data.position().lon(), data.position().lat(), 0));
|
|
if (data.moutObjectId().is_set())
|
|
out.position().moutObjectId().set(data.moutObjectId().get());
|
|
if (data.moutRoomId().is_set())
|
|
out.position().moutRoomId().set(data.moutRoomId().get());
|
|
out.equipmentNumber(m_tabocDtc->specificsEquipment(1).equipmentNumber());
|
|
|
|
m_tabDts->publish(out);
|
|
}
|
|
|
|
void HandlerOcData::onOperatorMessageChanged(const Messaging::OperatorMessage &data, DataModification modType)
|
|
{
|
|
if (DataModification::eRemoved == modType)
|
|
return;
|
|
DEBUG_LOG(m_logger) << data.recipientId() << "new message changed is send" << data.isSend() << " id" << data.id() ;
|
|
const int ownEqNo = m_tabocDtc->specificsEquipment(1).equipmentNumber();
|
|
if (data.recipientId() > 0)
|
|
{
|
|
if (data.isSend() ||
|
|
((data.recipientType() == Messaging::AddressType::ObserverController) && (data.recipientId() == getParticipantIdByEquipmentNumber(ownEqNo))))
|
|
return; // is already send or its a message we have received from TETRA
|
|
}
|
|
else
|
|
return; // message without recipient -> could not be send anyway
|
|
|
|
if (m_licensed)
|
|
{
|
|
QByteArray payload;
|
|
|
|
LtsUtils::set1Byte(OcSituation::TelegramId::Message, payload);
|
|
if (data.recipientType() == Messaging::AddressType::Operator)
|
|
LtsUtils::set2Byte(data.recipientId(), payload);
|
|
else
|
|
{
|
|
const auto participantEqNo = m_ppmDtc->participant(data.recipientId()).equipmentNumber();
|
|
if (!participantEqNo.is_set())
|
|
{
|
|
WARNING_LOG(m_logger) << "Recipient with id " << data.recipientId() << " has no equipment number set - can not send message";
|
|
return;
|
|
}
|
|
LtsUtils::set2Byte(participantEqNo.get(), payload);
|
|
}
|
|
LtsUtils::set1Byte(data.recipientType().underlying(), payload);
|
|
|
|
// always send with our own equipment number
|
|
LtsUtils::set2Byte(ownEqNo, payload);
|
|
LtsUtils::set1Byte(Messaging::AddressType::ObserverController, payload);
|
|
LtsUtils::set2Byte(data.exerciseId(), payload);
|
|
|
|
payload.append(QByteArray::fromStdString(data.subject()));
|
|
payload.append('\n'); // separating subject from message
|
|
payload.append(QByteArray::fromStdString(data.message()));
|
|
|
|
TrainingAreaBase::SendOcDataRequest out;
|
|
out.payload(LtsUtils::convert<std::vector<uint8_t>>(payload));
|
|
|
|
DEBUG_LOG(m_logger) << "Sending operator message: " << data;
|
|
|
|
m_tabFtc->sendOcDataRequest(out, this);
|
|
|
|
m_msgFtc->modifyOperatorMessageRequest(Messaging::ModifyOperatorMessageRequest(data.id(), data.isRead(), true, data.isDeleted()), this);
|
|
}
|
|
}
|
|
|
|
void HandlerOcData::situationRequestCycleTimeout()
|
|
{
|
|
demandSituation();
|
|
}
|
|
|
|
void HandlerOcData::onUserChanged(const OperatorManagement::User &data, DataModification modType)
|
|
{
|
|
TRACE_LOG(m_logger) << Q_FUNC_INFO;
|
|
|
|
if (modType != DataModification::eModified || data.id() == 99) // id 99 = Organisator
|
|
return;
|
|
|
|
// on the abt there is only one user logged in, so if the workstation id of any
|
|
// user changes, we remember the user. now we are able to see, if the user logs out
|
|
if (data.workstationId() != 0)
|
|
{
|
|
DEBUG_LOG(m_logger) << "User " << data.name() << " logged in.";
|
|
|
|
m_user = data;
|
|
|
|
return;
|
|
}
|
|
|
|
// if we get new information about the user we remembered and the workstation id is 0, the use is logged out
|
|
// or all applications are closed. now we have to stop situation data (if already requested) and forget the user.
|
|
if (m_user.id() == data.id() && data.workstationId() == 0)
|
|
{
|
|
DEBUG_LOG(m_logger) << "User " << m_user.name() << " logged out.";
|
|
|
|
if (m_centerEquipmentId > 0 || m_position.is_set())
|
|
{
|
|
DEBUG_LOG(m_logger) << "Stopping situation requests.";
|
|
|
|
// stopping situation data
|
|
m_centerEquipmentId = 0;
|
|
m_radius = 0;
|
|
m_position.reset();
|
|
demandSituation();
|
|
}
|
|
|
|
// forgetting the user
|
|
m_user = OperatorManagement::User();
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
void HandlerOcData::onSendDemandEvaluationSchemaRequest(const rti::core::SampleIdentity &cookie, const SendDemandEvaluationSchemaRequest &request)
|
|
{
|
|
demandEvaluationSchema(request.schemaId());
|
|
|
|
m_fts->sendDemandEvaluationSchemaReply(cookie, Core::FunctionReplyObject());
|
|
}
|
|
|
|
void HandlerOcData::onSendEvaluationRequest(const rti::core::SampleIdentity &cookie, const SendEvaluationRequest &request)
|
|
{
|
|
QByteArray payload;
|
|
|
|
LtsUtils::set1Byte(OcSituation::TelegramId::Evaluation, payload);
|
|
LtsUtils::set2Byte(request.schemaId(), payload);
|
|
LtsUtils::set4Byte(request.senderOperatorId(), payload);
|
|
if (request.receiverOperatorId().is_set())
|
|
LtsUtils::set4Byte(request.receiverOperatorId().get(), payload);
|
|
else
|
|
LtsUtils::set4Byte(0, payload);
|
|
LtsUtils::set8Byte(request.timeStamp(), payload);
|
|
LtsUtils::set2Byte(request.hierarchy().size(), payload);
|
|
payload.append(request.hierarchy().c_str(), request.hierarchy().size());
|
|
LtsUtils::set2Byte(request.text().size(), payload);
|
|
payload.append(request.text().c_str(), request.text().size());
|
|
|
|
TrainingAreaBase::SendOcDataRequest out;
|
|
out.payload(LtsUtils::convert<std::vector<uint8_t>>(payload));
|
|
|
|
m_tabFtc->sendOcDataRequest(out, this);
|
|
|
|
m_fts->sendEvaluationReply(cookie, Core::FunctionReplyObject());
|
|
}
|
|
|
|
void HandlerOcData::onSendDemandSituationRequest(const rti::core::SampleIdentity &cookie, const SendDemandSituationRequest &request)
|
|
{
|
|
DEBUG_LOG(m_logger) << "New demand situation request from UI: " << request;
|
|
|
|
m_centerEquipmentId = request.centerEquipmentId();
|
|
m_radius = request.radius();
|
|
m_position = request.position();
|
|
m_useFilter = request.filterActive();
|
|
m_typeClassList = request.typeClassList();
|
|
m_partyList = request.partyList();
|
|
|
|
demandSituation(true);
|
|
|
|
m_fts->sendDemandSituationReply(cookie, Core::FunctionReplyObject());
|
|
}
|
|
|
|
void HandlerOcData::onSendEquipmentMessageOcRequest(const rti::core::SampleIdentity &cookie, const OcSituationServer::SendEquipmentMessageRequest &request)
|
|
{
|
|
// just answer so the messaging service does work normally, messages are send when received from DTC
|
|
m_ossFts->sendEquipmentMessageOcReply(cookie, Core::FunctionReplyObject(request.requestId()));
|
|
return;
|
|
}
|
|
|
|
void HandlerOcData::onSendEquipmentErrorRegistrationRequest(const rti::core::SampleIdentity &cookie, const SendEquipmentErrorRegistrationRequest &request)
|
|
{
|
|
QByteArray payload;
|
|
|
|
LtsUtils::set1Byte(OcSituation::TelegramId::EquipmentErrorRegistration, payload);
|
|
LtsUtils::set2Byte(request.ocEquipmentNumber(), payload);
|
|
|
|
QByteArray faultEquipmentNumber(QByteArray::fromStdString(request.faultEquipmentNumber()));
|
|
faultEquipmentNumber.resize(36); // see ICD
|
|
payload.append(faultEquipmentNumber);
|
|
QByteArray device(QByteArray::fromStdString(request.device()));
|
|
device.resize(36); // see ICD
|
|
payload.append(device);
|
|
QByteArray text(QByteArray::fromStdString(request.text()));
|
|
if (text.size() > 255)
|
|
text.resize(255);
|
|
LtsUtils::set1Byte(text.size(), payload);
|
|
payload.append(text);
|
|
|
|
TrainingAreaBase::SendOcDataRequest out;
|
|
out.payload(LtsUtils::convert<std::vector<uint8_t>>(payload));
|
|
m_tabFtc->sendOcDataRequest(out, this);
|
|
|
|
m_fts->sendEquipmentErrorRegistrationReply(cookie, Core::FunctionReplyObject());
|
|
}
|
|
|
|
void HandlerOcData::onSendEquipmentRegistrationRequest(const rti::core::SampleIdentity &cookie, const SendEquipmentRegistrationRequest &request)
|
|
{
|
|
QByteArray payload;
|
|
|
|
LtsUtils::set1Byte(OcSituation::TelegramId::EquipmentRegistration, payload);
|
|
LtsUtils::set2Byte(request.participantId(), payload);
|
|
LtsUtils::set2Byte(request.equipmentNumber(), payload);
|
|
|
|
|
|
TrainingAreaBase::SendOcDataRequest out;
|
|
out.payload(LtsUtils::convert<std::vector<uint8_t>>(payload));
|
|
m_tabFtc->sendOcDataRequest(out, this);
|
|
DEBUG_LOG(m_logger) << "try send out to OcData";
|
|
|
|
m_fts->sendEquipmentRegistrationReply(cookie, Core::FunctionReplyObject());
|
|
}
|
|
|
|
void HandlerOcData::demandEvaluationSchema(int schemaId)
|
|
{
|
|
INFO_LOG(m_logger) << "Demand evaluation schema: " << schemaId;
|
|
|
|
QByteArray payload;
|
|
|
|
LtsUtils::set1Byte(OcSituation::TelegramId::DemandEvaluationSchema, payload);
|
|
LtsUtils::set2Byte(schemaId, payload);
|
|
|
|
TrainingAreaBase::SendOcDataRequest out;
|
|
out.payload(LtsUtils::convert<std::vector<uint8_t>>(payload));
|
|
|
|
m_tabFtc->sendOcDataRequest(out, this);
|
|
}
|
|
|
|
void HandlerOcData::demandSituation(bool initial)
|
|
{
|
|
if (!m_tabocDtc->technicalStateSfm(1).licensed())
|
|
return;
|
|
|
|
if (m_centerEquipmentId < -1)
|
|
{
|
|
DEBUG_LOG(m_logger) << "No situation requested as tlnId < -1!";
|
|
return;
|
|
}
|
|
|
|
if (m_centerEquipmentId == 0 && !m_position.is_set())
|
|
{
|
|
m_centerEquipmentId = -1;
|
|
m_handlerOcSituationData->removeAllPositions();
|
|
m_handlerOcCentralAesData->removeAllCentralAesItems();
|
|
}
|
|
|
|
|
|
if (m_centerEquipmentId == -1)
|
|
{
|
|
INFO_LOG(m_logger) << "Last demand situation m_centerEquipmentId < -1!";
|
|
|
|
// PlayerId -2 setzen, damit keine weiteren Telegramme uebertragen werden
|
|
m_centerEquipmentId = -2;
|
|
}
|
|
|
|
if (m_centerEquipmentId > 0)
|
|
INFO_LOG(m_logger) << "Demand OC situation around m_centerEquipmentId: " << m_centerEquipmentId
|
|
<< " radius: " << m_radius;
|
|
else if (m_position.is_set())
|
|
INFO_LOG(m_logger) << "Demand OC situation around position: " << m_position.get()
|
|
<< " radius: " << m_radius;
|
|
|
|
QByteArray payload;
|
|
|
|
LtsUtils::set1Byte(OcSituation::TelegramId::DemandSituation, payload);
|
|
if (m_position.is_set())
|
|
{
|
|
LtsUtils::set1Byte(OcSituation::SituationCenterType::Position, payload);
|
|
LtsUtils::set8Byte(m_position.get().lon(), payload);
|
|
LtsUtils::set8Byte(m_position.get().lat(), payload);
|
|
}
|
|
else
|
|
{
|
|
LtsUtils::set1Byte(OcSituation::SituationCenterType::Equipment, payload);
|
|
LtsUtils::set2Byte(m_centerEquipmentId, payload);
|
|
}
|
|
LtsUtils::set2Byte(m_radius, payload);
|
|
LtsUtils::set1Byte(initial, payload);
|
|
LtsUtils::set1Byte(m_useFilter, payload);
|
|
|
|
if (m_useFilter)
|
|
{
|
|
LtsUtils::set1Byte(m_partyList.size(), payload);
|
|
for (const auto &party : m_partyList)
|
|
LtsUtils::set2Byte(party, payload);
|
|
LtsUtils::set1Byte(m_typeClassList.size(), payload);
|
|
for (const auto &tc : m_typeClassList)
|
|
LtsUtils::set1Byte(tc, payload);
|
|
}
|
|
|
|
TrainingAreaBase::SendOcDataRequest out;
|
|
out.payload(LtsUtils::convert<std::vector<uint8_t>>(payload));
|
|
|
|
m_tabFtc->sendOcDataRequest(out, this);
|
|
|
|
if (initial)
|
|
{
|
|
m_handlerOcSituationData->removeAllPositions();
|
|
m_handlerOcCentralAesData->removeAllCentralAesItems();
|
|
}
|
|
}
|
|
|
|
void HandlerOcData::demandAesItems(OcSituation::AesType aesType)
|
|
{
|
|
INFO_LOG(m_logger) << "Demand aes items type: " << aesType;
|
|
QByteArray payload;
|
|
|
|
LtsUtils::set1Byte(OcSituation::TelegramId::DemandAesItems, payload);
|
|
LtsUtils::set1Byte(aesType, payload);
|
|
|
|
TrainingAreaBase::SendOcDataRequest out;
|
|
out.payload(LtsUtils::convert<std::vector<uint8_t>>(payload));
|
|
|
|
m_tabFtc->sendOcDataRequest(out, this);
|
|
}
|
|
|
|
void HandlerOcData::sendNewMessages()
|
|
{
|
|
DEBUG_LOG(m_logger) << "Sending operator messages that havn't been send yet.";
|
|
|
|
auto cb = [this](const Messaging::OperatorMessage & message)
|
|
{
|
|
if (message.recipientId() > 0 && !message.isSend())
|
|
onOperatorMessageChanged(message, DataModification::eModified);
|
|
};
|
|
m_msgDtc->operatorMessages(cb);
|
|
}
|
|
|
|
void HandlerOcData::handleMessage(const QByteArray &data)
|
|
{
|
|
Messaging::CreateOperatorMessageRequest out;
|
|
size_t pos = 0;
|
|
unsigned int tmp;
|
|
unsigned int addressType;
|
|
|
|
// get receiver
|
|
LtsUtils::get2Byte(data, pos, tmp);
|
|
|
|
int ownParticipantId = getParticipantIdByEquipmentNumber(m_tabocDtc->specificsEquipment(1).equipmentNumber());
|
|
if (ownParticipantId > 0)
|
|
out.recipientIds().push_back(ownParticipantId);
|
|
else
|
|
{
|
|
ERROR_LOG(m_logger) << "Receiver invalid, do not publish message.";
|
|
return;
|
|
}
|
|
|
|
// get address type
|
|
LtsUtils::get1Byte(data, pos, tmp);
|
|
out.recipientType(Messaging::AddressType::ObserverController);
|
|
|
|
// get sender
|
|
LtsUtils::get2Byte(data, pos, tmp);
|
|
out.senderId(tmp);
|
|
// get address type
|
|
LtsUtils::get1Byte(data, pos, addressType);
|
|
out.senderType(static_cast<Messaging::AddressType::inner_enum>(addressType));
|
|
/*
|
|
if (addressType == Messaging::AddressType::ObserverController)
|
|
{
|
|
int participantId = tmp;// getParticipantIdByEquipmentNumber(tmp);
|
|
if (participantId > 0)
|
|
{
|
|
out.senderId(participantId);
|
|
}
|
|
else
|
|
{
|
|
WARNING_LOG(m_logger) << "Sender equipment number: " << tmp << " is unknown. Setting senderId to 0.";
|
|
out.senderId(0);
|
|
}
|
|
}
|
|
*/
|
|
//excerciseID
|
|
LtsUtils::get2Byte(data, pos, tmp);
|
|
out.exerciseId(tmp);
|
|
//text
|
|
const QByteArray msg(data.right(data.size() - pos));
|
|
int idx = msg.indexOf('\n');
|
|
if (idx < 0)
|
|
{
|
|
out.subject((tr("Message from %1").arg(out.senderId())).toStdString());
|
|
out.message(msg.constData());
|
|
}
|
|
else
|
|
{
|
|
out.subject(msg.left(idx).constData());
|
|
out.message(msg.mid(idx + 1).constData());
|
|
}
|
|
|
|
DEBUG_LOG(m_logger) << "Got new message: " << out;
|
|
|
|
m_msgFtc->createOperatorMessageRequest(out, this);
|
|
}
|
|
|
|
void HandlerOcData::handleEvaluationSchema(const QByteArray &data)
|
|
{
|
|
Evaluations::EvlSchemaModifyRequest out;
|
|
size_t pos = 0;
|
|
unsigned int tmp;
|
|
|
|
// get schema id
|
|
LtsUtils::get2Byte(data, pos, tmp);
|
|
out.id(static_cast<int>(tmp) * -1); // to mark as from oc
|
|
// get schema string
|
|
const QByteArray uncompressed = MainHandler::tryUncompress(data.mid(pos), true);
|
|
out.schemadata(uncompressed.toStdString());
|
|
// set sendToTa true
|
|
out.sendToTa(true);
|
|
|
|
DEBUG_LOG(m_logger) << "Got new evaluation schema: ";
|
|
|
|
m_evlFtc->evlSchemaModifyRequest(out, this);
|
|
}
|
|
|
|
void HandlerOcData::handleStateInformation(const QByteArray &data)
|
|
{
|
|
size_t pos = 0;
|
|
unsigned int newEvaluationSchemaId = 0;
|
|
LtsUtils::get2Byte(data, pos, newEvaluationSchemaId);
|
|
unsigned int newResetCounterDangerAreas = 0;
|
|
LtsUtils::get2Byte(data, pos, newResetCounterDangerAreas);
|
|
unsigned int newResetCounterIeds = 0;
|
|
LtsUtils::get2Byte(data, pos, newResetCounterIeds);
|
|
|
|
if (newEvaluationSchemaId != m_stateInformation.avticeEvaluationSchemaId)
|
|
{
|
|
demandEvaluationSchema(newEvaluationSchemaId);
|
|
m_stateInformation.avticeEvaluationSchemaId = newEvaluationSchemaId;
|
|
}
|
|
|
|
if (newResetCounterDangerAreas != m_stateInformation.resetCounterDangerAreas)
|
|
{
|
|
setResetCnt(OcSituation::AesType::DangerArea, newResetCounterDangerAreas);
|
|
demandAesItems(OcSituation::AesType::DangerArea);
|
|
}
|
|
|
|
if (newResetCounterIeds != m_stateInformation.resetCounterIeds)
|
|
{
|
|
setResetCnt(OcSituation::AesType::Ied, newResetCounterIeds);
|
|
demandAesItems(OcSituation::AesType::Ied);
|
|
}
|
|
}
|
|
|
|
void HandlerOcData::setResetCnt(OcSituation::AesType aesType, int resetCnt)
|
|
{
|
|
Database::OscResetCounter data;
|
|
data.aesTypeId = aesType;
|
|
data.resetCounter = resetCnt;
|
|
|
|
switch (aesType)
|
|
{
|
|
case OcSituation::AesType::DangerArea:
|
|
{
|
|
m_stateInformation.resetCounterDangerAreas = resetCnt;
|
|
break;
|
|
}
|
|
case OcSituation::AesType::Ied:
|
|
{
|
|
m_stateInformation.resetCounterIeds = resetCnt;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
WARNING_LOG(m_logger) << "Setting reset counter for aes type: " << aesType << " is not handled.";
|
|
break;
|
|
}
|
|
}
|
|
|
|
// update db
|
|
if (!m_dbHandler->update(data))
|
|
ERROR_LOG(m_logger) << "Error updating reset counter in db.";
|
|
}
|
|
|
|
int HandlerOcData::getParticipantIdByEquipmentNumber(int eqNumber)
|
|
{
|
|
int partId = m_ppmDtc->participantIdByEquipmentNumber(eqNumber);
|
|
|
|
if (partId <= 0)
|
|
ERROR_LOG(m_logger) << "Couldn't find our own ID in ppm!";
|
|
|
|
return partId;
|
|
}
|
|
|
|
} // Namespace OcSituationClient
|