Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
@@ -0,0 +1,53 @@
|
||||
#
|
||||
# Commmunication with HlaApacheProxy
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
|
||||
SET(SRCS
|
||||
logger.cpp
|
||||
logger.h
|
||||
main_dispatcher.cpp
|
||||
main_dispatcher.h
|
||||
main_handler_tx.cpp
|
||||
main_handler_tx.h
|
||||
plugin.cpp
|
||||
plugin.h
|
||||
|
||||
hla_dispatcher.cpp
|
||||
hla_dispatcher.h
|
||||
hla_handler_rx.cpp
|
||||
hla_handler_rx.h
|
||||
hla_handler_tx.cpp
|
||||
hla_handler_tx.h
|
||||
ppm_handler.cpp
|
||||
ppm_handler.h
|
||||
pdm_handler.cpp
|
||||
pdm_handler.h
|
||||
aes_handler.cpp
|
||||
aes_handler.h
|
||||
dds_handler.cpp
|
||||
dds_handler.h
|
||||
)
|
||||
NGL_ADD_LIBRARY(AAR SV tabPluginApHla MODULE ${SRCS})
|
||||
NGL_INSTALL_TARGET(tabPluginApHla)
|
||||
NGL_TARGET_LINK_LIBRARIES(tabPluginApHla
|
||||
svcTabServer
|
||||
NGLLogger
|
||||
nglsettings
|
||||
ngltools
|
||||
Qt5::Core
|
||||
Qt5::Network
|
||||
Qt5::WebSockets
|
||||
tabPluginInterface
|
||||
tabTelegrams
|
||||
svcTabCommon
|
||||
svcPpmClient
|
||||
svcPdmClient
|
||||
svcExmClient
|
||||
svcAesClient
|
||||
svcCoreClient
|
||||
ddsconnector
|
||||
LtsUtilsDds
|
||||
)
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
All Telegrams only defined for communication between TAB-Plugin and Apache Virtual Machine
|
||||
|
||||
|
||||
AddParticipant Telegram(Sending updated or added participant to Apache)
|
||||
|
||||
Example Telegram:
|
||||
<pre><code>
|
||||
{
|
||||
typeId:8000,
|
||||
type: ApacheHlaAddParticipant,
|
||||
data:
|
||||
{
|
||||
header: {
|
||||
equipmentNumber: 42,
|
||||
timeStamp: MsecsSinceEpoch
|
||||
},
|
||||
status: 11,
|
||||
forceIdentifier: 42,
|
||||
ets: "2.0.0.0.0.0.1",
|
||||
GeoPosition: {
|
||||
lon: 15.145274,
|
||||
lat: 24.5554556,
|
||||
z: 55.000124
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre></code>
|
||||
|
||||
|
||||
|
||||
RemoveParticipant Telegram(Sending deleted participant to Apache)
|
||||
|
||||
|
||||
Example Telegram:
|
||||
<pre><code>
|
||||
{
|
||||
typeId:8001,
|
||||
type: ApacheHlaRemoveParticipant,
|
||||
data:
|
||||
{
|
||||
header: {
|
||||
equipmentNumber: 42,
|
||||
timeStamp: MsecsSinceEpoch
|
||||
}
|
||||
}
|
||||
}
|
||||
</pre></code>
|
||||
|
||||
Change Position Telegram( Send new Position of participant to Apache)
|
||||
|
||||
Example Telegram:
|
||||
<pre><code>
|
||||
{
|
||||
typeId:8002,
|
||||
type: ApacheHlaPositionChanged,
|
||||
data:
|
||||
{
|
||||
header: {
|
||||
equipmentNumber: 42,
|
||||
timeStamp: MsecsSinceEpoch
|
||||
},
|
||||
lon: 15.275884,
|
||||
lat: 37.854856,
|
||||
z: 42.255278
|
||||
}
|
||||
}
|
||||
</pre></code>
|
||||
|
||||
Change VulnerabilityState Telegram(Sending updated VulnerabilityState to Apache)
|
||||
|
||||
|
||||
Example Telegram:
|
||||
<pre><code>
|
||||
{
|
||||
typeId:8003,
|
||||
type: ApacheHlaVulnerabilityStateChanged,
|
||||
data:
|
||||
{
|
||||
header: {
|
||||
equipmentNumber: 42,
|
||||
timeStamp: MsecsSinceEpoch
|
||||
},
|
||||
status: 11
|
||||
}
|
||||
}
|
||||
</pre></code>
|
||||
|
||||
|
||||
|
||||
AllChargeTypes Telegram(Sending all Charge Types at the beginning of an exercise to Apache)
|
||||
|
||||
|
||||
Example Telegram:
|
||||
|
||||
<pre><code>
|
||||
{
|
||||
typeId:8005,
|
||||
type: ApacheHlaSendChargeTypes,
|
||||
data:
|
||||
[
|
||||
{
|
||||
id: 420,
|
||||
name: 42mm,
|
||||
entityTypeStruct: TestTest,
|
||||
primaryGearTasCode: 11,
|
||||
radius: 7
|
||||
},
|
||||
{
|
||||
id: 777,
|
||||
name: 77mm,
|
||||
entityTypeStruct: TestTest,
|
||||
primaryGearTasCode: 77,
|
||||
radius: 77
|
||||
},
|
||||
{
|
||||
...
|
||||
}
|
||||
]
|
||||
}
|
||||
</pre></code>
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* IsmHandler for WirelessLocationSystem
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-04-14
|
||||
*/
|
||||
|
||||
#include "aes_handler.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
|
||||
|
||||
namespace ApHlaJson
|
||||
{
|
||||
/**
|
||||
* @brief
|
||||
* @author Niklas Schmidt
|
||||
* @details Receives AesModifyRequests from HLA and publish them with Ftc for Aes
|
||||
* HLA -> Excon
|
||||
* @param parent
|
||||
*/
|
||||
AesHandler::AesHandler(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
||||
, m_logger(getLogger("AesHandler"))
|
||||
{}
|
||||
|
||||
bool AesHandler::init(MainDispatcher* mainDispatcher)
|
||||
{
|
||||
m_ftcAes = AreaEffectSimulation::Interface::Ftc::create(mainDispatcher->ddsHandler()->ddsConnector());
|
||||
m_dtcPpm = ParticipantManagement::Interface::Dtc::create(mainDispatcher->ddsHandler()->ddsConnector());
|
||||
if (!m_ftcAes)
|
||||
return false;
|
||||
|
||||
if (!m_ftcAes->enableAirSupportImpactModify())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Can not enableAirSupportImpactModify ";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AesHandler::sendAesModifyRequest(const QJsonObject &data)
|
||||
{
|
||||
int equipmentNumber = data[QStringLiteral("header")].toObject()[QStringLiteral("equipmentNumber")].toInt();
|
||||
|
||||
AreaEffectSimulation::AirSupportImpactModifyRequest request;
|
||||
request.chargeTypeId(data[QStringLiteral("chargeTypeId")].toInt());
|
||||
request.externalId(data[QStringLiteral("eventId")].toInt());
|
||||
request.name(data[QStringLiteral("name")].toString().toStdString());
|
||||
request.impactPosition(Core::GeoPosition2D(data[QStringLiteral("impactPosition")].toObject()[QStringLiteral("lon")].toDouble(),
|
||||
data[QStringLiteral("impactPosition")].toObject()[QStringLiteral("lat")].toDouble()));
|
||||
request.flightTime(0);
|
||||
qint64 requestedTime = static_cast<qint64>(data[QStringLiteral("header")].toObject()[QStringLiteral("timeStamp")].toDouble());
|
||||
if (requestedTime < QDateTime::currentMSecsSinceEpoch())
|
||||
requestedTime = QDateTime::currentMSecsSinceEpoch() + 500;
|
||||
request.effectStart(requestedTime);
|
||||
|
||||
QJsonDocument doc(data);
|
||||
if (equipmentNumber)
|
||||
request.participantId(m_dtcPpm->participantIdByEquipmentNumber(equipmentNumber));
|
||||
m_requestHelper->startSingleRequest([this, request]()
|
||||
{
|
||||
return m_ftcAes->airSupportImpactModifyRequest(request, this);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
void AesHandler::onAirSupportImpactModifyReply(const Core::FunctionReplyObject &reply)
|
||||
{
|
||||
m_requestHelper->requestReply(reply);
|
||||
}
|
||||
|
||||
|
||||
} // namespace ApHlaJson
|
||||
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* IsmHandler for WirelessLocationSystem
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-04-14
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "main_dispatcher.h"
|
||||
#include "logger.h"
|
||||
#include "dds_handler.h"
|
||||
#include <AreaEffectSimulation/aes.hpp>
|
||||
#include <AreaEffectSimulation/aes_ftc.h>
|
||||
#include <ParticipantManagement/ppm.hpp>
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
#include <LtsUtilsCore/data_modification_enum.h>
|
||||
#include <LtsUtilsGuiDds/request_helper.h>
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
#include <QUrl>
|
||||
#include <QDateTime>
|
||||
|
||||
namespace ApHlaJson
|
||||
{
|
||||
|
||||
|
||||
class MainDispatcher;
|
||||
class AesHandler : public QObject
|
||||
, protected AreaEffectSimulation::Interface::Ftc::AirSupportImpactModifyReplyHandler
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit AesHandler(QObject *parent = nullptr);
|
||||
bool init(MainDispatcher* mainDispatcher);
|
||||
bool sendAesModifyRequest(const QJsonObject &obj);
|
||||
void onAirSupportImpactModifyReply(const Core::FunctionReplyObject &reply);
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr<AreaEffectSimulation::Interface::Ftc> m_ftcAes;
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_dtcPpm;
|
||||
LtsUtils::RequestHelper *m_requestHelper;
|
||||
LOGGER_T m_logger;
|
||||
|
||||
|
||||
};
|
||||
|
||||
} // namespace ApHlaJson
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* DdsHandler for DDS
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-04-14
|
||||
*/
|
||||
|
||||
#include "dds_handler.h"
|
||||
|
||||
#include <DDS/Core/pacemaker.h>
|
||||
|
||||
namespace ApHlaJson
|
||||
{
|
||||
|
||||
DdsHandler::DdsHandler(int domainId, int exerciseId)
|
||||
: m_ddsConnector(new DDSConnector::DdsConnector(domainId, IDL::PartitionType::Exercise, exerciseId))
|
||||
, m_logger(getLogger("DdsHandler"))
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "DdsHandler(" << domainId << ") for partition: " << m_ddsConnector->getDefaultPartition();
|
||||
}
|
||||
|
||||
bool DdsHandler::init(const QStringList &qosFileList)
|
||||
{
|
||||
if (!m_ddsConnector->init(qosFileList))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error initializing dds connections - aborting";
|
||||
return false;
|
||||
}
|
||||
|
||||
// default initialize Publisher and Subscriber
|
||||
m_ddsConnector->initPublisherSubscriber();
|
||||
|
||||
// Pacemaker
|
||||
m_pacemaker = std::make_shared<Core::Pacemaker>(m_ddsConnector);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace PatSimJson
|
||||
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* DdsHandler for DDS
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-04-14
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
namespace Core
|
||||
{
|
||||
class Pacemaker;
|
||||
}
|
||||
|
||||
namespace ApHlaJson
|
||||
{
|
||||
class DdsHandler
|
||||
{
|
||||
public:
|
||||
DdsHandler(int domainId, int exerciseId);
|
||||
|
||||
bool init(const QStringList &qosFileList = QStringList());
|
||||
|
||||
std::shared_ptr<Core::Pacemaker> pacemaker() const
|
||||
{
|
||||
return m_pacemaker;
|
||||
}
|
||||
|
||||
std::shared_ptr<DDSConnector::DdsConnector> ddsConnector() const
|
||||
{
|
||||
return m_ddsConnector;
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
|
||||
std::shared_ptr<Core::Pacemaker> m_pacemaker;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* Send / Receive telegrams to/from Hla
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-09-26
|
||||
*/
|
||||
|
||||
#include "hla_dispatcher.h"
|
||||
#include "hla_handler_rx.h"
|
||||
#include "hla_handler_tx.h"
|
||||
|
||||
#include <QSettings>
|
||||
#include <QWebSocket>
|
||||
#include <QTimer>
|
||||
#include <nglsettings/nglsettings_settings.h>
|
||||
|
||||
namespace ApHlaJson
|
||||
{
|
||||
HlaDispatcher::HlaDispatcher(TrainingAreaBase::Plugin::DataProvider *pdp,
|
||||
const std::shared_ptr<TrainingAreaBase::RecvFromTab> &recvFromTabCb,
|
||||
const std::shared_ptr<TrainingAreaBase::TxMixin> &sendToTabCb,
|
||||
NGL::Settings *settings,
|
||||
std::shared_ptr<PpmHandler> ppmHandler,
|
||||
std::shared_ptr<PdmHandler> pdmHandler,
|
||||
std::shared_ptr<AesHandler> aesHandler)
|
||||
: m_recvFromTabCb(recvFromTabCb)
|
||||
, m_recvFromHla(std::make_shared<HlaHandlerRx>(recvFromTabCb, sendToTabCb, this, aesHandler.get(), ppmHandler.get()))
|
||||
, m_sendToHla(std::make_shared<HlaHandlerTx>(pdp, ppmHandler.get(), pdmHandler.get()))
|
||||
, m_settings(settings)
|
||||
, m_webSocket(new QWebSocket(QString(), QWebSocketProtocol::VersionLatest, this))
|
||||
, m_webSocketReconnectTimer(new QTimer(this))
|
||||
, m_bWarnedOnce(false)
|
||||
, m_logger(getLogger("HlaDispatcher"))
|
||||
{
|
||||
connect(m_webSocket, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error),
|
||||
this, &HlaDispatcher::onWebSocketError);
|
||||
connect(m_webSocket, &QWebSocket::connected,
|
||||
this, &HlaDispatcher::onWebSocketConnected);
|
||||
connect(m_webSocket, &QWebSocket::disconnected,
|
||||
this, &HlaDispatcher::onWebsocketDisconnected);
|
||||
connect(m_webSocket, &QWebSocket::binaryMessageReceived,
|
||||
this, &HlaDispatcher::onTextMessageReceived, Qt::UniqueConnection);
|
||||
connect(m_webSocketReconnectTimer, &QTimer::timeout,
|
||||
this, &HlaDispatcher::reallyConnectWebsocket);
|
||||
connect(m_recvFromHla.get(), &HlaHandlerRx::participantConnectionState,
|
||||
m_sendToHla.get(), &HlaHandlerTx::onParticipantConnectionState);
|
||||
}
|
||||
|
||||
bool HlaDispatcher::init()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void HlaDispatcher::connectWebsocket()
|
||||
{
|
||||
const QUrl url(webSocketUrl());
|
||||
if (!m_bWarnedOnce)
|
||||
NOTICE_LOG(m_logger) << "Using WebSocket url: " << url.toString();
|
||||
if (m_webSocket->state() != QAbstractSocket::ConnectedState)
|
||||
m_webSocket->open(url);
|
||||
}
|
||||
|
||||
std::shared_ptr<TrainingAreaBase::SendToTab> HlaDispatcher::sendToTab()
|
||||
{
|
||||
return std::static_pointer_cast<TrainingAreaBase::SendToTab>(m_sendToHla);
|
||||
}
|
||||
|
||||
bool HlaDispatcher::canSendData() const
|
||||
{
|
||||
return m_webSocket && m_webSocket->state() == QAbstractSocket::ConnectedState;
|
||||
}
|
||||
|
||||
void HlaDispatcher::onWebSocketConnected()
|
||||
{
|
||||
INFO_LOG(m_logger) << "WebSocket connected";
|
||||
QWebSocket *ws = qobject_cast<QWebSocket *>(sender());
|
||||
m_sendToHla->onWebSocketConnected(ws);
|
||||
m_webSocketReconnectTimer->stop();
|
||||
m_bWarnedOnce = false;
|
||||
}
|
||||
|
||||
void HlaDispatcher::onWebsocketDisconnected()
|
||||
{
|
||||
INFO_LOG(m_logger) << "Hla socket disconnected";
|
||||
m_sendToHla->onWebSocketDisconnected();
|
||||
|
||||
emit connectionState(QString::fromUtf8(name()), false);
|
||||
|
||||
m_webSocketReconnectTimer->start(5000);
|
||||
}
|
||||
|
||||
void HlaDispatcher::onHlaExternalConnectionStateChanged(bool bConnected)
|
||||
{
|
||||
m_sendToHla->onHlaConnectedToExternalSystem(bConnected);
|
||||
emit connectionState(QString::fromUtf8(name()), bConnected);
|
||||
}
|
||||
|
||||
void HlaDispatcher::onWebSocketError()
|
||||
{
|
||||
if (!m_webSocket)
|
||||
return;
|
||||
if (!m_bWarnedOnce)
|
||||
WARNING_LOG(m_logger) << "Error connecting to " << webSocketUrl().toString() << ": " << m_webSocket->errorString();
|
||||
m_webSocket->close();
|
||||
m_webSocketReconnectTimer->start(5000);
|
||||
m_bWarnedOnce = true;
|
||||
|
||||
emit connectionState(QString::fromUtf8(name()), false);
|
||||
}
|
||||
|
||||
void HlaDispatcher::onTextMessageReceived(const QByteArray &message)
|
||||
{
|
||||
|
||||
INFO_LOG(m_logger) << "Text Message received: " << message;
|
||||
// convert from json to internal representation, send to TAB
|
||||
m_recvFromHla->handleTelegram(message);
|
||||
}
|
||||
|
||||
QUrl HlaDispatcher::webSocketUrl() const
|
||||
{
|
||||
const quint16 port = m_settings->settings()->value(QStringLiteral("aphla/webSocketListenPort"), 12345).toInt();
|
||||
const QString addr = m_settings->settings()->value(QStringLiteral("aphla/webSocketHostname"), QStringLiteral("172.25.160.11")).toString();
|
||||
return QUrl(QStringLiteral("ws://%1:%2/").arg(addr).arg(port));
|
||||
}
|
||||
} // namespace HlaJson
|
||||
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Send / Receive telegrams to/from Hla
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-09-26
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <QWebSocket>
|
||||
#include <TrainingAreaBase/tab_plugin_interface.h>
|
||||
#include <DDS/Core/function_reply_object.h> // tr_lts
|
||||
#include "logger.h"
|
||||
#include "ppm_handler.h"
|
||||
#include "aes_handler.h"
|
||||
#include "pdm_handler.h"
|
||||
|
||||
class QTimer;
|
||||
namespace ApHlaJson
|
||||
{
|
||||
class HlaHandlerRx;
|
||||
class HlaHandlerTx;
|
||||
|
||||
class HlaDispatcher final : public TrainingAreaBase::Plugin::Interface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HlaDispatcher(TrainingAreaBase::Plugin::DataProvider *pdp,
|
||||
const std::shared_ptr<TrainingAreaBase::RecvFromTab> &recvFromTabCb,
|
||||
const std::shared_ptr<TrainingAreaBase::TxMixin> &sendToTabCb,
|
||||
NGL::Settings *settings,
|
||||
std::shared_ptr<PpmHandler> ppmHandler,
|
||||
std::shared_ptr<PdmHandler> pdmHandler,
|
||||
std::shared_ptr<AesHandler> aesHandler);
|
||||
|
||||
public Q_SLOTS:
|
||||
bool init() override;
|
||||
public:
|
||||
std::shared_ptr<TrainingAreaBase::SendToTab> sendToTab() override;
|
||||
bool isDebugInterface() const override { return false; }
|
||||
bool canSendData() const override;
|
||||
void exerciseChanged() override { return; }
|
||||
const char *name() const override { return tr_lts("dds", "APHLA"); }
|
||||
public Q_SLOTS:
|
||||
void onWebSocketConnected();
|
||||
void onWebsocketDisconnected();
|
||||
void onHlaExternalConnectionStateChanged(bool bConnected);
|
||||
void onWebSocketError();
|
||||
void onTextMessageReceived(const QByteArray &message);
|
||||
void connectWebsocket();
|
||||
void reallyConnectWebsocket() { connectWebsocket(); }
|
||||
Q_SIGNALS:
|
||||
void broadcastTelegramsRequest(int equipmentNumber, int broadcastIndex, int resetCounter);
|
||||
void hlaTelegramReceived(const TrainingAreaBase::TetraIcd::TrainingAreaTelegram *tele);
|
||||
private:
|
||||
QUrl webSocketUrl() const;
|
||||
private:
|
||||
std::shared_ptr<TrainingAreaBase::RecvFromTab> m_recvFromTabCb;
|
||||
std::shared_ptr<HlaHandlerRx> m_recvFromHla;
|
||||
std::shared_ptr<HlaHandlerTx> m_sendToHla;
|
||||
NGL::Settings *m_settings;
|
||||
QWebSocket *m_webSocket;
|
||||
QTimer *m_webSocketReconnectTimer;
|
||||
bool m_bWarnedOnce;
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
|
||||
} // namespace HlaJson
|
||||
@@ -0,0 +1,176 @@
|
||||
/**
|
||||
* Convert Json from WLS to internal telegrams
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-09-26
|
||||
*/
|
||||
|
||||
#include "hla_handler_rx.h"
|
||||
#include "hla_dispatcher.h"
|
||||
#include "aes_handler.h"
|
||||
#include "ppm_handler.h"
|
||||
#include <TrainingAreaBase/training_area_telegrams.h>
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace ApHlaJson
|
||||
{
|
||||
/*!
|
||||
* \brief HlaHandlerRx::HlaHandlerRx
|
||||
* \param recvFromTabCb
|
||||
* \param sendToTabCb
|
||||
* \param dispatcher
|
||||
* \param aesHandler
|
||||
* \param ppmHandler
|
||||
* \author Niklas Schmidt
|
||||
* \details Handles all incoming telegrams from Apache
|
||||
*/
|
||||
HlaHandlerRx::HlaHandlerRx(const std::shared_ptr<TrainingAreaBase::RecvFromTab> &recvFromTabCb,
|
||||
const std::shared_ptr<TrainingAreaBase::TxMixin> &sendToTabCb,
|
||||
HlaDispatcher *dispatcher,
|
||||
AesHandler* aesHandler,
|
||||
PpmHandler* ppmHandler)
|
||||
: m_rxHandler(recvFromTabCb)
|
||||
, m_txHandler(sendToTabCb)//std::static_pointer_cast<TrainingAreaBase::SendToTab>(sendToTabCb))
|
||||
, m_dispatcher(dispatcher)
|
||||
, m_bWarnedOnce(false)
|
||||
, m_bWarnedOnceTx(false)
|
||||
, m_aesHandler(aesHandler)
|
||||
, m_ppmHandler(ppmHandler)
|
||||
, m_logger(getLogger("HlaHandlerRx"))
|
||||
{}
|
||||
|
||||
bool HlaHandlerRx::handleTelegram(const QByteArray &baJson)
|
||||
{
|
||||
using namespace TrainingAreaBase::TetraIcd;
|
||||
|
||||
if (baJson.isEmpty())
|
||||
return false;
|
||||
const QJsonObject obj = QJsonDocument::fromJson(baJson).object();
|
||||
|
||||
|
||||
const QJsonValue typeId = obj.value(QStringLiteral("typeId"));
|
||||
if (!typeId.isDouble())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Can not read type id: " << baJson;
|
||||
return false;
|
||||
}
|
||||
const QJsonObject data = obj.value(QStringLiteral("data")).toObject();
|
||||
if(typeId.toInt() != 21)
|
||||
ERROR_LOG(m_logger) << "Telegram before filter: " << baJson;
|
||||
try
|
||||
{
|
||||
QJsonValue header = data[QStringLiteral("header")];
|
||||
QJsonObject obj = header.toObject();
|
||||
if (!obj.isEmpty())
|
||||
{
|
||||
int eqNo = obj[QStringLiteral("equipmentNumber")].toInt(0);
|
||||
if (eqNo <= 0)
|
||||
return false;
|
||||
if (!checkExercise(eqNo))
|
||||
return false;
|
||||
}
|
||||
if(typeId.toInt() != 21)
|
||||
ERROR_LOG(m_logger) << "Telegram after filter: " << baJson;
|
||||
switch (typeId.toInt())
|
||||
{
|
||||
case Constraints<ProxyConnectionState>::id(): // 2013
|
||||
{
|
||||
bool connected = ProxyConnectionState::fromJson(data).connectedToSystem;
|
||||
m_dispatcher->onHlaExternalConnectionStateChanged(connected);
|
||||
}
|
||||
break;
|
||||
case Constraints<CesHitInformation>::id(): // 211
|
||||
if(checkExercise(data[QStringLiteral("originatorEquipmentNumber")].toInt()))
|
||||
txData(CesHitInformation::fromJson(data));
|
||||
break;
|
||||
case Constraints<PositionReport>::id(): // 21
|
||||
rxData(PositionReport::fromJson(data));
|
||||
break;
|
||||
case Constraints<StateChangeDirect>::id(): //has originator
|
||||
rxData(StateChangeDirect::fromJson(data));
|
||||
break;
|
||||
case Constraints<StateChange>::id(): //has originator
|
||||
rxData(StateChange::fromJson(data));
|
||||
break;
|
||||
case Constraints<EquipmentGearEvent>::id():
|
||||
rxData(EquipmentGearEvent::fromJson(data));
|
||||
break;
|
||||
case Constraints<EquipmentGearAssignment>::id():
|
||||
rxData(EquipmentGearAssignment::fromJson(data));
|
||||
break;
|
||||
case Constraints<EquipmentGearChargeState>::id():
|
||||
rxData(EquipmentGearChargeState::fromJson(data));
|
||||
break;
|
||||
case Constraints<SpecialSensorData>::id():
|
||||
rxData(SpecialSensorData::fromJson(data));
|
||||
break;
|
||||
case 8006 :
|
||||
m_aesHandler->sendAesModifyRequest(data);
|
||||
break;
|
||||
case Constraints<ApacheLaserDesignation>::id():
|
||||
rxData(ApacheLaserDesignation::fromJson(data));
|
||||
break;
|
||||
case Constraints<WlsParticipantsConnectionState>::id(): // 3004
|
||||
{
|
||||
const auto tele = WlsParticipantsConnectionState::fromJson(data);
|
||||
if (checkExercise(tele.equipmentNumber))
|
||||
emit participantConnectionState(tele.equipmentNumber, tele.dataCommunicationPossible);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
WARNING_LOG(m_logger) << "Could not parse json: " << e.what() << " (" << baJson << ")";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief
|
||||
\details Check if Participant is in same Exercise than the TAB-Process is
|
||||
\param equipmentNumber
|
||||
\return bool
|
||||
*/
|
||||
bool HlaHandlerRx::checkExercise(int equipmentNumber) const
|
||||
{
|
||||
return m_ppmHandler->isEqNumberInExercise(equipmentNumber);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void HlaHandlerRx::rxData(const T &data)
|
||||
{
|
||||
if (!m_rxHandler)
|
||||
{
|
||||
if (!m_bWarnedOnce)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "No RecvFromTab available";
|
||||
m_bWarnedOnce = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
emit m_dispatcher->hlaTelegramReceived(&data);
|
||||
return m_rxHandler->rxData(data);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void HlaHandlerRx::txData(const T &data)
|
||||
{
|
||||
if (!m_txHandler)
|
||||
{
|
||||
if (!m_bWarnedOnceTx)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "No RecvFromTab available";
|
||||
m_bWarnedOnceTx = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
emit m_dispatcher->hlaTelegramReceived(&data);
|
||||
m_txHandler->txData(data);
|
||||
}
|
||||
|
||||
} // namespace HlaJson
|
||||
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Convert Json from WLS to internal telegrams
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-09-26
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <TrainingAreaBase/recv_from_tab.h>
|
||||
#include <TrainingAreaBase/tx_mixin.h>
|
||||
#include <TrainingAreaBase/tab_plugin_interface.h>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <memory>
|
||||
#include "logger.h"
|
||||
|
||||
namespace ApHlaJson
|
||||
{
|
||||
class AesHandler;
|
||||
class PpmHandler;
|
||||
class HlaDispatcher;
|
||||
class HlaHandlerRx : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit HlaHandlerRx(const std::shared_ptr<TrainingAreaBase::RecvFromTab> &recvFromTabCb,
|
||||
const std::shared_ptr<TrainingAreaBase::TxMixin> &sendToTabCb,
|
||||
HlaDispatcher *dispatcher,
|
||||
AesHandler* aesHandler,
|
||||
PpmHandler* ppmHandler);
|
||||
|
||||
bool handleTelegram(const QByteArray &baJson);
|
||||
bool handleTelegram(TrainingAreaBase::TetraIcd::TrainingAreaTelegram *tabTele);
|
||||
Q_SIGNALS:
|
||||
void participantConnectionState(int equipmentNumber, bool dataCommunicationPossible);
|
||||
private:
|
||||
template<typename T>
|
||||
void rxData(const T &data);
|
||||
|
||||
template<typename T>
|
||||
void txData(const T &data);
|
||||
private:
|
||||
bool checkExercise(int equipmentNumber) const;
|
||||
|
||||
std::shared_ptr<TrainingAreaBase::RecvFromTab> m_rxHandler;
|
||||
std::shared_ptr<TrainingAreaBase::TxMixin> m_txHandler;
|
||||
HlaDispatcher *m_dispatcher;
|
||||
bool m_bWarnedOnce;
|
||||
bool m_bWarnedOnceTx;
|
||||
AesHandler* m_aesHandler;
|
||||
PpmHandler* m_ppmHandler;
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
} // namespace HlaJson
|
||||
@@ -0,0 +1,343 @@
|
||||
/**
|
||||
* Convert telegrams to Json and sent to WLS proxy
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-09-26
|
||||
*/
|
||||
|
||||
#include "hla_handler_tx.h"
|
||||
#include "ppm_handler.h"
|
||||
#include "pdm_handler.h"
|
||||
#include <QJsonDocument>
|
||||
#include <QWebSocket>
|
||||
namespace ApHlaJson
|
||||
{
|
||||
class PpmHandler;
|
||||
HlaHandlerTx::HlaHandlerTx(TrainingAreaBase::Plugin::DataProvider *pdp, PpmHandler* ppmHandler, PdmHandler* pdmHandler)
|
||||
: m_pdp(pdp)
|
||||
, m_ppmHandler(ppmHandler)
|
||||
, m_pdmHandler(pdmHandler)
|
||||
, m_webSocket(nullptr)
|
||||
, m_bHlaConnectedToExternalSystem(false)
|
||||
, m_logger(getLogger("HlaHandlerTx"))
|
||||
{}
|
||||
|
||||
void HlaHandlerTx::onWebSocketConnected(QWebSocket *webSocket)
|
||||
{
|
||||
m_webSocket = webSocket;
|
||||
if (!m_webSocket)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void HlaHandlerTx::onWebSocketDisconnected()
|
||||
{
|
||||
m_ppmHandler->disconnect(this);
|
||||
m_pdmHandler->disconnect(this);
|
||||
m_webSocket = nullptr;
|
||||
}
|
||||
|
||||
void HlaHandlerTx::onHlaConnectedToExternalSystem(bool bConnected)
|
||||
{
|
||||
m_bHlaConnectedToExternalSystem = bConnected;
|
||||
|
||||
NOTICE_LOG(m_logger) << "Connected to Old HLA Interface - exercise environment, charges and participants";
|
||||
const auto tele2 = m_pdp->exerciseEnvironmentData();
|
||||
sendToTx(&tele2, true);
|
||||
connect(m_ppmHandler, &PpmHandler::participantChanged, this, &HlaHandlerTx::onGenericTelegram, Qt::UniqueConnection);
|
||||
connect(m_pdmHandler, &PdmHandler::sendChargeTypes, this, &HlaHandlerTx::onGenericTelegram, Qt::UniqueConnection);
|
||||
m_pdmHandler->getChargeTypes();
|
||||
m_ppmHandler->getParticipants();
|
||||
}
|
||||
|
||||
TrainingAreaBase::SendToTab::HandleState HlaHandlerTx::canHandleTelegram(int equipmentNumber, int telegramId) const
|
||||
{
|
||||
if (!m_webSocket || !m_bHlaConnectedToExternalSystem)
|
||||
return HandleState::No;
|
||||
|
||||
using namespace TrainingAreaBase::TetraIcd;
|
||||
// if (telegramId == Constraints<ExerciseEquipmentAssignmentComplete>::id() ||
|
||||
// telegramId == Constraints<ExerciseStateData>::id())
|
||||
// return HandleState::YesShare;
|
||||
|
||||
if (equipmentNumber <= 0 || !m_dataCommunicationPossible.value(equipmentNumber, false))
|
||||
return HandleState::No;
|
||||
|
||||
if (telegramId == Constraints<Init>::id() ||
|
||||
telegramId == Constraints<DemandVulnerabilityStateChange>::id() ||
|
||||
telegramId == Constraints<SelectiveReammunition>::id() ||
|
||||
telegramId == Constraints<CesHitInformation>::id()
|
||||
)
|
||||
return HandleState::YesConsume;
|
||||
|
||||
return HandleState::No;
|
||||
}
|
||||
|
||||
void HlaHandlerTx::resetSendCounter()
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::Init &data)
|
||||
{
|
||||
return sendToTx(&data);
|
||||
}
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::DemandVulnerabilityStateChange &data)
|
||||
{
|
||||
return sendToTx(&data);
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::CesHitInformation &data)
|
||||
{
|
||||
return sendToTx(&data);
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::ExerciseEnvironmentData &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::Acknowledge &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::DemandBite &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::SetVulnerabilityModel &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::DemandEquipmentConfigurationReport &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::LanguageSelection &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::EquipmentMessage &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::EquipmentMessageOC &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::CreateSingleExplosion &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::CreateAreaExplosion &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::CreateMineArea &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::MineAreaSingleMineState &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::CreateNContamination &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::CreateCContamination &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::DeactivateEffectSimulation &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::ModifyAreaEffectSimulationName &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::PauseEffectSimulation &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::ResumeEffectSimulation &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::MineTriggered &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::DusMineReactivation &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::CreateFunctionalArea &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::CreateDusSingleMine &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::ExerciseStateData &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::OpaquePayloadDataOut &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::ParticipantSwVersionsRequest &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::TechnicalArea &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false; // only for Tetra - really?
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::CesHitRequest &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::ParticipantMode &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::DemandParticipantMode &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::ParticipantConfiguration &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::DemandParticipantConfiguration &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::ExerciseEquipmentAssignmentComplete &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::Sanitation &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HlaHandlerTx::txData(const TrainingAreaBase::TetraIcd::SelectiveReammunition &data)
|
||||
{
|
||||
Q_UNUSED(data);
|
||||
return false;
|
||||
}
|
||||
|
||||
void HlaHandlerTx::onParticipantConnectionState(int equipmentNumber, bool dataCommunicationPossible)
|
||||
{
|
||||
INFO_LOG(m_logger) << "onParticipantConnectionState - " << equipmentNumber
|
||||
<< ", communication possible: " << dataCommunicationPossible;
|
||||
if (equipmentNumber == -1)
|
||||
m_dataCommunicationPossible.clear();
|
||||
m_dataCommunicationPossible[equipmentNumber] = dataCommunicationPossible;
|
||||
}
|
||||
|
||||
void HlaHandlerTx::onGenericTelegram(const QJsonObject &telegram)
|
||||
{
|
||||
if (!m_webSocket || !m_bHlaConnectedToExternalSystem)
|
||||
return;
|
||||
const QByteArray ba = QJsonDocument(telegram).toJson(QJsonDocument::Compact);
|
||||
DEBUG_LOG(m_logger) << "Sending tele: " << ba;
|
||||
m_webSocket->sendTextMessage(QString::fromUtf8(ba));
|
||||
}
|
||||
|
||||
|
||||
bool HlaHandlerTx::sendToTx(const TrainingAreaBase::TetraIcd::TrainingAreaTelegram *data, bool bForce)
|
||||
{
|
||||
Q_UNUSED(bForce);
|
||||
QJsonObject telegram;
|
||||
telegram[QStringLiteral("data")] = data->toJson();
|
||||
telegram[QStringLiteral("type")] = data->type();
|
||||
telegram[QStringLiteral("typeId")] = data->id();
|
||||
onGenericTelegram(telegram);
|
||||
return true;
|
||||
}
|
||||
|
||||
QHash<int, bool> HlaHandlerTx::dataCommunicationPossible() const
|
||||
{
|
||||
return m_dataCommunicationPossible;
|
||||
}
|
||||
|
||||
|
||||
} // namespace HlaJson
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* Convert telegrams to Json and sent to WLS proxy
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-09-26
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ppm_handler.h"
|
||||
#include "pdm_handler.h"
|
||||
#include "logger.h"
|
||||
#include <TrainingAreaBase/send_to_tab.h>
|
||||
#include <TrainingAreaBase/recv_from_tab.h>
|
||||
#include <TrainingAreaBase/tab_plugin_interface.h>
|
||||
#include <QHash>
|
||||
|
||||
class QWebSocket;
|
||||
class PpmHandler;
|
||||
class PdmHandler;
|
||||
namespace ApHlaJson
|
||||
{
|
||||
class HlaHandlerTx final : public QObject, public TrainingAreaBase::SendToTab
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit HlaHandlerTx(TrainingAreaBase::Plugin::DataProvider *pdp, PpmHandler* ppmHandler, PdmHandler* pdmHandler);
|
||||
|
||||
void onWebSocketConnected(QWebSocket *webSocket);
|
||||
void onWebSocketDisconnected();
|
||||
void onHlaConnectedToExternalSystem(bool bConnected);
|
||||
|
||||
const char *name() const override { return "ApHla"; }
|
||||
HandleState canHandleTelegram(int equipmentNumber, int telegramId) const override;
|
||||
void resetSendCounter() override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::Acknowledge &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::DemandBite &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::Init &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::SetVulnerabilityModel &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::DemandEquipmentConfigurationReport &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::DemandVulnerabilityStateChange &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::LanguageSelection &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::EquipmentMessage &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::EquipmentMessageOC &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::CreateSingleExplosion &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::CreateAreaExplosion &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::CreateMineArea &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::MineAreaSingleMineState &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::CreateNContamination &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::CreateCContamination &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::DeactivateEffectSimulation &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::ModifyAreaEffectSimulationName &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::PauseEffectSimulation &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::ResumeEffectSimulation &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::MineTriggered &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::DusMineReactivation &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::CreateFunctionalArea &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::CreateDusSingleMine &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::ExerciseEnvironmentData &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::ExerciseStateData &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::OpaquePayloadDataOut &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::ParticipantSwVersionsRequest &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::CesHitInformation &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::TechnicalArea &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::CesHitRequest &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::ParticipantMode &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::DemandParticipantMode &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::ParticipantConfiguration &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::DemandParticipantConfiguration &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::ExerciseEquipmentAssignmentComplete &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::Sanitation &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::SelectiveReammunition &data) override;
|
||||
|
||||
QHash<int, bool> dataCommunicationPossible() const;
|
||||
|
||||
public slots:
|
||||
void onParticipantConnectionState(int equipmentNumber, bool dataCommunicationPossible);
|
||||
void onGenericTelegram(const QJsonObject &telegram);
|
||||
|
||||
private:
|
||||
bool sendToTx(const TrainingAreaBase::TetraIcd::TrainingAreaTelegram *data, bool bForce = false);
|
||||
private:
|
||||
QHash<int, bool> m_dataCommunicationPossible; // equioNo, reachable
|
||||
TrainingAreaBase::Plugin::DataProvider *m_pdp;
|
||||
PpmHandler* m_ppmHandler;
|
||||
PdmHandler* m_pdmHandler;
|
||||
QWebSocket *m_webSocket;
|
||||
bool m_bHlaConnectedToExternalSystem;
|
||||
LOGGER_T m_logger;
|
||||
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Building Config - logging facility
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-04-14
|
||||
*/
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
|
||||
namespace ApHlaJson
|
||||
{
|
||||
|
||||
LOGGER_T getLogger(const char *name)
|
||||
{
|
||||
static const char ns[] = "TAB.APHLA.";
|
||||
std::string loggerName;
|
||||
const size_t len = strlen(name);
|
||||
loggerName.reserve(sizeof(ns) + len);
|
||||
loggerName.append(ns, sizeof(ns) - 1);
|
||||
loggerName.append(name, len);
|
||||
|
||||
try
|
||||
{
|
||||
return NGL::NGLLoggerBootstrap::getNGLRootLogger().
|
||||
getNGLLogger(loggerName);
|
||||
}
|
||||
catch (const std::exception &ex)
|
||||
{
|
||||
fprintf(stderr, "Error retrieving logger: %s", ex.what());
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace HlaJson
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* Logging for TrainingAreaBase
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-04-14
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
|
||||
namespace ApHlaJson
|
||||
{
|
||||
using LOGGER_T = NGL::INGLLogger&;
|
||||
|
||||
LOGGER_T getLogger(const char *name);
|
||||
inline LOGGER_T getLogger(const QString &loggerName)
|
||||
{
|
||||
return getLogger(loggerName.toUtf8().constData());
|
||||
}
|
||||
} // namespace HlaJson
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* Send / Receive telegrams to/from Hla
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-09-26
|
||||
*/
|
||||
|
||||
#include "main_dispatcher.h"
|
||||
#include "main_handler_tx.h"
|
||||
#include "hla_dispatcher.h"
|
||||
#include "hla_handler_tx.h"
|
||||
#include <nglsettings/nglsettings_settings.h>
|
||||
#include <QTimer>
|
||||
|
||||
namespace ApHlaJson
|
||||
{
|
||||
MainDispatcher::MainDispatcher(TrainingAreaBase::Plugin::DataProvider *pdp,
|
||||
const std::shared_ptr<TrainingAreaBase::RecvFromTab> &recvFromTabCb,
|
||||
const std::shared_ptr<TrainingAreaBase::TxMixin> &sendToTab,
|
||||
NGL::Settings *settings)
|
||||
: m_hlaDispatcher(nullptr)
|
||||
, m_recvFromTabCb(recvFromTabCb)
|
||||
, m_sendToTab(sendToTab)
|
||||
, m_mainHandlerTx(nullptr)
|
||||
, m_pdp(pdp)
|
||||
, m_settings(settings)
|
||||
, m_logger(getLogger("MainDispatcher"))
|
||||
, m_domainId(pdp->domainId())
|
||||
, m_exerciseId(pdp->exerciseId())
|
||||
{
|
||||
INFO_LOG(m_logger) << "ApHla started, Domain Id: " << m_domainId << " ExerciseId: " << m_exerciseId;
|
||||
}
|
||||
|
||||
MainDispatcher::~MainDispatcher()
|
||||
{
|
||||
m_mainHandlerTx = nullptr;
|
||||
m_recvFromTabCb = nullptr;
|
||||
m_ddsHandler = nullptr;
|
||||
m_ppmHandler = nullptr;
|
||||
m_pdmHandler = nullptr;
|
||||
m_aesHandler = nullptr;
|
||||
delete m_hlaDispatcher;
|
||||
}
|
||||
|
||||
bool MainDispatcher::init()
|
||||
{
|
||||
m_ddsHandler = std::make_shared<DdsHandler>(m_domainId, m_exerciseId);
|
||||
if (!m_ddsHandler->init())
|
||||
return false;
|
||||
|
||||
m_pdmHandler = std::make_shared<PdmHandler>();
|
||||
|
||||
m_pdmHandler->init(this);
|
||||
|
||||
m_ppmHandler = std::make_shared<PpmHandler>();
|
||||
|
||||
m_ppmHandler->init(this);
|
||||
|
||||
m_aesHandler = std::make_shared<AesHandler>();
|
||||
|
||||
m_aesHandler->init(this);
|
||||
|
||||
m_hlaDispatcher = new HlaDispatcher(m_pdp, m_recvFromTabCb, m_sendToTab, m_settings, m_ppmHandler, m_pdmHandler, m_aesHandler);
|
||||
m_mainHandlerTx = std::make_shared<MainHandlerTx>(std::dynamic_pointer_cast<HlaHandlerTx>(m_hlaDispatcher->sendToTab()));
|
||||
m_hlaDispatcher->init();
|
||||
|
||||
m_hlaDispatcher->connectWebsocket();
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<TrainingAreaBase::SendToTab> MainDispatcher::sendToTab()
|
||||
{
|
||||
return std::static_pointer_cast<TrainingAreaBase::SendToTab>(m_mainHandlerTx);
|
||||
}
|
||||
|
||||
bool MainDispatcher::canSendData() const
|
||||
{
|
||||
return m_hlaDispatcher->canSendData();
|
||||
}
|
||||
|
||||
void MainDispatcher::exerciseChanged()
|
||||
{
|
||||
m_hlaDispatcher->exerciseChanged();
|
||||
}
|
||||
|
||||
} // namespace ApHlaJson
|
||||
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Send / Receive telegrams to/from Hla
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-09-26
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <TrainingAreaBase/tab_plugin_interface.h>
|
||||
#include <DDS/Core/function_reply_object.h> // tr_lts
|
||||
#include "dds_handler.h"
|
||||
#include "logger.h"
|
||||
#include "ppm_handler.h"
|
||||
#include "pdm_handler.h"
|
||||
#include "aes_handler.h"
|
||||
|
||||
namespace ApHlaJson
|
||||
{
|
||||
class HlaDispatcher;
|
||||
class PpmHandler;
|
||||
class PdmHandler;
|
||||
class AesHandler;
|
||||
|
||||
class MainDispatcher final : public TrainingAreaBase::Plugin::Interface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MainDispatcher(TrainingAreaBase::Plugin::DataProvider *pdp,
|
||||
const std::shared_ptr<TrainingAreaBase::RecvFromTab> &recvFromTabCb,
|
||||
const std::shared_ptr<TrainingAreaBase::TxMixin> &sendToTabCb,
|
||||
NGL::Settings *settings);
|
||||
~MainDispatcher();
|
||||
|
||||
std::shared_ptr<PpmHandler> ppmHandler() const
|
||||
{
|
||||
return m_ppmHandler;
|
||||
}
|
||||
std::shared_ptr<PdmHandler> pdmHandler() const
|
||||
{
|
||||
return m_pdmHandler;
|
||||
}
|
||||
std::shared_ptr<AesHandler> aesHandler() const
|
||||
{
|
||||
return m_aesHandler;
|
||||
}
|
||||
std::shared_ptr<DdsHandler> ddsHandler() const
|
||||
{
|
||||
return m_ddsHandler;
|
||||
}
|
||||
int exerciseId() const
|
||||
{
|
||||
return m_exerciseId;
|
||||
}
|
||||
|
||||
public slots:
|
||||
bool init() override;
|
||||
|
||||
public:
|
||||
std::shared_ptr<TrainingAreaBase::SendToTab> sendToTab() override;
|
||||
bool isDebugInterface() const override { return false; }
|
||||
bool canSendData() const override;
|
||||
void exerciseChanged() override;
|
||||
const char *name() const override { return tr_lts("dds", "ApHlaJson"); }
|
||||
|
||||
private:
|
||||
HlaDispatcher *m_hlaDispatcher;
|
||||
|
||||
std::shared_ptr<TrainingAreaBase::RecvFromTab> m_recvFromTabCb;
|
||||
const std::shared_ptr<TrainingAreaBase::TxMixin> m_sendToTab;
|
||||
std::shared_ptr<TrainingAreaBase::SendToTab> m_mainHandlerTx;
|
||||
TrainingAreaBase::Plugin::DataProvider *m_pdp;
|
||||
NGL::Settings *m_settings;
|
||||
std::shared_ptr<PpmHandler> m_ppmHandler;
|
||||
std::shared_ptr<PdmHandler> m_pdmHandler;
|
||||
std::shared_ptr<AesHandler> m_aesHandler;
|
||||
std::shared_ptr<DdsHandler> m_ddsHandler;
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
int m_domainId;
|
||||
int m_exerciseId;
|
||||
};
|
||||
} // namespace HlaJson
|
||||
@@ -0,0 +1,222 @@
|
||||
/**
|
||||
* Convert telegrams to Json and sent to WLS proxy
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-09-26
|
||||
*/
|
||||
|
||||
#include "main_handler_tx.h"
|
||||
#include "hla_handler_tx.h"
|
||||
|
||||
using namespace TrainingAreaBase;
|
||||
|
||||
namespace ApHlaJson
|
||||
{
|
||||
MainHandlerTx::MainHandlerTx(const std::shared_ptr<HlaHandlerTx> &hlaTx)
|
||||
: m_hlaHandlerTx(hlaTx)
|
||||
, m_logger(getLogger("MainHandlerTx"))
|
||||
{}
|
||||
|
||||
SendToTab::HandleState MainHandlerTx::canHandleTelegram(int equipmentNumber, int telegramId) const
|
||||
{
|
||||
return m_hlaHandlerTx->canHandleTelegram(equipmentNumber, telegramId);
|
||||
}
|
||||
|
||||
void MainHandlerTx::resetSendCounter()
|
||||
{
|
||||
m_hlaHandlerTx->resetSendCounter();
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::Acknowledge &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::DemandBite &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::Init &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::SetVulnerabilityModel &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::DemandEquipmentConfigurationReport &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::DemandVulnerabilityStateChange &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::LanguageSelection &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::EquipmentMessage &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::EquipmentMessageOC &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::CreateSingleExplosion &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::CreateAreaExplosion &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::CreateMineArea &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::MineAreaSingleMineState &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::CreateNContamination &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::CreateCContamination &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::DeactivateEffectSimulation &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::ModifyAreaEffectSimulationName &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::PauseEffectSimulation &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::ResumeEffectSimulation &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::MineTriggered &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::DusMineReactivation &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::CreateFunctionalArea &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::CreateDusSingleMine &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::ExerciseEnvironmentData &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::ExerciseStateData &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::OpaquePayloadDataOut &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::ParticipantSwVersionsRequest &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::TechnicalArea &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::CesHitInformation &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::CesHitRequest &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::ParticipantMode &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::DemandParticipantMode &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::ParticipantConfiguration &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::DemandParticipantConfiguration &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::ExerciseEquipmentAssignmentComplete &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::Sanitation &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
bool MainHandlerTx::txData(const TetraIcd::SelectiveReammunition &data)
|
||||
{
|
||||
return sendToTxMixin(&data);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool MainHandlerTx::sendToTxMixin(const T *data)
|
||||
{
|
||||
return m_hlaHandlerTx->txData(*data);
|
||||
}
|
||||
|
||||
} // namespace HlaJson
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Convert telegrams to Json and sent to WLS proxy
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-09-26
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include "logger.h"
|
||||
#include <TrainingAreaBase/send_to_tab.h>
|
||||
#include <memory>
|
||||
|
||||
class QWebSocket;
|
||||
namespace ApHlaJson
|
||||
{
|
||||
class HlaHandlerTx;
|
||||
|
||||
class MainHandlerTx final : public QObject, public TrainingAreaBase::SendToTab
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MainHandlerTx(const std::shared_ptr<HlaHandlerTx> &hlaTx);
|
||||
|
||||
const char *name() const override { return "HlaJson"; }
|
||||
HandleState canHandleTelegram(int equipmentNumber, int telegramId) const override;
|
||||
void resetSendCounter() override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::Acknowledge &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::DemandBite &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::Init &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::SetVulnerabilityModel &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::DemandEquipmentConfigurationReport &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::DemandVulnerabilityStateChange &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::LanguageSelection &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::EquipmentMessage &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::EquipmentMessageOC &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::CreateSingleExplosion &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::CreateAreaExplosion &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::CreateMineArea &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::MineAreaSingleMineState &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::CreateNContamination &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::CreateCContamination &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::DeactivateEffectSimulation &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::ModifyAreaEffectSimulationName &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::PauseEffectSimulation &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::ResumeEffectSimulation &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::MineTriggered &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::DusMineReactivation &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::CreateFunctionalArea &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::CreateDusSingleMine &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::ExerciseEnvironmentData &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::ExerciseStateData &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::OpaquePayloadDataOut &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::ParticipantSwVersionsRequest &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::TechnicalArea &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::CesHitInformation &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::CesHitRequest &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::ParticipantMode &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::DemandParticipantMode &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::ParticipantConfiguration &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::DemandParticipantConfiguration &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::ExerciseEquipmentAssignmentComplete &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::Sanitation &data) override;
|
||||
bool txData(const TrainingAreaBase::TetraIcd::SelectiveReammunition &data) override;
|
||||
private:
|
||||
|
||||
template <typename T>
|
||||
bool sendToTxMixin(const T *data);
|
||||
private:
|
||||
std::shared_ptr<HlaHandlerTx> m_hlaHandlerTx;
|
||||
LOGGER_T m_logger;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* IsmHandler for WirelessLocationSystem
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-04-14
|
||||
*/
|
||||
|
||||
#include "pdm_handler.h"
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
|
||||
namespace ApHlaJson
|
||||
{
|
||||
/*!
|
||||
\brief
|
||||
\author Niklas Schmidt
|
||||
\details Initially send all Charge Types to HLA
|
||||
Excon -> HLA
|
||||
\param parent
|
||||
*/
|
||||
PdmHandler::PdmHandler(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_logger(getLogger("PdmHandler"))
|
||||
{}
|
||||
|
||||
bool PdmHandler::init(MainDispatcher* mainDispatcher)
|
||||
{
|
||||
m_dtcPdm = ProjectDataManagement::Interface::Dtc::create(mainDispatcher->ddsHandler()->ddsConnector());
|
||||
|
||||
if (!m_dtcPdm->enableChargeType())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Can not read data from Pdm";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_dtcPdm->waitForHistoricalDataChargeType(5000); //NOTE: Unsure if necessary??, what if getChargeTypes started before waitForHistoricalData is finished
|
||||
|
||||
if (m_dtcPdm->chargeTypes().size() <= 0)
|
||||
FATAL_LOG(m_logger) << "Could not fetch ChargeTypes (yet)!";
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* {
|
||||
* typeId:8005,
|
||||
* type: ApacheHlaSendChargeTypes,
|
||||
* data:
|
||||
* [
|
||||
* {
|
||||
* id: 420,
|
||||
* name: 42mm,
|
||||
* entityTypeStruct: TestTest,
|
||||
* primaryGearTasCode: 11,
|
||||
* radius: 7
|
||||
* },
|
||||
* {
|
||||
* id: 777,
|
||||
* name: 77mm,
|
||||
* entityTypeStruct: TestTest,
|
||||
* primaryGearTasCode: 77,
|
||||
* radius: 77
|
||||
* },
|
||||
* {
|
||||
* ...
|
||||
* }
|
||||
* ]
|
||||
* }
|
||||
*/
|
||||
|
||||
void PdmHandler::getChargeTypes()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Get Charge Types";
|
||||
QJsonObject obj;
|
||||
QJsonArray dataArray;
|
||||
obj[QStringLiteral("type")] = QStringLiteral("ApacheHlaSendChargeTypes");
|
||||
obj[QStringLiteral("typeId")] = 8005;
|
||||
|
||||
|
||||
QMap<qint32, ProjectDataManagement::ChargeType> chargeTypes = m_dtcPdm->chargeTypes();
|
||||
QMap<qint32, ProjectDataManagement::GearType> gearTypes = m_dtcPdm->gearTypes();
|
||||
QMap<qint32, ProjectDataManagement::GearTypeChargeType> gearTypeChargeTypes = m_dtcPdm->gearTypeChargeTypes();
|
||||
DEBUG_LOG(m_logger) << "Fetched " << chargeTypes.size() << " ChargeTypes to send to WebSocket. Ommiting those without DIS-Entity though.";
|
||||
|
||||
for(const ProjectDataManagement::ChargeType &charge : chargeTypes)
|
||||
{
|
||||
if (charge.disEntity().empty())
|
||||
continue;
|
||||
|
||||
QJsonObject chargeType;
|
||||
chargeType[QStringLiteral("id")] = charge.id();
|
||||
chargeType[QStringLiteral("name")] = QString::fromStdString(charge.name());
|
||||
chargeType[QStringLiteral("entityTypeStruct")] = QString::fromStdString(charge.disEntity());
|
||||
int gearTypeId = 0;
|
||||
// Take first occurence...
|
||||
for(const ProjectDataManagement::GearTypeChargeType &val : gearTypeChargeTypes)
|
||||
{
|
||||
if(val.chargeTypeId() == charge.id())
|
||||
{
|
||||
gearTypeId = val.gearTypeId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
chargeType[QStringLiteral("primaryGearTasCode")] = gearTypes[gearTypeId].tasCode();
|
||||
QJsonDocument doc = QJsonDocument::fromJson(QByteArray::fromStdString(charge.properties()));
|
||||
|
||||
QJsonObject prop = doc.object();
|
||||
chargeType[QStringLiteral("radius")] = prop[QStringLiteral("impactRadius")];
|
||||
|
||||
dataArray.push_back(chargeType);
|
||||
}
|
||||
obj[QStringLiteral("data")] = dataArray;
|
||||
|
||||
emit sendChargeTypes(obj);
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // namespace ApHlaJson
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* IsmHandler for WirelessLocationSystem
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-04-14
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "main_dispatcher.h"
|
||||
#include "logger.h"
|
||||
#include "dds_handler.h"
|
||||
#include <ProjectDataManagement/pdm.hpp>
|
||||
#include <LtsUtilsCore/data_modification_enum.h>
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
#include <QUrl>
|
||||
#include <QDateTime>
|
||||
|
||||
namespace ApHlaJson
|
||||
{
|
||||
|
||||
class MainDispatcher;
|
||||
class PdmHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PdmHandler(QObject *parent = nullptr);
|
||||
void getChargeTypes();
|
||||
signals:
|
||||
void sendChargeTypes(QJsonObject jsonObj);
|
||||
public slots:
|
||||
bool init(MainDispatcher* mainDispatcher);
|
||||
|
||||
private:
|
||||
|
||||
std::shared_ptr<ProjectDataManagement::Interface::Dtc> m_dtcPdm;
|
||||
LOGGER_T m_logger;
|
||||
|
||||
|
||||
};
|
||||
|
||||
} // namespace ApHlaJson
|
||||
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Send / Receive telegrams to/from TX/RX directory
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-09-26
|
||||
*/
|
||||
|
||||
#include "plugin.h"
|
||||
#include "main_dispatcher.h"
|
||||
#include <nglsettings/nglsettings_settings.h>
|
||||
|
||||
namespace ApHlaJson
|
||||
{
|
||||
|
||||
//
|
||||
// TetraXdrPlugin
|
||||
//
|
||||
/*!
|
||||
\brief
|
||||
\author Niklas Schmidt
|
||||
\details Plugin to integrate Apache with Hla Enviroment. The plugin receive data from HLA and forward
|
||||
the data to Excon and Tetra.
|
||||
Communication directions:
|
||||
- Excon -> Hla
|
||||
-# Init \ref hla_handler_rx.cpp
|
||||
-# VulnerabilityStateChange \ref ppm_handler.cpp
|
||||
-# ParticipantPositionChanged \ref ppm_handler.cpp
|
||||
-# ParticipantChanged \ref ppm_handler.cpp
|
||||
-# SendAllChargeTypes \ref pdm_handler.cpp
|
||||
- HLA -> Tetra
|
||||
-# CesHitInformation \ref hla_handler_tx.cpp
|
||||
- HLA -> Excon
|
||||
-# PositionReport \ref hla_handler_rx.cpp Defined in \ref training_area_telegrams.cpp
|
||||
-# StateChangeDirect
|
||||
-# StateChange
|
||||
-# StateChangeIndirect
|
||||
-# EquipmentGearEvent
|
||||
-# EquipmentGearAssignment
|
||||
-# EquipmentGearChargeState
|
||||
-# SpecialSensorData
|
||||
-# AesModifyRequest \ref aes_handler.cpp
|
||||
-# ApacheLaserDesignation \ref hla_handler_rx.cpp
|
||||
\param pdp
|
||||
\param recvFromTabCb
|
||||
\param sendToTabCb
|
||||
\param settings
|
||||
\return std::shared_ptr<TrainingAreaBase::Plugin::Interface>
|
||||
*/
|
||||
std::shared_ptr<TrainingAreaBase::Plugin::Interface> TabApHlaPlugin::createInterface(TrainingAreaBase::Plugin::DataProvider *pdp,
|
||||
const std::shared_ptr<TrainingAreaBase::RecvFromTab> &recvFromTabCb,
|
||||
const std::shared_ptr<TrainingAreaBase::TxMixin> &sendToTabCb,
|
||||
NGL::Settings *settings)
|
||||
{
|
||||
|
||||
return std::make_shared<MainDispatcher>(pdp, recvFromTabCb, sendToTabCb, settings);
|
||||
}
|
||||
} // namespace HlaJson
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Send / Receive telegrams to/from TX/RX directory
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-09-26
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QObject>
|
||||
#include <TrainingAreaBase/tab_plugin_interface.h>
|
||||
|
||||
namespace ApHlaJson
|
||||
{
|
||||
class TabApHlaPlugin : public QObject, public TrainingAreaBase::Plugin::Plugin
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID "special:3:tab.aphla")
|
||||
Q_INTERFACES(TrainingAreaBase::Plugin::Plugin)
|
||||
public:
|
||||
TabApHlaPlugin() = default;
|
||||
~TabApHlaPlugin() = default;
|
||||
std::shared_ptr<TrainingAreaBase::Plugin::Interface> createInterface(TrainingAreaBase::Plugin::DataProvider *pdp,
|
||||
const std::shared_ptr<TrainingAreaBase::RecvFromTab> &recvFromTabCb,
|
||||
const std::shared_ptr<TrainingAreaBase::TxMixin> &sendToTab,
|
||||
NGL::Settings *settings) override;
|
||||
};
|
||||
|
||||
} // namespace ApHlaJson
|
||||
@@ -0,0 +1,322 @@
|
||||
/**
|
||||
* IsmHandler for WirelessLocationSystem
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-04-14
|
||||
*/
|
||||
|
||||
#include "ppm_handler.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
|
||||
|
||||
namespace ApHlaJson
|
||||
{
|
||||
|
||||
/*!
|
||||
\brief
|
||||
\author Niklas Schmidt
|
||||
\details Recognize changes from PPM and creates new Telegram for these changes, than send to Hla
|
||||
Excon -> HLA
|
||||
\param parent
|
||||
*/
|
||||
PpmHandler::PpmHandler(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_logger(getLogger("PpmHandler"))
|
||||
{}
|
||||
|
||||
bool PpmHandler::init(MainDispatcher* mainDispatcher)
|
||||
{
|
||||
if (m_dtcPpm)
|
||||
return true;
|
||||
|
||||
m_dtcPpm = ParticipantManagement::Interface::Dtc::create(mainDispatcher->ddsHandler()->ddsConnector());
|
||||
|
||||
if (!m_dtcPpm->enableParticipant() || !m_dtcPpm->enableDynamicParticipantData() || !m_dtcPpm->enableParticipantPosition())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Can not read data from Ppm";
|
||||
return false;
|
||||
}
|
||||
|
||||
m_dtcPpm->waitForHistoricalDataParticipant(1000);
|
||||
m_dtcPpm->waitForHistoricalDataDynamicParticipantData(1000);
|
||||
m_dtcPpm->waitForHistoricalDataParticipantPosition(1000);
|
||||
|
||||
connect(m_dtcPpm.get(), &ParticipantManagement::Interface::Dtc::participantChanged,
|
||||
this, &PpmHandler::onParticipantChanged);
|
||||
|
||||
connect(m_dtcPpm.get(), &ParticipantManagement::Interface::Dtc::participantPositionChanged,
|
||||
this, &PpmHandler::onParticipantPositionChanged);
|
||||
|
||||
connect(m_dtcPpm.get(), &ParticipantManagement::Interface::Dtc::dynamicParticipantDataChanged,
|
||||
this, &PpmHandler::onDynamicParticipantDataChanged);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QString PpmHandler::fromDisInt(qint64 value)
|
||||
{
|
||||
QString s;
|
||||
|
||||
s.prepend(QString::number(value % 1000));
|
||||
s.prepend(QLatin1Literal("."));
|
||||
value /= 1000;
|
||||
s.prepend(QString::number(value % 1000));
|
||||
s.prepend(QLatin1Literal("."));
|
||||
value /= 1000;
|
||||
s.prepend(QString::number(value % 1000));
|
||||
s.prepend(QLatin1Literal("."));
|
||||
value /= 1000;
|
||||
s.prepend(QString::number(value % 1000));
|
||||
s.prepend(QLatin1Literal("."));
|
||||
value /= 1000;
|
||||
s.prepend(QString::number(value % 1000));
|
||||
s.prepend(QLatin1Literal("."));
|
||||
value /= 1000;
|
||||
s.prepend(QString::number(value % 1000));
|
||||
s.prepend(QLatin1Literal("."));
|
||||
value /= 1000;
|
||||
s.prepend(QString::number(value % 1000));
|
||||
return s;
|
||||
}
|
||||
|
||||
void PpmHandler::getParticipants()
|
||||
{
|
||||
|
||||
if(!m_dtcPpm)
|
||||
return;
|
||||
|
||||
for (const auto participant : m_dtcPpm->participants())
|
||||
{
|
||||
onParticipantChanged(participant, DataModification::eAdded);
|
||||
}
|
||||
}
|
||||
|
||||
bool PpmHandler::isEqNumberInExercise(int equipmentNumber) const
|
||||
{
|
||||
bool result = m_dtcPpm->participantIdByEquipmentNumber(equipmentNumber) > 0;
|
||||
|
||||
return result;
|
||||
//return m_participantIdsByEqNo.contains(equipmentNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief AddParticipant Telegram
|
||||
*
|
||||
*
|
||||
* @details Example Telegram:
|
||||
* {
|
||||
* typeId:8000,
|
||||
* type: ApacheHlaAddParticipant,
|
||||
* data:
|
||||
* {
|
||||
* header: {
|
||||
* equipmentNumber: 42,
|
||||
* timeStamp: MsecsSinceEpoch
|
||||
* },
|
||||
* status: 11,
|
||||
* forceIdentifier: 42,
|
||||
* ets: "2.0.0.0.0.0.1",
|
||||
* GeoPosition: {
|
||||
* lon: 15.145274,
|
||||
* lat: 24.5554556,
|
||||
* z: 55.000124
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief RemoveParticipant Telegram
|
||||
*
|
||||
*
|
||||
* @details Example Telegram:
|
||||
* {
|
||||
* typeId:8001,
|
||||
* type: ApacheHlaRemoveParticipant,
|
||||
* data:
|
||||
* {
|
||||
* header: {
|
||||
* equipmentNumber: 42,
|
||||
* timeStamp: MsecsSinceEpoch
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
|
||||
void PpmHandler::onParticipantChanged(const ParticipantManagement::Participant &participant, DataModification modType)
|
||||
{
|
||||
|
||||
//NOTE:Hier kommt er hin!
|
||||
|
||||
if(!participant.equipmentNumber().is_set())
|
||||
{
|
||||
for(auto it = m_participantIdsByEqNo.begin(); it != m_participantIdsByEqNo.end(); ++it)
|
||||
if (it.value() == participant.id())
|
||||
{
|
||||
m_participantIdsByEqNo.remove(it.key());
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (participant.externalId() > 0)
|
||||
return;
|
||||
|
||||
QJsonObject headerJson;
|
||||
headerJson[QStringLiteral("equipmentNumber")] = participant.equipmentNumber().get();
|
||||
headerJson[QStringLiteral("timeStamp")] = QDateTime::currentMSecsSinceEpoch();
|
||||
|
||||
if (modType == DataModification::eRemoved)
|
||||
{
|
||||
m_participantIdsByEqNo.remove(participant.equipmentNumber().get());
|
||||
QJsonObject telegram;
|
||||
QJsonObject data;
|
||||
data[QStringLiteral("header")] = headerJson;
|
||||
|
||||
telegram[QStringLiteral("data")] = data;
|
||||
telegram[QStringLiteral("type")] = QStringLiteral("ApacheHlaRemoveParticipant");
|
||||
telegram[QStringLiteral("typeId")] = 8001;
|
||||
emit participantChanged(telegram);
|
||||
|
||||
return;
|
||||
}
|
||||
if (m_participantIdsByEqNo.contains(participant.equipmentNumber().get()))
|
||||
{
|
||||
if (m_participantIdsByEqNo[participant.equipmentNumber().get()] != participant.id())
|
||||
{
|
||||
for(auto it = m_participantIdsByEqNo.begin(); it != m_participantIdsByEqNo.end(); ++it)
|
||||
if (it.value() == participant.id())
|
||||
{
|
||||
m_participantIdsByEqNo.remove(it.key());
|
||||
break;
|
||||
}
|
||||
m_participantIdsByEqNo[participant.equipmentNumber().get()] = participant.id();
|
||||
}
|
||||
}
|
||||
else
|
||||
m_participantIdsByEqNo[participant.equipmentNumber().get()] = participant.id();
|
||||
|
||||
|
||||
ParticipantManagement::DynamicParticipantData dynamicData = m_dtcPpm->dynamicParticipantData(participant.id());
|
||||
ParticipantManagement::Party party = m_dtcPpm->party(participant.partyId());
|
||||
ParticipantManagement::Type type = m_dtcPpm->type(participant.typeId());
|
||||
ParticipantManagement::ParticipantPosition partPos = m_dtcPpm->participantPosition(participant.id());
|
||||
|
||||
QJsonObject telegram;
|
||||
|
||||
QJsonObject geoPositionObj;
|
||||
geoPositionObj[QStringLiteral("lon")] = partPos.pos().lon();
|
||||
geoPositionObj[QStringLiteral("lat")] = partPos.pos().lat();
|
||||
geoPositionObj[QStringLiteral("z")] = partPos.pos().z();
|
||||
|
||||
QJsonObject data;
|
||||
data[QStringLiteral("header")] = headerJson;
|
||||
|
||||
data[QStringLiteral("status")] = static_cast<int>(m_dtcPpm->youngestStateInformation(dynamicData.stateHistory()).vulnerabilityState().underlying());
|
||||
data[QStringLiteral("forceIdentifier")] = static_cast<int>(party.hlaForceIdentifier().underlying());
|
||||
|
||||
data[QStringLiteral("ets")] = type.disEntities().empty() ? QStringLiteral("2.0.0.0.0.0.1") : fromDisInt(type.disEntities().front());
|
||||
data[QStringLiteral("geoPosition")] = geoPositionObj;
|
||||
telegram[QStringLiteral("data")] = data;
|
||||
telegram[QStringLiteral("type")] = QStringLiteral("ApacheHlaAddParticipant");
|
||||
telegram[QStringLiteral("typeId")] = 8000;
|
||||
emit participantChanged(telegram);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Change Position Telegram
|
||||
*
|
||||
*
|
||||
* @details Example Telegram:
|
||||
* {
|
||||
* typeId:8002,
|
||||
* type: ApacheHlaPositionChanged,
|
||||
* data:
|
||||
* {
|
||||
* header: {
|
||||
* equipmentNumber: 42,
|
||||
* timeStamp: MsecsSinceEpoch
|
||||
* },
|
||||
* lon: 15.275884,
|
||||
* lat: 37.854856,
|
||||
* z: 42.255278
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
void PpmHandler::onParticipantPositionChanged(const ParticipantManagement::ParticipantPosition &position, DataModification modType)
|
||||
{
|
||||
if (modType == DataModification::eRemoved)
|
||||
return;
|
||||
|
||||
ParticipantManagement::Participant part = m_dtcPpm->participant(position.participantId());
|
||||
|
||||
if (part.externalId() > 0 || !part.equipmentNumber().is_set())
|
||||
return;
|
||||
|
||||
QJsonObject telegram;
|
||||
telegram[QStringLiteral("typeId")] = 8002;
|
||||
telegram[QStringLiteral("type")] = QStringLiteral("ApacheHlaPositionChanged");
|
||||
|
||||
QJsonObject headerJson;
|
||||
headerJson[QStringLiteral("equipmentNumber")] = part.equipmentNumber().get();
|
||||
headerJson[QStringLiteral("timeStamp")] = QDateTime::currentMSecsSinceEpoch();
|
||||
|
||||
QJsonObject data;
|
||||
data[QStringLiteral("header")] = headerJson;
|
||||
data[QStringLiteral("lon")] = position.pos().lon();
|
||||
data[QStringLiteral("lat")] = position.pos().lat();
|
||||
data[QStringLiteral("z")] = position.pos().z();
|
||||
|
||||
telegram[QStringLiteral("data")] = data;
|
||||
emit participantChanged(telegram);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Change VulnerabilityState Telegram
|
||||
*
|
||||
*
|
||||
* @details Example Telegram:
|
||||
* {
|
||||
* typeId:8003,
|
||||
* type: ApacheHlaVulnerabilityStateChanged,
|
||||
* data:
|
||||
* {
|
||||
* header: {
|
||||
* equipmentNumber: 42,
|
||||
* timeStamp: MsecsSinceEpoch
|
||||
* },
|
||||
* status: 11
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
void PpmHandler::onDynamicParticipantDataChanged(const ParticipantManagement::DynamicParticipantData &dynPartData, DataModification modType)
|
||||
{
|
||||
if (modType == DataModification::eRemoved)
|
||||
return;
|
||||
|
||||
ParticipantManagement::Participant part = m_dtcPpm->participant(dynPartData.participantId());
|
||||
|
||||
if (part.externalId() > 0 || !part.equipmentNumber().is_set())
|
||||
return;
|
||||
|
||||
QJsonObject telegram;
|
||||
telegram[QStringLiteral("typeId")] = 8003;
|
||||
telegram[QStringLiteral("type")] = QStringLiteral("ApacheHlaVulnerabilityStateChanged");
|
||||
|
||||
QJsonObject headerJson;
|
||||
headerJson[QStringLiteral("equipmentNumber")] = part.equipmentNumber().get();
|
||||
headerJson[QStringLiteral("timeStamp")] = QDateTime::currentMSecsSinceEpoch();
|
||||
|
||||
QJsonObject data;
|
||||
data[QStringLiteral("header")] = headerJson;
|
||||
|
||||
data[QStringLiteral("status")] = static_cast<int>(m_dtcPpm->youngestStateInformation(dynPartData.stateHistory()).vulnerabilityState().underlying());
|
||||
telegram[QStringLiteral("data")] = data;
|
||||
|
||||
emit participantChanged(telegram);
|
||||
}
|
||||
|
||||
} // namespace ApHlaJson
|
||||
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* IsmHandler for WirelessLocationSystem
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by Christian Ehrlicher, SLSE, 2016-04-14
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "main_dispatcher.h"
|
||||
#include "logger.h"
|
||||
#include "dds_handler.h"
|
||||
#include <ParticipantManagement/ppm.hpp>
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
#include <LtsUtilsCore/data_modification_enum.h>
|
||||
#include <QObject>
|
||||
#include <QHash>
|
||||
#include <QUrl>
|
||||
#include <QDateTime>
|
||||
|
||||
namespace ApHlaJson
|
||||
{
|
||||
|
||||
class MainDispatcher;
|
||||
class PpmHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PpmHandler(QObject *parent = nullptr);
|
||||
bool init(MainDispatcher* mainDispatcher);
|
||||
static QString fromDisInt(qint64 value);
|
||||
void getParticipants();
|
||||
bool isEqNumberInExercise(int equipmentNumber) const;
|
||||
signals:
|
||||
void participantChanged(const QJsonObject &jsonObj);
|
||||
|
||||
private slots:
|
||||
void onParticipantChanged(const ParticipantManagement::Participant &data, DataModification modType);
|
||||
void onParticipantPositionChanged(const ParticipantManagement::ParticipantPosition &data, DataModification modType);
|
||||
void onDynamicParticipantDataChanged(const ParticipantManagement::DynamicParticipantData &data, DataModification modType);
|
||||
private:
|
||||
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_dtcPpm;
|
||||
LOGGER_T m_logger;
|
||||
/*!
|
||||
* \brief m_participantIdsByEqNo
|
||||
* \details Used to avoid using ppmDtc always the Apache send CesHitInformation
|
||||
*/
|
||||
QHash<int, int> m_participantIdsByEqNo; // eqNo, partId
|
||||
};
|
||||
|
||||
} // namespace ApHlaJson
|
||||
Reference in new issue
Block a user