289 lines
8.5 KiB
C++
Executable File
289 lines
8.5 KiB
C++
Executable File
/**
|
|
* Handler for aes data received transparent by the oc-laptop
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Philipp Dassow, NLST, 18-04-2018
|
|
*/
|
|
|
|
#include "handler_oc_aes_data.h"
|
|
|
|
#include <LtsUtilsCore/qbytearray_byteaccess.h>
|
|
|
|
#include <OcSituationServer/oc_situation.h>
|
|
|
|
#include "settings.h"
|
|
|
|
namespace OcSituationClient
|
|
{
|
|
|
|
HandlerOcAesData::HandlerOcAesData(MainHandler *mainHandler,
|
|
QObject *parent)
|
|
: QObject(parent)
|
|
, m_dds(mainHandler->dds())
|
|
, m_aesDtc(mainHandler->aesDtc())
|
|
, m_aesFtc(mainHandler->aesFtc())
|
|
, m_gimDtc(mainHandler->gimDtc())
|
|
, m_tabDts(mainHandler->tabDts())
|
|
, m_tabocDtc(mainHandler->tabocDtc())
|
|
, m_utmCoord(LtsCoordTrans::UtmCoordinate::fromMgrs(Settings::baseCoord()))
|
|
, m_logger(getLogger("HandlerOcAesData"))
|
|
{}
|
|
|
|
HandlerOcAesData::~HandlerOcAesData()
|
|
{}
|
|
|
|
bool HandlerOcAesData::init()
|
|
{
|
|
// AES DTC enable
|
|
if (!m_aesDtc->enableDangerArea())
|
|
{
|
|
ERROR_LOG(m_logger) << "Enabling AES Data-Topics failed.";
|
|
return false;
|
|
}
|
|
|
|
// AES FTC enable
|
|
if (!m_aesFtc->enableDangerAreaModify() ||
|
|
!m_aesFtc->enableDangerAreaRemove())
|
|
{
|
|
ERROR_LOG(m_logger) << "Enabling AES Function-Topics failed.";
|
|
return false;
|
|
}
|
|
|
|
// GIM DTC enable
|
|
if (!m_gimDtc->enableIed())
|
|
{
|
|
ERROR_LOG(m_logger) << "Enabling GIM Data-Topics failed.";
|
|
return false;
|
|
}
|
|
// TAB DTS enable
|
|
if (!m_tabDts->enableDefinitionIed())
|
|
{
|
|
ERROR_LOG(m_logger) << "Enabling TAB DTS Data-Topics failed.";
|
|
return false;
|
|
}
|
|
|
|
// TABOC DTC enable
|
|
if (!m_tabocDtc->enableSpecificsExercise())
|
|
{
|
|
ERROR_LOG(m_logger) << "Enabling TABOC Data-Topics failed.";
|
|
return false;
|
|
}
|
|
connect(m_tabocDtc.get(), &TrainingAreaBaseOC::Interface::Dtc::specificsExerciseChanged, this, &HandlerOcAesData::onSpecificsExerciseChanged);
|
|
auto cb = [this](const TrainingAreaBaseOC::SpecificsExercise & specificsExercise)
|
|
{
|
|
onSpecificsExerciseChanged(specificsExercise, DataModification::eAdded);
|
|
};
|
|
m_tabocDtc->specificsExercises(cb);
|
|
|
|
return true;
|
|
}
|
|
|
|
void HandlerOcAesData::process(const QByteArray &data)
|
|
{
|
|
DEBUG_LOG(m_logger) << "Compressed binary data: " << data.toHex(' ');
|
|
|
|
QByteArray uncompressed = MainHandler::tryUncompress(data, true);
|
|
|
|
DEBUG_LOG(m_logger) << "Uncompressed binary data: " << uncompressed.toHex(' ');
|
|
OcSituation::AesType aesType;
|
|
LtsUtils::get1Byte(uncompressed, aesType);
|
|
|
|
size_t pos = 1; // first byte is aesType
|
|
switch (aesType)
|
|
{
|
|
case OcSituation::AesType::DangerArea:
|
|
{
|
|
handleDangerAreas(uncompressed, pos);
|
|
break;
|
|
}
|
|
case OcSituation::AesType::Ied:
|
|
{
|
|
handleIeds(uncompressed, pos);
|
|
break;
|
|
}
|
|
case OcSituation::AesType::IedPositions:
|
|
{
|
|
handleIedPositions(uncompressed, pos);
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
WARNING_LOG(m_logger) << "Aes type: " << aesType << " is currently not handled.";
|
|
}
|
|
}
|
|
}
|
|
|
|
void HandlerOcAesData::onDangerAreaModifyReply(const Core::FunctionReplyObject &reply)
|
|
{
|
|
if (reply.error())
|
|
ERROR_LOG(m_logger) << "Danger area modify failed: " << reply.translated();
|
|
else
|
|
DEBUG_LOG(m_logger) << "Danger area modify successfull. Id: " << reply.id();
|
|
}
|
|
|
|
void HandlerOcAesData::onDangerAreaRemoveReply(const Core::FunctionReplyObject &reply)
|
|
{
|
|
if (reply.error())
|
|
ERROR_LOG(m_logger) << "Danger area remove failed: " << reply.translated();
|
|
else
|
|
DEBUG_LOG(m_logger) << "Danger area remove successfull. Id: " << reply.id();
|
|
}
|
|
|
|
void HandlerOcAesData::handleDangerAreas(const QByteArray &data, size_t pos)
|
|
{
|
|
INFO_LOG(m_logger) << "Got new danger area data";
|
|
DEBUG_LOG(m_logger) << "Binary data: " << data.toHex(' ');
|
|
|
|
QList<int> aesToBeDeleted = m_aesDtc->dangerAreas().keys();
|
|
|
|
int cnt;
|
|
LtsUtils::get1Byte(data, pos, cnt);
|
|
|
|
AreaEffectSimulation::DangerAreaModifyRequest req;
|
|
uint64_t tmp;
|
|
int x = 0, y = 0;
|
|
|
|
req.chargeTypeId(311); // danger area
|
|
|
|
for (int i = 0; i < cnt; ++i)
|
|
{
|
|
LtsUtils::get2Byte(data, pos, tmp);
|
|
req.id(tmp);
|
|
req.name(data.mid(pos, 8).toStdString());
|
|
pos += 8;
|
|
LtsUtils::get4Byte(data, pos, tmp);
|
|
if (tmp > 0)
|
|
req.effectStart(dds::core::optional<rti::core::int64>(tmp * 1000));
|
|
else
|
|
req.effectStart(dds::core::optional<rti::core::int64>());
|
|
|
|
size_t segmentCnt = 0;
|
|
LtsUtils::get1Byte(data, pos, segmentCnt);
|
|
std::vector<Core::GeoPosition2D> segments;
|
|
segments.reserve(segmentCnt);
|
|
for (size_t j = 0; j < segmentCnt; ++j)
|
|
{
|
|
LtsUtils::get3Byte(data, pos, y);
|
|
LtsUtils::get3Byte(data, pos, x);
|
|
segments.emplace_back(relativeFromGeoPosition(x, y));
|
|
}
|
|
req.segments(segments);
|
|
|
|
DEBUG_LOG(m_logger) << (aesToBeDeleted.contains(req.id()) ? "Modifying " : "Creating ") << "danger area: " << req;
|
|
|
|
aesToBeDeleted.removeAll(req.id()); // item was created/modified -> does not need to be deleted
|
|
req.id(req.id() * -1); // inverted id to mark as for oc
|
|
m_aesFtc->dangerAreaModifyRequest(req, this);
|
|
}
|
|
|
|
for (int id : qAsConst(aesToBeDeleted))
|
|
{
|
|
if (m_aesDtc->dangerArea(id).isCentral())
|
|
continue;
|
|
if (m_aesDtc->dangerArea(id).effectStateId().underlying() > AreaEffectSimulation::AesEffectState::EsRemoved)
|
|
{
|
|
DEBUG_LOG(m_logger) << "Removing danger area id: " << id;
|
|
m_aesFtc->dangerAreaRemoveRequest(Core::RemoveElementRequest(id), this);
|
|
}
|
|
}
|
|
}
|
|
|
|
void HandlerOcAesData::handleIeds(const QByteArray &data, size_t pos)
|
|
{
|
|
INFO_LOG(m_logger) << "Got new ied data";
|
|
DEBUG_LOG(m_logger) << "Binary data: " << data.toHex(' ');
|
|
|
|
int cnt;
|
|
LtsUtils::get1Byte(data, pos, cnt);
|
|
|
|
TrainingAreaBase::DefinitionIed def;
|
|
unsigned long tmp;
|
|
int x = 0, y = 0;
|
|
|
|
def.pairingState(1); // not paired in OC application
|
|
|
|
for (int i = 0; i < cnt; ++i)
|
|
{
|
|
LtsUtils::get2Byte(data, pos, tmp);
|
|
def.iedId(tmp);
|
|
LtsUtils::get1Byte(data, pos, tmp);
|
|
def.type(tmp);
|
|
LtsUtils::get1Byte(data, pos, tmp);
|
|
def.tautWireTrigger((tmp >> 3) & 0x01);
|
|
def.lightBarrierTrigger((tmp >> 2) & 0x01);
|
|
def.switchTrigger((tmp >> 1) & 0x01);
|
|
def.remoteTrigger((tmp >> 0) & 0x01);
|
|
LtsUtils::get1Byte(data, pos, tmp);
|
|
def.explosiveForce(tmp);
|
|
LtsUtils::get1Byte(data, pos, tmp);
|
|
def.partyId(tmp);
|
|
LtsUtils::get1Byte(data, pos, tmp);
|
|
def.tacticalState(tmp);
|
|
LtsUtils::get3Byte(data, pos, x);
|
|
LtsUtils::get3Byte(data, pos, y);
|
|
def.position(relativeFromGeoPosition(x, y));
|
|
|
|
DEBUG_LOG(m_logger) << "Publishing definition ied: " << def;
|
|
|
|
m_tabDts->publish(def);
|
|
}
|
|
}
|
|
|
|
void HandlerOcAesData::handleIedPositions(const QByteArray &data, size_t pos)
|
|
{
|
|
INFO_LOG(m_logger) << "Got new ied positions data";
|
|
DEBUG_LOG(m_logger) << "Binary data: " << data.toHex(' ');
|
|
|
|
int cnt;
|
|
LtsUtils::get1Byte(data, pos, cnt);
|
|
|
|
const QMap<int, GuezIedManagement::Ied> ieds = m_gimDtc->ieds();
|
|
QMap<int, int> IedEqNumberToDdsId; // iedEqNumber, ddsId
|
|
|
|
for (const auto &ied : ieds)
|
|
IedEqNumberToDdsId.insert(ied.equipmentNumber(), ied.id());
|
|
|
|
TrainingAreaBase::DefinitionIed def;
|
|
unsigned long eqNumber;
|
|
int x = 0, y = 0;
|
|
|
|
for (int i = 0; i < cnt; ++i)
|
|
{
|
|
LtsUtils::get2Byte(data, pos, eqNumber);
|
|
const GuezIedManagement::Ied &ied = ieds.value(IedEqNumberToDdsId.value(eqNumber));
|
|
def.iedId(eqNumber);
|
|
def.type(ied.type().underlying());
|
|
def.tautWireTrigger(ied.tautWireTrigger());
|
|
def.lightBarrierTrigger(ied.lightBarrierTrigger());
|
|
def.switchTrigger(ied.switchTrigger());
|
|
def.remoteTrigger(ied.remoteTrigger());
|
|
def.explosiveForce(ied.explosiveForce());
|
|
def.partyId(ied.partyId());
|
|
def.tacticalState(ied.tacticalState().underlying());
|
|
LtsUtils::get3Byte(data, pos, x);
|
|
LtsUtils::get3Byte(data, pos, y);
|
|
def.position(relativeFromGeoPosition(x, y));
|
|
|
|
m_tabDts->publish(def);
|
|
}
|
|
}
|
|
|
|
Core::GeoPosition2D HandlerOcAesData::relativeFromGeoPosition(int x, int y)
|
|
{
|
|
const QPointF point(m_utmCoord.geographic(x, y));
|
|
return Core::GeoPosition2D(point.x(), point.y());
|
|
}
|
|
|
|
void HandlerOcAesData::onSpecificsExerciseChanged(const TrainingAreaBaseOC::SpecificsExercise &data, DataModification mod)
|
|
{
|
|
if (mod == DataModification::eAdded || mod == DataModification::eModified)
|
|
m_utmCoord = LtsCoordTrans::UtmCoordinate::fromMgrs(QString::number(data.zone()) +
|
|
QLatin1Char(data.band()) +
|
|
QString::fromStdString(data.square()) +
|
|
QString::number(data.northing()).rightJustified(7, QLatin1Char('0')) +
|
|
QString::number(data.easting()).rightJustified(7, QLatin1Char('0')));
|
|
}
|
|
|
|
} // namespace OcSituationClient
|