Initial commit

This commit is contained in:
torsten committed 2026-08-13 18:33:10 +02:00
commit b7d90b9afe
16245 files changed
+3396666

No files matched your search

+186
View File
@@ -0,0 +1,186 @@
#
# $Id$
# $HeadURL$
# $Author$
#
INCLUDE(MacroRTIDDSGen)
INCLUDE(MacroCodeGenIdl)
SET(xml_FILE osc_service.xml)
#
# --- Library svcOscCommon --------------------------------------------------------------------------------
#
SET(SRCS_common
osc_export.h
logger.cpp
logger.h
)
# copy osc_predefined_data.sql to share
SET(in_file_sql "osc_predefined_data.sql")
SET(out_dir_sql "${CMAKE_BINARY_DIR}/share/Lts/sql/")
SET(out_file_sql "${out_dir_sql}/${in_file_sql}")
ADD_CUSTOM_COMMAND(OUTPUT ${out_file_sql}
COMMAND ${CMAKE_COMMAND}
ARGS -E make_directory ${out_dir_sql}
COMMAND ${CMAKE_COMMAND}
ARGS -E copy_if_different ${in_file_sql} ${out_file_sql}
DEPENDS ${in_file_sql}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
# Generate osc_enums.idl / osc.idl
CODEGEN_IDL_SVC(SRCS_common ${xml_FILE})
# Generate osc_db_impl.cpp/.h, osc_db.h
CODEGEN_DATABASE(SRCS_common ${xml_FILE})
# Generate *.cpp/*.hpp from idl
RTIDDSGEN(SRCS_common osc_enums.idl)
RTIDDSGEN(SRCS_common osc.idl)
# Generate osc_dt[s,c]_types.h, osc_ft[s,c]_types.h
CODEGEN_TOPIC_TYPEDEFS(SRCS_common ${xml_FILE})
# Generate osc_[d|f]tc.h
CODEGEN_CLIENT_TOPICS_IFC(SRCS_common ${xml_FILE} PARTS FTC)
NGL_ADD_LIBRARY(SV WS svcOscCommon SHARED ${SRCS_common})
NGL_TARGET_INCLUDE_DIRECTORIES(svcOscCommon
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../
${CMAKE_CURRENT_BINARY_DIR}/../
)
NGL_TARGET_LINK_LIBRARIES(svcOscCommon
PRIVATE
RTI::nddscpp2
PUBLIC
Qt5::Core
ddscore
NGLLogger
ngldb
)
NGL_INSTALL_TARGET(svcOscCommon)
#
# --- Library svcOscClient --------------------------------------------------------------------------------
#
SET(SRCS_client
osc_export.h
)
# generate osc_[d|f]tc.h, osc_[d|f]tc_impl.[cpp|h]
CODEGEN_CLIENT_TOPICS_IMPL(SRCS_client ${xml_FILE} PARTS FTC)
NGL_ADD_LIBRARY(SV WS svcOscClient SHARED ${SRCS_client})
NGL_TARGET_INCLUDE_DIRECTORIES(svcOscClient
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../
${CMAKE_CURRENT_BINARY_DIR}/../
)
NGL_TARGET_LINK_LIBRARIES(svcOscClient
PRIVATE
RTI::nddscpp2
ddsconnector
PUBLIC
svcOscCommon
ddsftc
)
NGL_INSTALL_TARGET(svcOscClient)
#
# --- Library svcOscServer --------------------------------------------------------------------------------
#
SET(SRCS_server
osc_export.h
)
# generate osc_[d|f]ts.h, osc_[d|f]ts_impl.[cpp|h]
CODEGEN_SERVER_TOPICS(SRCS_server ${xml_FILE} PARTS FTS)
NGL_ADD_LIBRARY(SV svcOscServer SHARED ${SRCS_server})
NGL_TARGET_INCLUDE_DIRECTORIES(svcOscServer
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../
${CMAKE_CURRENT_BINARY_DIR}/../
)
NGL_TARGET_LINK_LIBRARIES(svcOscServer
PRIVATE
RTI::nddscpp2
ddsconnector
ddsfts
PUBLIC
svcOscCommon
ngldb
)
NGL_INSTALL_TARGET(svcOscServer)
#
# --- Topic Type Plugin --------------------------------------------------------------
#
CREATE_TOPIC_TYPE_PLUGIN(${xml_FILE})
#
# --- Executable svcOcSituationClient (sOSC) -------------------------------------------------
#
SET(SRCS_exe
central_aes_byte_reader.h
central_aes_byte_reader.cpp
main.cpp
main_handler.cpp
main_handler.h
dds_handler.cpp
dds_handler.h
handler_oc_aes_data.cpp
handler_oc_aes_data.h
handler_oc_central_aes_data.cpp
handler_oc_central_aes_data.h
handler_oc_data.cpp
handler_oc_data.h
handler_oc_situation_data.cpp
handler_oc_situation_data.h
settings.cpp
settings.h
${xml_FILE}
)
# Generate osc.sql, osc.xml
CODEGEN_SQL(SRCS_exe ${xml_FILE})
NGL_ADD_SVC_ICON(SRCS_exe)
NGL_ADD_EXECUTABLE(SV svcOcSituationClient ${SRCS_exe})
NGL_TARGET_LINK_LIBRARIES(svcOcSituationClient
Qt5::Core
svcOscCommon
svcOscServer
svcCoreClient
svcAesClient
svcEvlClient
svcGimClient
svcMsgClient
svcOpmClient
svcOssServer
svcPpmClient
svcTabClient
svcTabServer
svcTabocClient
svcTabocServer
ddsconnector
nglsettings
ProjectConfig
LtsCommandLineParser
LtsCoordTrans
LtsUtilsCoreHeaderOnly
NGLLogger
nglcoreapplication
ngltools
)
NGL_INSTALL_TARGET(svcOcSituationClient)
NGL_INSTALL(SV FILES log4cxx_osc.props DESTINATION bin)
NGL_ADD_TARGET_LINK(svcOcSituationClient sOSC)
# Uncomment if necessary
#ADD_SUBDIRECTORY(UnitTests)
#ADD_SUBDIRECTORY(ModuleTests)
@@ -0,0 +1,126 @@
/**
* @RDE_HEADER@
* The ClientMessage class is an abstract base class for concrete ClientMessage objects
* $Id$
* $HeadURL$
* $Author$
* Created by Philipp Dassow, SLST, 2017-12-05
*/
#include "client_message.h"
#include "WebSocketInterface/Messages/reply_message.h"
#include "WebSocketInterface/json_keys.h"
#include "WebSocketInterface/data_manager.h"
#include <QtCore/QJsonDocument>
#include <QtCore/QUuid>
namespace OcSituationClient
{
namespace WebSocketInterface
{
namespace Messages
{
using namespace JsonKeys;
// ####### ClientMessageFactory begin #######
ClientMessageFactory::ClientMessageFactory(DataManager *dataManager)
: LtsWebSocket::AbstractClientMessageFactory(getLogger("ClientMessageFactory"))
, m_dataManager(dataManager)
{}
ClientMessageFactory::~ClientMessageFactory()
{}
LtsWebSocket::AbstractClientMessage *ClientMessageFactory::createMessage(LtsWebSocket::ReplyHandler *client,
const QString &message)
{
LtsWebSocket::AbstractClientMessage *result = checkAttributes(client, message);
if (result)
return result;
if (m_type == ServiceManagement::WebSocketInterface::JsonKeys::SERVICE_PORTS_INFORMATION())
result = new ServicePortsInformation(m_dataManager, client, m_type, m_uuid, m_data);
return checkResult(client, message, result);
}
// ####### ClientMessageFactory end #######
// ####### ClientMessage begin #######
ClientMessage::ClientMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const QString &uuid, const QJsonValue &data)
: LtsWebSocket::AbstractClientMessage(client, type, uuid, data)
, m_dataManager(dataManager)
{}
// ####### ClientMessage end #######
// ####### ServicesInformation begin #######
ServicePortsInformation::ServicePortsInformation(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const QString &uuid, const QJsonValue &data)
: ClientMessage (dataManager,client, type, uuid, data)
{}
void ServicePortsInformation::process()
{
QJsonArray exerciseInformationArray = m_data.toArray();
QVector<ExerciseInformation> exercises;
QVector<ServiceInformation> services;
QVector<PortInformation> ports;
exercises.reserve(exerciseInformationArray.size());
for (const auto &exerciseJsonValue : exerciseInformationArray)
{
QJsonObject exerciseJsonObject = exerciseJsonValue.toObject();
ExerciseInformation exercise;
exercise.exerciseId = exerciseJsonObject.value(ServiceManagement::WebSocketInterface::JsonKeys::EXERCISE_ID()).toInt();
if (exerciseJsonObject.find(ServiceManagement::WebSocketInterface::JsonKeys::REPLAY_PARTITION_ID()) != exerciseJsonObject.end())
exercise.replayPartitionId = dds::core::optional<int32_t>(exerciseJsonObject.value(ServiceManagement::WebSocketInterface::JsonKeys::REPLAY_PARTITION_ID()).toInt());
QJsonArray servicesJsonArray = exerciseJsonObject.value(ServiceManagement::WebSocketInterface::JsonKeys::SERVICES()).toArray();
// prepare vector
services.clear();
services.reserve(servicesJsonArray.size());
for (const auto &serviceValue : servicesJsonArray)
{
ServiceInformation service;
QJsonObject serviceObject = serviceValue.toObject();
service.name = serviceObject.value(ServiceManagement::WebSocketInterface::JsonKeys::NAME()).toString();
service.abbreviation = serviceObject.value(ServiceManagement::WebSocketInterface::JsonKeys::NAME_ABBR()).toString();
QJsonArray portsJsonArray = serviceObject.value(ServiceManagement::WebSocketInterface::JsonKeys::PORTS()).toArray();
// prepare vector
ports.clear();
ports.reserve(portsJsonArray.size());
for (const auto &portValue : portsJsonArray)
{
QJsonObject portObject = portValue.toObject();
PortInformation port;
port.number = portObject.value(ServiceManagement::WebSocketInterface::JsonKeys::NUMBER()).toInt();
port.type = portObject.value(ServiceManagement::WebSocketInterface::JsonKeys::TYPE_ID()).toInt();
ports.append(port);
}
service.ports = ports;
services.append(service);
}
exercise.services = services;
exercises.append(exercise);
}
m_dataManager->servicePortsInformation(exercises);
}
bool ServicePortsInformation::hasValidData() const
{
return true;
}
// ####### ServicesInformation end #######
} // namespace Messages
} // namespace WebSocketInterface
} // namespace OcSituationClient
@@ -0,0 +1,106 @@
/**
* @RDE_HEADER@
* The ClientMessage class is an abstract base class for concrete ClientMessage objects
* $Id$
* $HeadURL$
* $Author$
* Created by Philipp Dassow, SLST, 2017-12-05
*/
#pragma once
#include <QtCore/QJsonObject>
#include <QVector>
#include <DDS/Core/core.hpp>
#include <LtsWebSocket/client_message_factory.h>
#include <LtsWebSocket/client_message.h>
#include "logger.h"
namespace OcSituationClient
{
namespace WebSocketInterface
{
class DataManager;
namespace Messages
{
/**
* @brief The ClientMessageFactory class creates ClientMessages which will then be processed
*/
class ClientMessageFactory final : public LtsWebSocket::AbstractClientMessageFactory
{
public:
explicit ClientMessageFactory(DataManager *dataManager);
virtual ~ClientMessageFactory();
/**
* @brief create Only way to create a ClientMessage object
* @param message Text message which will be converted to a ClientMessage object
* @return A ClientMessage object, which represents a concrete ClientMessage
*/
LtsWebSocket::AbstractClientMessage *createMessage(LtsWebSocket::ReplyHandler *client,
const QString &message);
private:
DataManager *m_dataManager;
}; // class ClientMessageFactory
/**
* @brief The ClientMessage class is an abstract base class for concrete ClientMessage objects
*/
class ClientMessage : public LtsWebSocket::AbstractClientMessage
{
protected: // method
explicit ClientMessage(DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const QString &uuid, const QJsonValue &data = QJsonValue());
protected: // attributes
DataManager *m_dataManager;
}; // class ClientMessage
// ################## Message Implementations ##################
class ServicePortsInformation : public ClientMessage
{
public:
explicit ServicePortsInformation (DataManager *dataManager, LtsWebSocket::ReplyHandler *client, const QString &type, const QString &uuid, const QJsonValue &data);
public:
/**
* @brief The PortInformation struct holds the information what kind of port we have here
*/
struct PortInformation
{
int32_t number;
int32_t type;
};
/**
* @brief The ServiceInformation struct information about a service
*/
struct ServiceInformation
{
QString name;
QString abbreviation;
QVector<PortInformation> ports;
};
/**
* @brief The ExerciseInformation struct with information about an exercise (could also be a replay)
*/
struct ExerciseInformation
{
int32_t exerciseId;
dds::core::optional<int32_t> replayPartitionId;
QVector<ServiceInformation> services;
};
void process();
bool hasValidData() const;
}; // class ServicesInformation
} // namespace Messages
} // namespace WebSocketInterface
} // namespace OcSituationClient
@@ -0,0 +1,32 @@
/**
* @RDE_HEADER@
* The ReplyMessage class is an abstract base class for all possible messages which are sent to the client
* $Id$
* $HeadURL$
* $Author$
* Created by Philipp Dassow, SLST, 2017-12-05
*/
#include "reply_message.h"
#include <LtsWebSocket/json_keys.h>
#include "WebSocketInterface/json_keys.h"
#include <QtCore/QUuid>
#include <QtCore/QJsonDocument>
namespace OcSituationClient
{
namespace WebSocketInterface
{
namespace Messages
{
using namespace JsonKeys;
using namespace LtsWebSocket::JsonKeys;
ServicePortsInformationRequest::ServicePortsInformationRequest(const QString &uuid)
: ReplyMessage(ServiceManagement::WebSocketInterface::JsonKeys::SERVICE_PORTS_INFORMATION_REQUEST(), uuid)
{}
} // namespace Messages
} // namespace WebSocketInterface
} // namespace OcSituationClient
@@ -0,0 +1,36 @@
/**
* @RDE_HEADER@
* The ReplyMessage class is an abstract base class for all possible messages which are sent to the client
* $Id$
* $HeadURL$
* $Author$
* Created by Philipp Dassow, SLST, 2017-12-05
*/
#pragma once
#include <LtsWebSocket/client_message_factory.h>
#include <DDS/Core/core.hpp>
#include <QString>
#include <QMap>
#include <QtCore/QVector>
#include <QtCore/QJsonObject>
#include <QtCore/QJsonArray>
namespace OcSituationClient
{
namespace WebSocketInterface
{
namespace Messages
{
class ServicePortsInformationRequest : public LtsWebSocket::ReplyMessage
{
public:
explicit ServicePortsInformationRequest(const QString &uuid);
};
} // namespace Messages
} // namespace WebSocketInterface
} // namespace OcSituationClient
@@ -0,0 +1,40 @@
/**
* @RDE_HEADER@
* The DataManager class takes strucure element data from the HandlerStructureElement,
* offers an interface to get and set structure data
* $Id$
* $HeadURL$
* $Author$
* Created by Philipp Dassow, SLST, 2017-12-05
*/
#include "WebSocketInterface/data_manager.h"
#include "main_handler.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QMap>
#include <QVector>
namespace OcSituationClient
{
namespace WebSocketInterface
{
//---------------------------------------------------------------------------------------------------------
DataManager::DataManager(MainHandler *mainHandler)
: m_mainHandler(mainHandler)
, m_logger(getLogger(QStringLiteral("DataManager")))
{
}
//---------------------------------------------------------------------------------------------------------
void DataManager::servicePortsInformation(const QVector<Messages::ServicePortsInformation::ExerciseInformation> &exerciseInformation)
{
DEBUG_LOG(m_logger) << "Got ServicePortsInformation from websocket";
m_mainHandler->handlerBaseDownload()->handleServicePortsInformation(exerciseInformation);
}
} // namespace WebSocketInterface
} // namespace OcSituationClient
@@ -0,0 +1,47 @@
/**
* @RDE_HEADER@
* The DataManager class is a convenience class for managing structure data
* $Id$
* $HeadURL$
* $Author$
* Created by Philipp Dassow, SLST, 2017-12-05
*/
#pragma once
#include "WebSocketInterface/Messages/client_message.h"
#include "logger.h"
namespace OcSituationClient
{
class MainHandler;
namespace WebSocketInterface
{
/**
* @brief The DataManager class is a convenience class for managing structure data
*/
class DataManager final
{
public:
/**
* @brief DataManager Constructor
* @param mainHandler Source for needed handlers
*/
explicit DataManager(MainHandler *mainHandler);
/**
* @brief servicePortsInformation processing new port informations, only called during base DL
* @param exerciseInformation
*/
void servicePortsInformation(const QVector<Messages::ServicePortsInformation::ExerciseInformation> &exerciseInformation);
private: // attributes
MainHandler *m_mainHandler;
LOGGER_T m_logger;
}; // class DataManager
} // namespace WebSocketInterface
} // namespace OcSituationClient
@@ -0,0 +1,32 @@
/**
* @RDE_HEADER@
* Header file which holds all occuring JSON keys
* $Id$
* $HeadURL$
* $Author$
* Created by Philipp Dassow, SLST, 2017-12-05
*/
#pragma once
#include <QtCore/QString>
#include <ServiceManagement/WebSocketInterface/json_keys.h>
namespace OcSituationClient
{
namespace WebSocketInterface
{
/**
* @brief Namespace which holds all occuring JSON keys as const QString objects
*/
namespace JsonKeys
{
// types for client --> server messages
// types for server --> client messages
// data keys
} // namespace JsonKeys
} // namespace WebSocketInterface
} // namespace OcSituationClient
@@ -0,0 +1,72 @@
/**
* @RDE_HEADER@
* Handler for the WebSocket Interface
* $Id$
* $HeadURL$
* $Author$
* Created by Philipp Dassow, SLST, 2017-12-05
*/
#include "websocket_interface_handler.h"
#include "main_handler.h"
#include "data_manager.h"
#include "WebSocketInterface/Messages/client_message.h"
namespace OcSituationClient
{
namespace WebSocketInterface
{
WebSocketInterfaceHandler::WebSocketInterfaceHandler(MainHandler *mainHandler, QObject *parent)
: QObject(parent)
, m_webSocketClient(nullptr)
, m_messageFactory(nullptr)
, m_dataManager(nullptr)
, m_mainHandler(mainHandler)
, m_logger(getLogger("WebSocketInterfaceHandler"))
{
}
WebSocketInterfaceHandler::~WebSocketInterfaceHandler()
{
cleanup();
}
bool WebSocketInterfaceHandler::init()
{
cleanup();
DEBUG_LOG(m_logger) << "Initialising DataManager";
m_dataManager = new DataManager(m_mainHandler);
DEBUG_LOG(m_logger) << "... ok";
m_messageFactory = new Messages::ClientMessageFactory(m_dataManager);
m_webSocketClient = new LtsWebSocket::LtsWebSocketClient(m_messageFactory, this);
DEBUG_LOG(m_logger) << "Connection signals and slots";
connect(m_webSocketClient, &LtsWebSocket::LtsWebSocketClient::connected, this, &WebSocketInterfaceHandler::connected);
connect(m_webSocketClient, &LtsWebSocket::LtsWebSocketClient::disconnected, this, &WebSocketInterfaceHandler::disconnected);
DEBUG_LOG(m_logger) << "... ok";
return true;
}
void WebSocketInterfaceHandler::open(const QString &hostname, int port)
{
m_webSocketClient->open(hostname, port);
}
void WebSocketInterfaceHandler::send(LtsWebSocket::ReplyMessage *message)
{
m_webSocketClient->addReply(message);
}
void WebSocketInterfaceHandler::cleanup()
{
delete m_webSocketClient;
delete m_messageFactory;
delete m_dataManager;
}
} // namespace WebSocketInterface
} // namespace OcSituationClient
@@ -0,0 +1,90 @@
/**
* @RDE_HEADER@
* Handler for the WebSocket Interface
* $Id$
* $HeadURL$
* $Author$
* Created by Philipp Dassow, SLST, 2017-12-05
*/
#pragma once
#include <QtCore/QObject>
#include <QString>
#include <LtsWebSocket/lts_web_socket_client.h>
#include "logger.h"
namespace OcSituationClient
{
class MainHandler;
namespace WebSocketInterface
{
namespace Messages
{
class ClientMessageFactory;
class ReplyMessage;
}
class DataManager;
/**
* @brief The WebSocketInterfaceHandler class is the main class for the WebSocketInterface
*/
class WebSocketInterfaceHandler final : public QObject
{
Q_OBJECT
public:
/**
* @brief WebSocketInterfaceHandler Constructor
* @param mainHandler MainHandler to get the HandlerStructureElement from
*/
explicit WebSocketInterfaceHandler(MainHandler *mainHandler, QObject *parent = nullptr);
/**
* @brief ~WebSocketInterfaceHandler Destructor
*/
~WebSocketInterfaceHandler();
/**
* @brief init Initialises all needed classes for the WebSocketInterface
* @return True on success, otherwise false
*/
bool init();
/**
* @brief open Opens the websocket with the given parameter
* @param hostname
* @param port
*/
void open(const QString &hostname, int port);
/**
* @brief send Sends the given message
* @param msg
*/
void send(LtsWebSocket::ReplyMessage *message);
signals:
/**
* @brief connected
*/
void connected();
/**
* @brief disconnected
*/
void disconnected();
private:
void cleanup();
private:
LtsWebSocket::LtsWebSocketClient *m_webSocketClient;
Messages::ClientMessageFactory *m_messageFactory;
DataManager *m_dataManager;
MainHandler *m_mainHandler;
LOGGER_T m_logger;
}; // class WebSocketInterfaceHandle
} // namespace WebSocketInterface
} // namespace OcSituationClient
+610
View File
@@ -0,0 +1,610 @@
/**
* Class for reading oc data
* $Id: handler_oc_situation_data.h 57655 2022-07-20 11:38:28Z karwat $
* $HeadURL: svn://192.168.133.21/TDS/branches/product/features/3dws_devel/Lts/Services/OcSituationClient/handler_oc_situation_data.h $
* $Author: karwat $
* Created by Hannes Fritsche, SLTE, 30-08-2023
*/
#include "central_aes_byte_reader.h"
#include <LtsUtilsCore/qbytearray_byteaccess.h>
#include "main_handler.h"
#include "settings.h"
namespace OcSituationClient
{
CentralAesByteReader::CentralAesByteReader(const QByteArray &data)
: m_data(data)
, m_logger(getLogger("CentralAesByteReader"))
{}
bool CentralAesByteReader::getRemoveMessage(size_t &pos, CentralAesByteReader::RemoveMessage &removeMessage) const
{
bool result = getAesItemId(pos, removeMessage.aesItemId);
result &= getAesType(pos, removeMessage.aesType);
DEBUG_LOG(m_logger) << "Got remove message:"
<< "\naesItemId = " << removeMessage.aesItemId
<< "\naesType = " << removeMessage.aesType;
return result;
}
bool CentralAesByteReader::getNContamination(size_t &pos, AreaEffectSimulation::NContaminationModifyRequest &nContamination) const
{
bool result = getAesItemId(pos, nContamination.id());
result &= getName(pos, nContamination.name());
result &= getOptionalNumber(pos, nContamination.effectStart(), &CentralAesByteReader::getEffectStart);
result &= getEffectDuration(pos, nContamination.effectDuration());
result &= getChargeTypeId(pos, nContamination.chargeTypeId());
result &= getImpactPosition(pos, nContamination.impactPosition());
result &= getBorderLengthInner(pos, nContamination.borderLengthInner());
result &= getBorderLengthOuter(pos, nContamination.borderLengthOuter());
result &= getImpactRadius(pos, nContamination.impactRadius());
result &= getSpanAngle(pos, nContamination.spanAngle());
result &= getRotationAngle(pos, nContamination.rotationAngle());
result &= getDetonationValue(pos, nContamination.detonationValue());
result &= getOptionalNumber(pos, nContamination.partyId(), &CentralAesByteReader::getPartyId);
nContamination.weatherSource(AreaEffectSimulation::AesWeatherSource::AwsNoUpdate);
DEBUG_LOG(m_logger) << "Got NContamination:"
<< "\nid = " << nContamination.id()
<< "\nname = " << nContamination.name()
<< "\neffectStart = " << nContamination.effectStart()
<< "\neffectDuration = " << nContamination.effectDuration()
<< "\nchargeTypeId = " << nContamination.chargeTypeId()
<< "\nimpactPosition = " << nContamination.impactPosition()
<< "\nborderLengthInner = " << nContamination.borderLengthInner()
<< "\nborderLengthOuter = " << nContamination.borderLengthOuter()
<< "\nimpactRadius = " << nContamination.impactRadius()
<< "\nspanAngle = " << nContamination.spanAngle()
<< "\nrotationAngle = " << nContamination.rotationAngle()
<< "\ndetonationValue = " << nContamination.detonationValue()
<< "\npartyId = " << nContamination.partyId();
return result;
}
bool CentralAesByteReader::getBCContamination(size_t &pos, AreaEffectSimulation::BCContaminationModifyRequest &bCContamination) const
{
bool result = getAesItemId(pos, bCContamination.id());
result &= getName(pos, bCContamination.name());
result &= getOptionalNumber(pos, bCContamination.effectStart(), &CentralAesByteReader::getEffectStart);
result &= getEffectDuration(pos, bCContamination.effectDuration());
result &= getChargeTypeId(pos, bCContamination.chargeTypeId());
result &= getImpactPosition(pos, bCContamination.impactPosition());
result &= getImpactRadius(pos, bCContamination.impactRadius());
result &= getOptionalNumber(pos, bCContamination.partyId(), &CentralAesByteReader::getPartyId);
result &= getOptionalNumber(pos, bCContamination.propagationDirection(), &CentralAesByteReader::getPropagationDirection);
result &= getOptionalNumber(pos, bCContamination.windSpeed(), &CentralAesByteReader::getWindSpeed);
bCContamination.weatherSource(AreaEffectSimulation::AesWeatherSource::AwsNoUpdate);
DEBUG_LOG(m_logger) << "Got BCContamination:"
<< "\nid = " << bCContamination.id()
<< "\nname = " << bCContamination.name()
<< "\neffectStart = " << bCContamination.effectStart()
<< "\neffectDuration = " << bCContamination.effectDuration()
<< "\nchargeTypeId = " << bCContamination.chargeTypeId()
<< "\nimpactPosition = " << bCContamination.impactPosition()
<< "\nimpactRadius = " << bCContamination.impactRadius()
<< "\nweatherSource = " << bCContamination.weatherSource()
<< "\npartyId = " << bCContamination.partyId()
<< "\npropagationDirection = " << bCContamination.propagationDirection()
<< "\nwindSpeed = " << bCContamination.windSpeed()
<< "\nweatherPosition = " << bCContamination.weatherPosition()
<< "\nweatherTimestamp = " << bCContamination.weatherTimestamp();
return result;
}
bool CentralAesByteReader::getExplosionArea(size_t &pos, AreaEffectSimulation::ExplosionAreaModifyRequest &explosionArea) const
{
bool result = getAesItemId(pos, explosionArea.id());
result &= getName(pos, explosionArea.name());
result &= getOptionalNumber(pos, explosionArea.effectStart(), &CentralAesByteReader::getEffectStart);
result &= getEffectDuration(pos, explosionArea.effectDuration());
result &= getChargeTypeId(pos, explosionArea.chargeTypeId());
result &= getArea(pos, explosionArea.area());
result &= getOptionalNumber(pos, explosionArea.partyId(), &CentralAesByteReader::getPartyId);
result &= getCannonCount(pos, explosionArea.cannonCount());
result &= getCannonRounds(pos, explosionArea.cannonRounds());
result &= getFireRequestTime(pos, explosionArea.fireRequestTime());
result &= getAltitude(pos, explosionArea.altitude());
result &= getPurpose(pos, explosionArea.purpose());
DEBUG_LOG(m_logger) << "Got ExplosionArea:"
<< "\nid = " << explosionArea.id()
<< "\nname = " << explosionArea.name()
<< "\neffectStart = " << explosionArea.effectStart()
<< "\neffectDuration = " << explosionArea.effectDuration()
<< "\nchargeTypeId = " << explosionArea.chargeTypeId()
<< "\narea = " << explosionArea.area()
<< "\npartyId = " << explosionArea.partyId()
<< "\ncannonCount = " << explosionArea.cannonCount()
<< "\ncannonRounds = " << explosionArea.cannonRounds()
<< "\nfireRequestTime = " << explosionArea.fireRequestTime()
<< "\naltitude = " << explosionArea.altitude()
<< "\npurpose = " << explosionArea.purpose();
return result;
}
bool CentralAesByteReader::getExplosionSingle(size_t &pos, AreaEffectSimulation::ExplosionSingleModifyRequest &explosionSingle) const
{
bool result = getAesItemId(pos, explosionSingle.id());
result &= getName(pos, explosionSingle.name());
result &= getOptionalNumber(pos, explosionSingle.effectStart(), &CentralAesByteReader::getEffectStart);
result &= getChargeTypeId(pos, explosionSingle.chargeTypeId());
result &= getImpactPosition(pos, explosionSingle.impactPosition());
result &= getOptionalNumber(pos, explosionSingle.partyId(), &CentralAesByteReader::getPartyId);
result &= getFireRequestTime(pos, explosionSingle.fireRequestTime());
result &= getAltitude(pos, explosionSingle.altitude());
result &= getPurpose(pos, explosionSingle.purpose());
DEBUG_LOG(m_logger) << "Got ExplosionSingle:"
<< "\nid = " << explosionSingle.id()
<< "\nname = " << explosionSingle.name()
<< "\neffectStart = " << explosionSingle.effectStart()
<< "\nchargeTypeId = " << explosionSingle.chargeTypeId()
<< "\nimpactPosition = " << explosionSingle.impactPosition()
<< "\npartyId = " << explosionSingle.partyId()
<< "\nfireRequestTime = " << explosionSingle.fireRequestTime()
<< "\naltitude = " << explosionSingle.altitude()
<< "\npurpose = " << explosionSingle.purpose();
return result;
}
bool CentralAesByteReader::getMineArea(size_t &pos, AreaEffectSimulation::MineAreaModifyRequest &mineArea) const
{
bool result = getAesItemId(pos, mineArea.id());
result &= getName(pos, mineArea.name());
result &= getOptionalNumber(pos, mineArea.effectStart(), &CentralAesByteReader::getEffectStart);
result &= getEffectDuration(pos, mineArea.effectDuration());
result &= getDensity(pos, mineArea.density());
result &= getWidth(pos, mineArea.width());
result &= getChargeTypeId(pos, mineArea.chargeStruct().chargeTypeId());
result &= getOptionalNumber(pos, mineArea.partyId(), &CentralAesByteReader::getPartyId);
result &= getAesMaLayingProcedureType(pos, mineArea.layingProcedureType());
result &= getIsLayedHidden(pos, mineArea.isLaidHidden());
result &= getIsCenterLine(pos, mineArea.isCenterLine());
result &= getSegments(pos, mineArea.segments());
DEBUG_LOG(m_logger) << "Got MineArea:"
<< "\nid = " << mineArea.id()
<< "\nname = " << mineArea.name()
<< "\neffectStart = " << mineArea.effectStart()
<< "\neffectDuration = " << mineArea.effectDuration()
<< "\ndensity = " << mineArea.density()
<< "\nwidth = " << mineArea.width()
<< "\nchargeTypeId = " << mineArea.chargeStruct().chargeTypeId()
<< "\npartyId = " << mineArea.partyId()
<< "\nlayingProcedureType = " << mineArea.layingProcedureType()
<< "\nisLaidHidden = " << mineArea.isLaidHidden()
<< "\nisCenterLine = " << mineArea.isCenterLine()
<< "\nsegments.size = " << mineArea.segments().size();
return result;
}
bool CentralAesByteReader::getFunctionalArea(size_t &pos, AreaEffectSimulation::FunctionalAreaModifyRequest &functionalArea) const
{
bool result = getAesItemId(pos, functionalArea.id());
result &= getName(pos, functionalArea.name());
result &= getOptionalNumber(pos, functionalArea.effectStart(), &CentralAesByteReader::getEffectStart);
result &= getEffectDuration(pos, functionalArea.effectDuration());
result &= getChargeTypeId(pos, functionalArea.chargeTypeId());
result &= getArea(pos, functionalArea.area());
result &= getOptionalNumber(pos, functionalArea.partyId(), &CentralAesByteReader::getPartyId);
std::string pointSymbol;
result &= getPointSymbol(pos, pointSymbol);
if (pointSymbol != std::string())
functionalArea.pointSymbol().set(pointSymbol);
result &= getFunctionalAreaTypeId(pos, functionalArea.functionalAreaTypeId());
result &= getDeconMode(pos, functionalArea.deconMode());
result &= getDeconTime(pos, functionalArea.deconTime());
result &= getMaintMode(pos, functionalArea.maintMode());
result &= getMaintTime(pos, functionalArea.maintTime());
result &= getMedicMode(pos, functionalArea.medicMode());
result &= getMedicTime(pos, functionalArea.medicTime());
DEBUG_LOG(m_logger) << "Got MineArea:"
<< "\nid = " << functionalArea.id()
<< "\nname = " << functionalArea.name()
<< "\neffectStart = " << functionalArea.effectStart()
<< "\neffectDuration = " << functionalArea.effectDuration()
<< "\nchargeTypeId = " << functionalArea.chargeTypeId()
<< "\narea = " << functionalArea.area()
<< "\npartyId = " << functionalArea.partyId()
<< "\npointSymbol = " << functionalArea.pointSymbol()
<< "\nfunctionalAreaTypeId = " << functionalArea.functionalAreaTypeId()
<< "\ndeconMode = " << functionalArea.deconMode()
<< "\ndeconTime = " << functionalArea.deconTime()
<< "\nmaintMode = " << functionalArea.maintMode()
<< "\nmaintTime = " << functionalArea.maintTime()
<< "\nmedicMode = " << functionalArea.medicMode()
<< "\n medicTime= " << functionalArea.medicTime();
return result;
}
bool CentralAesByteReader::getBoobyTrap(size_t &pos, AreaEffectSimulation::BoobyTrapModifyRequest &boobyTrap) const
{
bool result = getAesItemId(pos, boobyTrap.id());
result &= getName(pos, boobyTrap.name());
result &= getEffectDuration(pos, boobyTrap.effectDuration());
result &= getChargeTypeId(pos, boobyTrap.chargeTypeId());
result &= getImpactPosition(pos, boobyTrap.impactPosition());
result &= getImpactRadius(pos, boobyTrap.impactRadius());
result &= getTriggerRadius(pos, boobyTrap.triggerRadius());
result &= getOptionalNumber(pos, boobyTrap.rotationAngle(), &CentralAesByteReader::getRotationAngle);
result &= getOptionalNumber(pos, boobyTrap.centralAngle(), &CentralAesByteReader::getCentralAngle);
result &= getOptionalNumber(pos, boobyTrap.effectStart(), &CentralAesByteReader::getEffectStart);
result &= getOptionalNumber(pos, boobyTrap.partyId(), &CentralAesByteReader::getPartyId);
DEBUG_LOG(m_logger) << "Got BoobyTrap:"
<< "\nid = " << boobyTrap.id()
<< "\nname = " << boobyTrap.name()
<< "\neffectDuration = " << boobyTrap.effectDuration()
<< "\nchargeTypeId = " << boobyTrap.chargeTypeId()
<< "\nimpactPosition = " << boobyTrap.impactPosition()
<< "\nimpactRadius = " << boobyTrap.impactRadius()
<< "\ntriggerRadius = " << boobyTrap.triggerRadius()
<< "\nrotationAngle = " << boobyTrap.rotationAngle()
<< "\ncentralAngle = " << boobyTrap.centralAngle()
<< "\neffectStart = " << boobyTrap.effectStart()
<< "\npartyId = " << boobyTrap.partyId();
return result;
}
bool CentralAesByteReader::getOffRouteMine(size_t &pos, AreaEffectSimulation::OffRouteMineModifyRequest &offRouteMine) const
{
bool result = getAesItemId(pos, offRouteMine.id());
result &= getName(pos, offRouteMine.name());
result &= getEffectDuration(pos, offRouteMine.effectDuration());
result &= getChargeTypeId(pos, offRouteMine.chargeTypeId());
result &= getArea(pos, offRouteMine.area());
result &= getOptionalNumber(pos, offRouteMine.impactRadius(), &CentralAesByteReader::getImpactRadius);
result &= getOptionalNumber(pos, offRouteMine.effectStart(), &CentralAesByteReader::getEffectStart);
result &= getOptionalNumber(pos, offRouteMine.partyId(), &CentralAesByteReader::getPartyId);
DEBUG_LOG(m_logger) << "Got OffRouteMine: "
<< "\nid: " << offRouteMine.id()
<< "\nname = " << offRouteMine.name()
<< "\neffectDuration = " << offRouteMine.effectDuration()
<< "\nchargeTypeId = " << offRouteMine.chargeTypeId()
<< "\narea = " << offRouteMine.area()
<< "\nimpactRadius = " << offRouteMine.impactRadius()
<< "\neffectStart = " << offRouteMine.effectStart()
<< "\npartyId = " << offRouteMine.partyId();
return result;
}
bool CentralAesByteReader::getExplosionCluster(size_t &pos, AreaEffectSimulation::ExplosionClusterOcModifyRequest &explosionCluster) const
{
bool result = getAesItemId(pos, explosionCluster.id());
result &= getName(pos, explosionCluster.name());
result &= getEffectStart(pos, explosionCluster.effectStart());
result &= getEffectDuration(pos, explosionCluster.effectDuration());
result &= getArea(pos, explosionCluster.area());
result &= getMhpCount(pos, explosionCluster.mhpCount());
result &= getMhpRotation(pos, explosionCluster.mhpRotation());
result &= getImpactCount(pos, explosionCluster.impactCount());
result &= getChargeTypeId(pos, explosionCluster.chargeStruct().chargeTypeId());
result &= getPartyId(pos, explosionCluster.partyId());
DEBUG_LOG(m_logger) << "Got ExplosionCluster:"
<< "\nid: " << explosionCluster.id()
<< "\nname: " << explosionCluster.name()
<< "\neffectStart: " << explosionCluster.effectStart()
<< "\neffectDuration: " << explosionCluster.effectDuration()
<< "\narea: " << explosionCluster.area()
<< "\nmhpCount: " << explosionCluster.mhpCount()
<< "\nmhpRotation: " << explosionCluster.mhpRotation()
<< "\nimpactCount: " << explosionCluster.impactCount()
<< "\nchargeTypeId: " << explosionCluster.chargeStruct().chargeTypeId()
<< "\npartyId: " << explosionCluster.partyId();
return result;
}
bool CentralAesByteReader::getAesItemId(size_t &pos, int32_t &aesItemId) const
{
return LtsUtils::get4Byte(m_data, pos, aesItemId);
}
bool CentralAesByteReader::getAesMaLayingProcedureType(size_t &pos, AreaEffectSimulation::AesMaLayingProcedureType &aesMaLayingProcedureType) const
{
return getDdsEnumVal(pos, aesMaLayingProcedureType);
}
bool CentralAesByteReader::getAesType(size_t &pos, AreaEffectSimulation::AesType &aesType) const
{
return getDdsEnumVal(pos, aesType);
}
bool CentralAesByteReader::getAltitude(size_t &pos, int32_t &altitude) const
{
return LtsUtils::get4Byte(m_data, pos, altitude);
}
bool CentralAesByteReader::getArea(size_t &pos, AreaEffectSimulation::Area &area) const
{
bool result = getPosition2D(pos, area.cornerBottomLeft());
result &= LtsUtils::get8Byte(m_data, pos, area.width());
result &= LtsUtils::get8Byte(m_data, pos, area.height());
result &= LtsUtils::get8Byte(m_data, pos, area.rotation());
return result;
}
bool CentralAesByteReader::getBorderLengthInner(size_t &pos, double &borderLengthInner) const
{
return LtsUtils::get8Byte(m_data, pos, borderLengthInner);
}
bool CentralAesByteReader::getBorderLengthOuter(size_t &pos, double &borderLengthOuter) const
{
return LtsUtils::get8Byte(m_data, pos, borderLengthOuter);
}
bool CentralAesByteReader::getCannonCount(size_t &pos, int32_t &cannonCount) const
{
return LtsUtils::get4Byte(m_data, pos, cannonCount);
}
bool CentralAesByteReader::getCannonRounds(size_t &pos, int32_t &cannonRounds) const
{
return LtsUtils::get4Byte(m_data, pos, cannonRounds);
}
bool CentralAesByteReader::getChargeTypeId(size_t &pos, int32_t &chargeType) const
{
return LtsUtils::get4Byte(m_data, pos, chargeType);
}
bool CentralAesByteReader::getCentralAesChangeType(size_t &pos, OcSituation::CentralAesChangeType &changeType) const
{
return LtsUtils::get1Byte(m_data, pos, changeType);
}
bool CentralAesByteReader::getCentralAngle(size_t &pos, double &centralAngle) const
{
return LtsUtils::get8Byte(m_data, pos, centralAngle);
}
template<typename T>
bool CentralAesByteReader::getDdsEnumVal(size_t &pos, T &ddsEnumVal) const
{
int32_t tempVal;
bool result = LtsUtils::get4Byte(m_data, pos, tempVal);
ddsEnumVal = static_cast<typename T::inner_enum>(tempVal);
return result;
}
bool CentralAesByteReader::getDeconMode(size_t &pos, AreaEffectSimulation::AesOperatingMode &deconMode) const
{
return getDdsEnumVal(pos, deconMode);
}
bool CentralAesByteReader::getDeconTime(size_t &pos, int32_t &deconTime) const
{
return LtsUtils::get4Byte(m_data, pos, deconTime);
}
bool CentralAesByteReader::getDensity(size_t &pos, double &density) const
{
return LtsUtils::get8Byte(m_data, pos, density);
}
bool CentralAesByteReader::getDetonationValue(size_t &pos, double &detonationValue) const
{
return LtsUtils::get8Byte(m_data, pos, detonationValue);
}
bool CentralAesByteReader::getEffectDuration(size_t &pos, int32_t &effectDuration) const
{
return LtsUtils::get4Byte(m_data, pos, effectDuration);
}
bool CentralAesByteReader::getEffectStart(size_t &pos, rti::core::int64 &effectStart) const
{
return LtsUtils::get8Byte(m_data, pos, effectStart);
}
bool CentralAesByteReader::getExplosionGeometry(size_t &pos, AreaEffectSimulation::AesExplosionGeometry &explosionGeometry) const
{
return getDdsEnumVal(pos, explosionGeometry);
}
bool CentralAesByteReader::getFireRequestTime(size_t &pos, rti::core::int64 &fireRequestTime) const
{
return LtsUtils::get8Byte(m_data, pos, fireRequestTime);
}
bool CentralAesByteReader::getFunctionalAreaTypeId(size_t &pos, int32_t &functionalAreaTypeId) const
{
return LtsUtils::get4Byte(m_data, pos, functionalAreaTypeId);
}
bool CentralAesByteReader::getIgniterType(size_t &pos, int32_t igniterTypeId) const
{
return LtsUtils::get4Byte(m_data, pos, igniterTypeId);
}
bool CentralAesByteReader::getImpactCount(size_t &pos, int32_t &impactCount) const
{
return LtsUtils::get4Byte(m_data, pos, impactCount);
}
bool CentralAesByteReader::getImpactPosition(size_t &pos, Core::GeoPosition2D &position) const
{
return getPosition2D(pos, position);
}
bool CentralAesByteReader::getImpactRadius(size_t &pos, double &impactRadius) const
{
return LtsUtils::get8Byte(m_data, pos, impactRadius);
}
bool CentralAesByteReader::getIsCenterLine(size_t &pos, bool &isCenterLine) const
{
return LtsUtils::get1Byte(m_data, pos, isCenterLine);
}
bool CentralAesByteReader::getIsLayedHidden(size_t &pos, bool &isLayedHidden) const
{
return LtsUtils::get1Byte(m_data, pos, isLayedHidden);
}
bool CentralAesByteReader::getMaintMode(size_t &pos, AreaEffectSimulation::AesOperatingMode &maintMode) const
{
return getDdsEnumVal(pos, maintMode);
}
bool CentralAesByteReader::getMaintTime(size_t &pos, int32_t &maintTime) const
{
return LtsUtils::get4Byte(m_data, pos, maintTime);
}
bool CentralAesByteReader::getMedicMode(size_t &pos, AreaEffectSimulation::AesOperatingMode &medicMode) const
{
return getDdsEnumVal(pos, medicMode);
}
bool CentralAesByteReader::getMedicTime(size_t &pos, int32_t &medicTime) const
{
return LtsUtils::get4Byte(m_data, pos, medicTime);
}
bool CentralAesByteReader::getMhpCount(size_t &pos, int32_t &mhpCount) const
{
return LtsUtils::get4Byte(m_data, pos, mhpCount);
}
bool CentralAesByteReader::getMhpRotation(size_t &pos, double &mhpRotation) const
{
return LtsUtils::get8Byte(m_data, pos, mhpRotation);
}
bool CentralAesByteReader::getName(size_t &pos, std::string &name) const
{
return getString(pos, name);
}
template<typename T>
bool CentralAesByteReader::getOptionalNumber(size_t &pos, rti::core::optional<T> &optionalNumber, bool(CentralAesByteReader::*method)(size_t &pos, T &number) const) const
{
T value;
bool result = (*this.*method)(pos, value);
if (value != -1)
optionalNumber.set(value);
return result;
}
bool CentralAesByteReader::getPartyId(size_t &pos, int32_t &partyId) const
{
return LtsUtils::get4Byte(m_data, pos, partyId);
}
bool CentralAesByteReader::getPointSymbol(size_t &pos, std::string &pointSymbol) const
{
return getString(pos, pointSymbol);
}
bool CentralAesByteReader::getPosition2D(size_t &pos, Core::GeoPosition2D &position) const
{
bool result = LtsUtils::get8Byte(m_data, pos, position.lon());
result &= LtsUtils::get8Byte(m_data, pos, position.lat());
return result;
}
bool CentralAesByteReader::getPropagationDirection(size_t &pos, double &propagationDirection) const
{
return LtsUtils::get8Byte(m_data, pos, propagationDirection);
}
bool CentralAesByteReader::getPurpose(size_t &pos, std::string &purpose) const
{
return getString(pos, purpose);
}
bool CentralAesByteReader::getRotationAngle(size_t &pos, double &rotationAngle) const
{
return LtsUtils::get8Byte(m_data, pos, rotationAngle);
}
bool CentralAesByteReader::getSegments(size_t &pos, std::vector<Core::GeoPosition2D> &segments) const
{
int tmp;
bool result = LtsUtils::get1Byte(m_data, pos, tmp);
size_t len = tmp;
if (len < 1)
return result;
Core::GeoPosition2D geoPos;
for (size_t counter = 0; counter < len; ++counter)
{
result &= getPosition2D(pos, geoPos);
segments.push_back(geoPos);
}
return result;
}
bool CentralAesByteReader::getSpanAngle(size_t &pos, double &spanAngle) const
{
return LtsUtils::get8Byte(m_data, pos, spanAngle);
}
bool CentralAesByteReader::getString(size_t &pos, std::string &str) const
{
int tmp;
bool result = LtsUtils::get1Byte(m_data, pos, tmp);
size_t len = tmp;
if (static_cast<size_t>(m_data.size()) < (pos + len))
result = false;
if (result)
str = m_data.mid(pos, len).toStdString();
pos += len;
return result;
}
bool CentralAesByteReader::getTriggerRadius(size_t &pos, double &triggerRadius) const
{
return LtsUtils::get8Byte(m_data, pos, triggerRadius);
}
bool CentralAesByteReader::getWidth(size_t &pos, double &width) const
{
return LtsUtils::get8Byte(m_data, pos, width);
}
bool CentralAesByteReader::getWindSpeed(size_t &pos, double &windSpeed) const
{
return LtsUtils::get8Byte(m_data, pos, windSpeed);
}
} // namespace OcSituationClient
+108
View File
@@ -0,0 +1,108 @@
/**
* Class for reading oc data
* $Id: handler_oc_situation_data.h 57655 2022-07-20 11:38:28Z karwat $
* $HeadURL: svn://192.168.133.21/TDS/branches/product/features/3dws_devel/Lts/Services/OcSituationClient/handler_oc_situation_data.h $
* $Author: karwat $
* Created by Hannes Fritsche, SLTE, 30-08-2023
*/
#pragma once
#include <QByteArray>
#include "AreaEffectSimulation/aes_dtc.h"
#include "OcSituationServer/oc_situation.h"
#include "logger.h"
namespace OcSituationClient
{
class CentralAesByteReader
{
public:
struct RemoveMessage
{
qint32 aesItemId;
AreaEffectSimulation::AesType aesType;
RemoveMessage(qint32 aesItemId, AreaEffectSimulation::AesType aesType)
: aesItemId(aesItemId)
, aesType(aesType)
{}
RemoveMessage()
: RemoveMessage(-1, AreaEffectSimulation::AesType::inner_enum::AtUnknown)
{}
};
explicit CentralAesByteReader(const QByteArray &data);
bool getRemoveMessage(size_t &pos, RemoveMessage &removeMessage) const;
bool getNContamination(size_t &pos, AreaEffectSimulation::NContaminationModifyRequest &nContamination) const;
bool getBCContamination(size_t &pos, AreaEffectSimulation::BCContaminationModifyRequest &bCContamination) const;
bool getExplosionArea(size_t &pos, AreaEffectSimulation::ExplosionAreaModifyRequest &explosionArea) const;
bool getExplosionSingle(size_t &pos, AreaEffectSimulation::ExplosionSingleModifyRequest &explosionSingle) const;
bool getMineArea(size_t &pos, AreaEffectSimulation::MineAreaModifyRequest &mineArea) const;
bool getFunctionalArea(size_t &pos, AreaEffectSimulation::FunctionalAreaModifyRequest &functionalArea) const;
bool getBoobyTrap(size_t &pos, AreaEffectSimulation::BoobyTrapModifyRequest &boobyTrap) const;
bool getOffRouteMine(size_t &pos, AreaEffectSimulation::OffRouteMineModifyRequest &offRouteMine) const;
bool getExplosionCluster(size_t &pos, AreaEffectSimulation::ExplosionClusterOcModifyRequest &explosionCluster) const;
bool getAesType(size_t &pos, AreaEffectSimulation::AesType &aesType) const;
bool getCentralAesChangeType(size_t &pos, OcSituation::CentralAesChangeType &changeType) const;
private:
bool getAesItemId(size_t &pos, int32_t &aesItemId) const;
bool getAesMaLayingProcedureType(size_t &pos, AreaEffectSimulation::AesMaLayingProcedureType &aesMaLayingProcedureType) const;
bool getAltitude(size_t &pos, int32_t &altitude) const;
bool getArea(size_t &pos, AreaEffectSimulation::Area &area) const;
bool getBorderLengthInner(size_t &pos, double &borderLengthInner) const;
bool getBorderLengthOuter(size_t &pos, double &borderLengthOuter) const;
bool getCannonCount(size_t &pos, int32_t &cannonCount) const;
bool getCannonRounds(size_t &pos, int32_t &cannonRounds) const;
bool getChargeTypeId(size_t &pos, int32_t &chargeType) const;
bool getCentralAngle(size_t &pos, double &centralAngle) const;
template <typename T>
bool getDdsEnumVal(size_t &pos, T &ddsEnumVal) const;
bool getDeconMode(size_t &pos, AreaEffectSimulation::AesOperatingMode &deconMode) const;
bool getDeconTime(size_t &pos, int32_t &deconTime) const;
bool getDensity(size_t &pos, double &density) const;
bool getDetonationValue(size_t &pos, double &detonationValue) const;
bool getEffectDuration(size_t &pos, int32_t &effectDuration) const;
bool getEffectStart(size_t &pos, rti::core::int64 &effectStart) const;
bool getExplosionGeometry(size_t &pos, AreaEffectSimulation::AesExplosionGeometry &explosionGeometry) const;
bool getFireRequestTime(size_t &pos, rti::core::int64 &fireRequestTime) const;
bool getFunctionalAreaTypeId(size_t &pos, int32_t &functionalAreaTypeId) const;
bool getIgniterType(size_t &pos, int32_t igniterTypeId) const;
bool getImpactCount(size_t &pos, int32_t &impactCount) const;
bool getImpactPosition(size_t &pos, Core::GeoPosition2D &position) const;
bool getImpactRadius(size_t &pos, double &impactRadius) const;
bool getIsCenterLine(size_t &pos, bool &isCenterLine) const;
bool getIsLayedHidden(size_t &pos, bool &isLayedHidden) const;
bool getMaintMode(size_t &pos, AreaEffectSimulation::AesOperatingMode &maintMode) const;
bool getMaintTime(size_t &pos, int32_t &maintTime) const;
bool getMedicMode(size_t &pos, AreaEffectSimulation::AesOperatingMode &medicMode) const;
bool getMedicTime(size_t &pos, int32_t &medicTime) const;
bool getMhpCount(size_t &pos, int32_t &mhpCount) const;
bool getMhpRotation(size_t &pos, double &mhpRotation) const;
bool getName(size_t &pos, std::string &name) const;
template <typename T>
bool getOptionalNumber(size_t &pos, rti::core::optional<T> &optionalNumber, bool(CentralAesByteReader::*method)(size_t &pos, T &number) const) const;
bool getPartyId(size_t &pos, int32_t &partyId) const;
bool getPointSymbol(size_t &pos, std::string &pointSymbol) const;
bool getPosition2D(size_t &pos, Core::GeoPosition2D &position) const;
bool getPropagationDirection(size_t &pos, double &propagationDirection) const;
bool getPurpose(size_t &pos, std::string &purpose) const;
bool getRotationAngle(size_t &pos, double &rotationAngle) const;
bool getSegments(size_t &pos, std::vector<Core::GeoPosition2D> &segments) const;
bool getSpanAngle(size_t &pos, double &spanAngle) const;
bool getString(size_t &pos, std::string &str) const;
bool getTriggerRadius(size_t &pos, double &triggerRadius) const;
bool getWidth(size_t &pos, double &width) const;
bool getWindSpeed(size_t &pos, double &windSpeed) const;
private:
const QByteArray m_data;
LOGGER_T &m_logger;
};
} // namespace OcSituationClient
+54
View File
@@ -0,0 +1,54 @@
/**
* DdsHandler for DDS
* $Id$
* $HeadURL$
* $Author$
* Created by Hanna E. Rathje, SLSE, 2015-09-02
*/
#include "dds_handler.h"
#include <DDS/Core/pacemaker.h>
namespace OcSituationClient
{
DdsHandler::DdsHandler(int domainId, int exerciseId)
: m_ddsConnector(std::make_shared<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();
m_dtcCore = Core::Interface::Dtc::create(m_ddsConnector);
bool bRet = m_dtcCore->enablePartitionTime();
// Pacemaker
m_pacemaker = std::make_shared<Core::Pacemaker>(m_ddsConnector);
m_topicLockMaster = std::make_shared<Core::TopicLockMaster>(m_ddsConnector);
m_ddsFts = OcSituationClient::Interface::Fts::create(m_ddsConnector);
bRet &= m_ddsFts->enableAll();
INFO_LOG(m_logger) << "Fts initialised";
return bRet;
}
qint64 DdsHandler::currentPartitionTime() const
{
return m_dtcCore->partitionTime().timeStamp();
}
} // namespace OcSituationClient
+53
View File
@@ -0,0 +1,53 @@
/**
* DdsHandler for DDS
* $Id$
* $HeadURL$
* $Author$
* Created by Hanna E. Rathje, SLSE, 2015-09-02
*/
#pragma once
#include <DDS/DDSConnector/dds_connector.h>
#include <DDS/Core/topic_lock_master.h>
#include <DDS/Core/core_dtc.h>
#include <OcSituationClient/osc_fts.h>
#include "logger.h"
namespace Core
{
class Pacemaker;
}
namespace OcSituationClient
{
class DdsHandler final
{
public:
DdsHandler(int domainId, int exerciseId);
~DdsHandler() = default;
bool init(const QStringList &qosFileList = QStringList());
std::shared_ptr<Core::Pacemaker> pacemaker() const { return m_pacemaker; }
std::shared_ptr<DDSConnector::DdsConnector> dds() const { return m_ddsConnector; }
std::shared_ptr<Core::TopicLockMaster> topicLockMaster() const { return m_topicLockMaster; }
std::shared_ptr<OcSituationClient::Interface::Fts> fts() const { return m_ddsFts; }
qint64 currentPartitionTime() const;
private:
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
std::shared_ptr<Core::Pacemaker> m_pacemaker;
std::shared_ptr<Core::TopicLockMaster> m_topicLockMaster;
std::shared_ptr<Core::Interface::Dtc> m_dtcCore;
std::shared_ptr<OcSituationClient::Interface::Fts> m_ddsFts;
NGL::INGLLogger &m_logger;
};
} // namespace OcSituationClient
+288
View File
@@ -0,0 +1,288 @@
/**
* 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
+60
View File
@@ -0,0 +1,60 @@
/**
* Handler for aes data received transparent by the oc-laptop
* $Id$
* $HeadURL$
* $Author$
* Created by Philipp Dassow, NLST, 18-04-2018
*/
#pragma once
#include <QObject>
#include <QPointF>
#include <LtsCoordTrans/lts_coord_trans.h>
#include "main_handler.h"
#include "logger.h"
namespace OcSituationClient
{
class HandlerOcAesData : public QObject
, protected AreaEffectSimulation::Interface::Ftc::DangerAreaModifyReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::DangerAreaRemoveReplyHandler
{
Q_OBJECT
public:
explicit HandlerOcAesData(MainHandler *mainHandler,
QObject *parent = nullptr);
~HandlerOcAesData();
bool init();
void process(const QByteArray &data);
void onDangerAreaModifyReply(const Core::FunctionReplyObject &reply);
void onDangerAreaRemoveReply(const Core::FunctionReplyObject &reply);
private:
void handleDangerAreas(const QByteArray &data, size_t pos);
void handleIeds(const QByteArray &data, size_t pos);
void handleIedPositions(const QByteArray &data, size_t pos);
Core::GeoPosition2D relativeFromGeoPosition(int x, int y);
void onSpecificsExerciseChanged(const TrainingAreaBaseOC::SpecificsExercise &data, DataModification mod);
// for partition time
std::shared_ptr<DdsHandler> m_dds;
// data publishing
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> m_aesDtc;
std::shared_ptr<AreaEffectSimulation::Interface::Ftc> m_aesFtc;
std::shared_ptr<GuezIedManagement::Interface::Dtc> m_gimDtc;
std::shared_ptr<TrainingAreaBase::Interface::Dts> m_tabDts;
std::shared_ptr<TrainingAreaBaseOC::Interface::Dtc> m_tabocDtc;
LtsCoordTrans::UtmCoordinate m_utmCoord; // for position translation to relative
LOGGER_T &m_logger;
};
} // namespace OcSituationClient
@@ -0,0 +1,622 @@
/**
* Handler for all oc situation data at the client
* $Id: handler_oc_situation_data.cpp 57655 2022-07-20 11:38:28Z karwat $
* $HeadURL: svn://192.168.133.21/TDS/branches/product/features/3dws_devel/Lts/Services/OcSituationClient/handler_oc_situation_data.cpp $
* $Author: karwat $
* Created by Philipp Dassow, NLST, 01-03-2018
*/
#include "handler_oc_central_aes_data.h"
#include <QLineF>
#include <QPointF>
#include <QTimer>
#include <Common/LtsCoordTrans/lts_coord_trans.h>
#include <LtsUtilsCore/qbytearray_byteaccess.h>
#include "central_aes_byte_reader.h"
#include "main_handler.h"
#include "settings.h"
namespace OcSituationClient
{
HandlerOcCentralAesData::HandlerOcCentralAesData(const std::shared_ptr<AreaEffectSimulation::Interface::Dtc> &aesDtc,
const std::shared_ptr<AreaEffectSimulation::Interface::Ftc> &aesFtc,
const std::shared_ptr<TrainingAreaBaseOC::Interface::Dts> &tabocDts,
QObject *parent)
: QObject(parent), m_aesDtc(aesDtc), m_aesFtc(aesFtc), m_tabocDts(tabocDts), m_logger(getLogger("HandlerOcCentralAesData"))
{
}
HandlerOcCentralAesData::~HandlerOcCentralAesData() {}
bool HandlerOcCentralAesData::init()
{
// AES DTC enable
if (!m_aesDtc->enableNContamination() || !m_aesDtc->enableBCContamination() || !m_aesDtc->enableExplosionArea() || !m_aesDtc->enableExplosionSingle()
|| !m_aesDtc->enableMineArea() || !m_aesDtc->enableFunctionalArea() || !m_aesDtc->enableBoobyTrap() || !m_aesDtc->enableOffRouteMine()
|| !m_aesDtc->enableExplosionCluster())
{
ERROR_LOG(m_logger) << "Enabling AES Data-Topics failed.";
return false;
}
// AES FTC enable
if (!m_aesFtc->enableNContaminationModify() || !m_aesFtc->enableNContaminationRemove() || !m_aesFtc->enableBCContaminationModify()
|| !m_aesFtc->enableBCContaminationRemove() || !m_aesFtc->enableExplosionAreaModify() || !m_aesFtc->enableExplosionAreaRemove()
|| !m_aesFtc->enableExplosionSingleModify() || !m_aesFtc->enableExplosionSingleRemove() || !m_aesFtc->enableMineAreaModify() || !m_aesFtc->enableMineAreaRemove()
|| !m_aesFtc->enableFunctionalAreaModify() || !m_aesFtc->enableFunctionalAreaRemove() || !m_aesFtc->enableBoobyTrapModify() || !m_aesFtc->enableBoobyTrapRemove()
|| !m_aesFtc->enableOffRouteMineModify() || !m_aesFtc->enableOffRouteMineRemove() || !m_aesFtc->enableExplosionClusterOcModify()
|| !m_aesFtc->enableExplosionClusterRemove() || !m_aesFtc->enableMineAreaReferenceModify())
{
ERROR_LOG(m_logger) << "Enabling AES Function-Topics failed.";
return false;
}
// TABOC DTS enable
if (!m_tabocDts->enableCentralAesOverload())
{
ERROR_LOG(m_logger) << "Enabling TABOC Data-Topics failed.";
return false;
}
m_aesDtc->nContaminations(
[this](const AreaEffectSimulation::NContamination &data)
{
if (!data.isCentral())
return;
m_allCentralAesItems.insert(data.id(), AreaEffectSimulation::AesType::AtNContamination);
});
m_aesDtc->bCContaminations(
[this](const AreaEffectSimulation::BCContamination &data)
{
if (!data.isCentral())
return;
m_allCentralAesItems.insert(data.id(), AreaEffectSimulation::AesType::AtBCContamination);
});
m_aesDtc->explosionAreas(
[this](const AreaEffectSimulation::ExplosionArea &data)
{
if (!data.isCentral())
return;
m_allCentralAesItems.insert(data.id(), AreaEffectSimulation::AesType::AtExplosionArea);
});
m_aesDtc->explosionSingles(
[this](const AreaEffectSimulation::ExplosionSingle &data)
{
if (!data.isCentral())
return;
m_allCentralAesItems.insert(data.id(), AreaEffectSimulation::AesType::AtExplosionSingle);
});
m_aesDtc->mineAreas(
[this](const AreaEffectSimulation::MineArea &data)
{
if (!data.isCentral())
return;
m_allCentralAesItems.insert(data.id(), AreaEffectSimulation::AesType::AtMineArea);
});
m_aesDtc->functionalAreas(
[this](const AreaEffectSimulation::FunctionalArea &data)
{
if (!data.isCentral())
return;
m_allCentralAesItems.insert(data.id(), AreaEffectSimulation::AesType::AtFunctionalArea);
});
m_aesDtc->boobyTraps(
[this](const AreaEffectSimulation::BoobyTrap &data)
{
if (!data.isCentral())
return;
m_allCentralAesItems.insert(data.id(), AreaEffectSimulation::AesType::AtBoobyTrap);
});
m_aesDtc->offRouteMines(
[this](const AreaEffectSimulation::OffRouteMine &data)
{
if (!data.isCentral())
return;
m_allCentralAesItems.insert(data.id(), AreaEffectSimulation::AesType::AtOffRouteMine);
});
m_aesDtc->explosionClusters(
[this](const AreaEffectSimulation::ExplosionCluster &data)
{
if (!data.isCentral())
return;
m_allCentralAesItems.insert(data.id(), AreaEffectSimulation::AesType::AtExplosionCluster);
});
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::nContaminationChanged, this, &HandlerOcCentralAesData::onNContaminationChanged);
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::bCContaminationChanged, this, &HandlerOcCentralAesData::onBCContaminationChanged);
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::explosionAreaChanged, this, &HandlerOcCentralAesData::onExplosionAreaChanged);
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::explosionSingleChanged, this, &HandlerOcCentralAesData::onExplosionSingleChanged);
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::mineAreaChanged, this, &HandlerOcCentralAesData::onMineAreaChanged);
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::functionalAreaChanged, this, &HandlerOcCentralAesData::onFunctionalAreaChanged);
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::boobyTrapChanged, this, &HandlerOcCentralAesData::onBoobyTrapChanged);
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::offRouteMineChanged, this, &HandlerOcCentralAesData::onOffRouteMineChanged);
connect(m_aesDtc.get(), &AreaEffectSimulation::Interface::Dtc::explosionClusterChanged, this, &HandlerOcCentralAesData::onExplosionClusterChanged);
DEBUG_LOG(m_logger) << "Initialisation HandlerOcCentralAesData succesful.";
return true;
}
void HandlerOcCentralAesData::process(const QByteArray &data, bool bIsInitial)
{
DEBUG_LOG(m_logger) << "Starting to parse central aes data.";
if (bIsInitial)
{
DEBUG_LOG(m_logger) << "Data is initial --> removing central aes items.";
removeAllCentralAesItems();
if (!m_allCentralAesItems.isEmpty())
{
QTimer::singleShot(500, this, [this, data, bIsInitial]() { process(data, bIsInitial); });
return;
}
}
if (data.isEmpty())
{
ERROR_LOG(m_logger) << "Got an empty QByteArray to decode.";
return;
}
bool centralAesItemsOverloaded = false;
LtsUtils::get1Byte(data, centralAesItemsOverloaded);
TrainingAreaBaseOC::CentralAesOverload centralAesOverload;
centralAesOverload.id(1);
centralAesOverload.hasOverload(centralAesItemsOverloaded);
m_tabocDts->publish(centralAesOverload);
DEBUG_LOG(m_logger) << "Central AesItems overloaded: " << centralAesItemsOverloaded;
// TODO: Further processing of overloaded info
QByteArray data2 = data;
data2.remove(0, 1);
QByteArray uncompressed = MainHandler::tryUncompress(data2, m_bWithCompression);
if (uncompressed.isEmpty())
{
INFO_LOG(m_logger) << "Got an empty QByteArray after uncompression.";
return;
}
CentralAesByteReader reader(uncompressed);
TRACE_LOG(m_logger) << "Uncompressed Data: " << uncompressed.toHex(' ');
size_t pos = 0;
AreaEffectSimulation::AesType aesType;
OcSituation::CentralAesChangeType changeType;
while (pos < static_cast<size_t>(uncompressed.size()))
{
if (!reader.getCentralAesChangeType(pos, changeType))
{
FATAL_LOG(m_logger) << "Coul not read CentralAesChangeType --> aborting.";
return;
}
DEBUG_LOG(m_logger) << "Got AesChangeType " << changeType;
switch (changeType)
{
case OcSituation::AddMod:
if (!reader.getAesType(pos, aesType))
{
FATAL_LOG(m_logger) << "Coul not read AesType --> aborting.";
return;
}
DEBUG_LOG(m_logger) << "Got AesType " << aesType;
switch (aesType.underlying())
{
case AreaEffectSimulation::AesType::AtUnknown:
case AreaEffectSimulation::AesType::AtDangerArea:
case AreaEffectSimulation::AesType::AtMineCorridor:
case AreaEffectSimulation::AesType::AtBorderline:
case AreaEffectSimulation::AesType::AtTechnicalArea:
case AreaEffectSimulation::AesType::AtExplosionSingleCentral:
case AreaEffectSimulation::AesType::AtReconArea:
case AreaEffectSimulation::AesType::AtDusSingleMine:
case AreaEffectSimulation::AesType::AtExplosionAreaSingleExplosions:
case AreaEffectSimulation::AesType::AtMineAreaSingleMines:
case AreaEffectSimulation::AesType::AtGasPipe:
case AreaEffectSimulation::AesType::AtAirSupportImpact:
case AreaEffectSimulation::AesType::AtExplosionSingleCentralTrajectory:
case AreaEffectSimulation::AesType::AtBoobyTrapSecondary:
case AreaEffectSimulation::AesType::AtOffRouteMineSecondary:
FATAL_LOG(m_logger) << "Got false AesType: " << aesType.underlying() << " --> aborting.";
return;
case AreaEffectSimulation::AesType::AtNContamination:
{
AreaEffectSimulation::NContaminationModifyRequest nContamination;
if (!reader.getNContamination(pos, nContamination))
{
FATAL_LOG(m_logger) << "Could not read NContamination --> aborting.";
return;
}
else
DEBUG_LOG(m_logger) << "NContamination added/modified.";
checkId(nContamination);
m_aesFtc->nContaminationModifyRequest(nContamination, this);
break;
}
case AreaEffectSimulation::AesType::AtBCContamination:
{
AreaEffectSimulation::BCContaminationModifyRequest bCContamination;
if (!reader.getBCContamination(pos, bCContamination))
{
FATAL_LOG(m_logger) << "Could not read BCContamination --> aborting.";
return;
}
else
DEBUG_LOG(m_logger) << "BCContamination added/modified.";
checkId(bCContamination);
m_aesFtc->bCContaminationModifyRequest(bCContamination, this);
break;
}
case AreaEffectSimulation::AesType::AtExplosionArea:
{
AreaEffectSimulation::ExplosionAreaModifyRequest explosionArea;
if (!reader.getExplosionArea(pos, explosionArea))
{
FATAL_LOG(m_logger) << "Could not read ExplosionArea --> aborting.";
return;
}
else
DEBUG_LOG(m_logger) << "ExplosionArea added/modified.";
checkId(explosionArea);
m_aesFtc->explosionAreaModifyRequest(explosionArea, this);
break;
}
case AreaEffectSimulation::AesType::AtExplosionSingle:
{
AreaEffectSimulation::ExplosionSingleModifyRequest explosionSingle;
if (!reader.getExplosionSingle(pos, explosionSingle))
{
FATAL_LOG(m_logger) << "Could not read ExplosionSingle --> aborting.";
return;
}
else
DEBUG_LOG(m_logger) << "ExplosionSingle added/modified.";
checkId(explosionSingle);
m_aesFtc->explosionSingleModifyRequest(explosionSingle, this);
break;
}
case AreaEffectSimulation::AesType::AtMineArea:
{
AreaEffectSimulation::MineAreaModifyRequest mineArea;
if (!reader.getMineArea(pos, mineArea))
{
FATAL_LOG(m_logger) << "Could not read MineArea --> aborting.";
return;
}
else
DEBUG_LOG(m_logger) << "MineArea added/modified.";
mineArea.distance() = 0.5;
checkId(mineArea);
m_aesFtc->mineAreaModifyRequest(mineArea, this);
break;
}
case AreaEffectSimulation::AesType::AtFunctionalArea:
{
AreaEffectSimulation::FunctionalAreaModifyRequest functionalArea;
if (!reader.getFunctionalArea(pos, functionalArea))
{
FATAL_LOG(m_logger) << "Could not read FunctionalArea --> aborting.";
return;
}
else
DEBUG_LOG(m_logger) << "FunctionalArea added/modified.";
checkId(functionalArea);
m_aesFtc->functionalAreaModifyRequest(functionalArea, this);
break;
}
case AreaEffectSimulation::AesType::AtBoobyTrap:
{
AreaEffectSimulation::BoobyTrapModifyRequest boobyTrap;
if (!reader.getBoobyTrap(pos, boobyTrap))
{
FATAL_LOG(m_logger) << "Could not read BoobyTrap --> aborting.";
return;
}
else
DEBUG_LOG(m_logger) << "BoobyTrap added/modified.";
checkId(boobyTrap);
m_aesFtc->boobyTrapModifyRequest(boobyTrap, this);
break;
}
case AreaEffectSimulation::AesType::AtOffRouteMine:
{
AreaEffectSimulation::OffRouteMineModifyRequest offRouteMine;
if (!reader.getOffRouteMine(pos, offRouteMine))
{
FATAL_LOG(m_logger) << "Could not read OffRouteMine --> aborting.";
return;
}
else
DEBUG_LOG(m_logger) << "OffRouteMine added/modified.";
checkId(offRouteMine);
m_aesFtc->offRouteMineModifyRequest(offRouteMine, this);
break;
}
case AreaEffectSimulation::AesType::AtExplosionCluster:
{
AreaEffectSimulation::ExplosionClusterOcModifyRequest explosionCluster;
if (!reader.getExplosionCluster(pos, explosionCluster))
{
FATAL_LOG(m_logger) << "Could not read ExplosionCluster --> aborting.";
return;
}
else
DEBUG_LOG(m_logger) << "ExplosionCluster added/modified.";
checkId(explosionCluster);
m_aesFtc->explosionClusterOcModifyRequest(explosionCluster, this);
break;
}
default:
break;
}
break;
case OcSituation::Remove:
{
CentralAesByteReader::RemoveMessage removeMessage;
if (!reader.getRemoveMessage(pos, removeMessage))
{
FATAL_LOG(m_logger) << "Could not read RemoveMessage --> aborting.";
return;
}
if (!m_allCentralAesItems.contains(removeMessage.aesItemId))
{
INFO_LOG(m_logger) << "Got remove message for unknown aesItemId " << removeMessage.aesItemId;
break;
}
DEBUG_LOG(m_logger) << "Sending remove request: aesItemId = " << removeMessage.aesItemId << " ,aesType = " << removeMessage.aesType;
tryRemoveAesItem(removeMessage.aesItemId, removeMessage.aesType);
break;
}
}
}
DEBUG_LOG(m_logger) << "All central aes data parsed.";
}
void HandlerOcCentralAesData::removeAllCentralAesItems()
{
using namespace AreaEffectSimulation;
for (auto it = m_allCentralAesItems.constBegin(); it != m_allCentralAesItems.constEnd(); ++it)
tryRemoveAesItem(it.key(), it.value());
}
void HandlerOcCentralAesData::onNContaminationChanged(const AreaEffectSimulation::NContamination &data, DataModification modType)
{
onAesItemChanged(data, modType, AreaEffectSimulation::AesType::AtNContamination);
}
void HandlerOcCentralAesData::onBCContaminationChanged(const AreaEffectSimulation::BCContamination &data, DataModification modType)
{
onAesItemChanged(data, modType, AreaEffectSimulation::AesType::AtBCContamination);
}
void HandlerOcCentralAesData::onExplosionAreaChanged(const AreaEffectSimulation::ExplosionArea &data, DataModification modType)
{
onAesItemChanged(data, modType, AreaEffectSimulation::AesType::AtExplosionArea);
}
void HandlerOcCentralAesData::onExplosionSingleChanged(const AreaEffectSimulation::ExplosionSingle &data, DataModification modType)
{
onAesItemChanged(data, modType, AreaEffectSimulation::AesType::AtExplosionSingle);
}
void HandlerOcCentralAesData::onMineAreaChanged(const AreaEffectSimulation::MineArea &data, DataModification modType)
{
onAesItemChanged(data, modType, AreaEffectSimulation::AesType::AtMineArea);
}
void HandlerOcCentralAesData::onFunctionalAreaChanged(const AreaEffectSimulation::FunctionalArea &data, DataModification modType)
{
onAesItemChanged(data, modType, AreaEffectSimulation::AesType::AtFunctionalArea);
}
void HandlerOcCentralAesData::onBoobyTrapChanged(const AreaEffectSimulation::BoobyTrap &data, DataModification modType)
{
onAesItemChanged(data, modType, AreaEffectSimulation::AesType::AtBoobyTrap);
}
void HandlerOcCentralAesData::onOffRouteMineChanged(const AreaEffectSimulation::OffRouteMine &data, DataModification modType)
{
onAesItemChanged(data, modType, AreaEffectSimulation::AesType::AtOffRouteMine);
}
void HandlerOcCentralAesData::onExplosionClusterChanged(const AreaEffectSimulation::ExplosionCluster &data, DataModification modType)
{
onAesItemChanged(data, modType, AreaEffectSimulation::AesType::AtExplosionCluster);
}
void HandlerOcCentralAesData::tryRemoveAesItem(qint32 aesItemId, AreaEffectSimulation::AesType aesType)
{
using namespace AreaEffectSimulation;
switch (aesType.underlying())
{
case AesType::AtUnknown:
case AesType::AtDangerArea:
case AesType::AtMineCorridor:
case AesType::AtBorderline:
case AesType::AtTechnicalArea:
case AesType::AtExplosionSingleCentral:
case AesType::AtReconArea:
case AesType::AtDusSingleMine:
case AesType::AtExplosionAreaSingleExplosions:
case AesType::AtMineAreaSingleMines:
case AesType::AtGasPipe:
case AesType::AtAirSupportImpact:
case AesType::AtExplosionSingleCentralTrajectory:
case AesType::AtBoobyTrapSecondary:
case AesType::AtOffRouteMineSecondary:
WARNING_LOG(m_logger) << "Got false AesType: " << aesType.underlying() << " --> aborting.";
break;
case AesType::AtNContamination:
removeAesItem(aesItemId, &AreaEffectSimulation::Interface::Ftc::nContaminationRemoveRequest);
break;
case AesType::AtBCContamination:
removeAesItem(aesItemId, &AreaEffectSimulation::Interface::Ftc::bCContaminationRemoveRequest);
break;
case AesType::AtExplosionArea:
removeAesItem(aesItemId, &AreaEffectSimulation::Interface::Ftc::explosionAreaRemoveRequest);
break;
case AesType::AtExplosionSingle:
removeAesItem(aesItemId, &AreaEffectSimulation::Interface::Ftc::explosionSingleRemoveRequest);
break;
case AesType::AtMineArea:
removeAesItem(aesItemId, &AreaEffectSimulation::Interface::Ftc::mineAreaRemoveRequest);
break;
case AesType::AtFunctionalArea:
removeAesItem(aesItemId, &AreaEffectSimulation::Interface::Ftc::functionalAreaRemoveRequest);
break;
case AesType::AtBoobyTrap:
removeAesItem(aesItemId, &AreaEffectSimulation::Interface::Ftc::boobyTrapRemoveRequest);
break;
case AesType::AtOffRouteMine:
removeAesItem(aesItemId, &AreaEffectSimulation::Interface::Ftc::offRouteMineRemoveRequest);
break;
case AesType::AtExplosionCluster:
removeAesItem(aesItemId, &AreaEffectSimulation::Interface::Ftc::explosionClusterRemoveRequest);
break;
default:
break;
}
}
void HandlerOcCentralAesData::onOffRouteMineModifyReply(const Core::FunctionReplyObject &reply) { onReply(reply); }
void HandlerOcCentralAesData::onBoobyTrapModifyReply(const Core::FunctionReplyObject &reply) { onReply(reply); }
void HandlerOcCentralAesData::onFunctionalAreaModifyReply(const Core::FunctionReplyObject &reply) { onReply(reply); }
void HandlerOcCentralAesData::onMineAreaModifyReply(const Core::FunctionReplyObject &reply) { onReply(reply); }
void HandlerOcCentralAesData::onExplosionSingleModifyReply(const Core::FunctionReplyObject &reply) { onReply(reply); }
void HandlerOcCentralAesData::onExplosionAreaModifyReply(const Core::FunctionReplyObject &reply) { onReply(reply); }
void HandlerOcCentralAesData::onBCContaminationModifyReply(const Core::FunctionReplyObject &reply) { onReply(reply); }
void HandlerOcCentralAesData::onNContaminationModifyReply(const Core::FunctionReplyObject &reply) { onReply(reply); }
void HandlerOcCentralAesData::onExplosionClusterOcModifyReply(const Core::FunctionReplyObject &reply) { onReply(reply); }
void HandlerOcCentralAesData::onReply(const Core::FunctionReplyObject &reply) const
{
if (reply.error())
ERROR_LOG(m_logger) << reply.str();
}
template <typename T> void HandlerOcCentralAesData::onAesItemChanged(const T &aesItem, DataModification modType, AreaEffectSimulation::AesType aesType)
{
if (!aesItem.isCentral())
return;
switch (modType)
{
case DataModification::eAdded:
m_allCentralAesItems[aesItem.id()] = aesType;
DEBUG_LOG(m_logger) << "Added new AES Item: id=" << aesItem.id() << ", type=" << aesType;
break;
case DataModification::eRemoved:
m_allCentralAesItems.remove(aesItem.id());
DEBUG_LOG(m_logger) << "Removed AES Item with id=" << aesItem.id();
break;
case DataModification::eModified:
default:
break;
}
}
template <typename T> void HandlerOcCentralAesData::checkId(T &aesItem) const
{
if (!m_allCentralAesItems.contains(aesItem.id()))
aesItem.id(aesItem.id() * -1);
}
void HandlerOcCentralAesData::removeAesItem(
qint32 aesItemId,
int64_t (AreaEffectSimulation::Interface::Ftc::*removeFunction)(const Core::RemoveElementRequest &, const std::function<void(const Core::FunctionReplyObject &)> &))
{
(*m_aesFtc.get().*removeFunction)(Core::RemoveElementRequest(aesItemId * -1),
[this](const Core::FunctionReplyObject &replyObject)
{
if (replyObject.error())
ERROR_LOG(m_logger) << replyObject.str();
});
}
} // namespace OcSituationClient
@@ -0,0 +1,104 @@
/**
* Handler for all oc situation data at the client
* $Id: handler_oc_situation_data.h 57655 2022-07-20 11:38:28Z karwat $
* $HeadURL: svn://192.168.133.21/TDS/branches/product/features/3dws_devel/Lts/Services/OcSituationClient/handler_oc_situation_data.h $
* $Author: karwat $
* Created by Philipp Dassow, NLST, 01-03-2018
*/
#pragma once
#include <QObject>
#include <QHash>
#include <QSet>
#include <OcSituationServer/oc_situation.h>
#include <AreaEffectSimulation/aes_ftc.h>
#include <AreaEffectSimulation/aes_dtc.h>
#include <TrainingAreaBaseOC/taboc_dts.h>
#include "logger.h"
namespace OcSituationClient
{
class HandlerOcCentralAesData
: public QObject
, protected AreaEffectSimulation::Interface::Ftc::NContaminationModifyReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::BCContaminationModifyReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::ExplosionAreaModifyReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::ExplosionSingleModifyReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::MineAreaModifyReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::FunctionalAreaModifyReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::BoobyTrapModifyReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::OffRouteMineModifyReplyHandler
, protected AreaEffectSimulation::Interface::Ftc::ExplosionClusterOcModifyReplyHandler
{
Q_OBJECT
public:
explicit HandlerOcCentralAesData(const std::shared_ptr<AreaEffectSimulation::Interface::Dtc> &aesDtc,
const std::shared_ptr<AreaEffectSimulation::Interface::Ftc> &aesFtc,
const std::shared_ptr<TrainingAreaBaseOC::Interface::Dts> &tabocDts,
QObject *parent);
~HandlerOcCentralAesData();
bool init();
void process(const QByteArray &data, bool bIsInitial);
void removeAllCentralAesItems();
bool withCompression() const { return m_bWithCompression; }
void setWithCompression(bool bOn) { m_bWithCompression = bOn; }
bool withVBGTime() const { return m_bWithVBGTime; }
void setWithVBGTime(bool bOn) { m_bWithVBGTime = bOn; }
private Q_SLOTS:
void onNContaminationChanged(const AreaEffectSimulation::NContamination &data, DataModification modType);
void onBCContaminationChanged(const AreaEffectSimulation::BCContamination &data, DataModification modType);
void onExplosionAreaChanged(const AreaEffectSimulation::ExplosionArea &data, DataModification modType);
void onExplosionSingleChanged(const AreaEffectSimulation::ExplosionSingle &data, DataModification modType);
void onMineAreaChanged(const AreaEffectSimulation::MineArea &data, DataModification modType);
void onFunctionalAreaChanged(const AreaEffectSimulation::FunctionalArea &data, DataModification modType);
void onBoobyTrapChanged(const AreaEffectSimulation::BoobyTrap &data, DataModification modType);
void onOffRouteMineChanged(const AreaEffectSimulation::OffRouteMine &data, DataModification modType);
void onExplosionClusterChanged(const AreaEffectSimulation::ExplosionCluster &data, DataModification modType);
private:
template <typename T>
void onAesItemChanged(const T &aesItem, DataModification modType, AreaEffectSimulation::AesType aesType);
template <typename T>
void checkId(T &aesItem) const;
void tryRemoveAesItem(qint32 aesItemId, AreaEffectSimulation::AesType aesType);
void removeAesItem(qint32 aesItemId,
int64_t (AreaEffectSimulation::Interface::Ftc::*removeFunction)(const Core::RemoveElementRequest &, const std::function<void (const Core::FunctionReplyObject &)> &));
void onOffRouteMineModifyReply(const Core::FunctionReplyObject &reply) override final;
void onBoobyTrapModifyReply(const Core::FunctionReplyObject &reply) override final;
void onFunctionalAreaModifyReply(const Core::FunctionReplyObject &reply) override final;
void onMineAreaModifyReply(const Core::FunctionReplyObject &reply) override final;
void onExplosionSingleModifyReply(const Core::FunctionReplyObject &reply) override final;
void onExplosionAreaModifyReply(const Core::FunctionReplyObject &reply) override final;
void onBCContaminationModifyReply(const Core::FunctionReplyObject &reply) override final;
void onNContaminationModifyReply(const Core::FunctionReplyObject &reply) override final;
void onExplosionClusterOcModifyReply(const Core::FunctionReplyObject &reply) override final;
void onReply(const Core::FunctionReplyObject &reply) const;
private:
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> m_aesDtc;
std::shared_ptr<AreaEffectSimulation::Interface::Ftc> m_aesFtc;
std::shared_ptr<TrainingAreaBaseOC::Interface::Dts> m_tabocDts;
// aes item id, paired to AesType
QHash<int32_t, AreaEffectSimulation::AesType> m_allCentralAesItems;
// options, must be in sync with oss
bool m_bWithCompression = true;
bool m_bWithVBGTime = true;
LOGGER_T &m_logger;
};
} // namespace OcSituationClient
+810
View File
@@ -0,0 +1,810 @@
/**
* 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 <LtsUtilsCore/dds_vector.h>
#include <LtsUtilsCore/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)
, m_logger(getLogger("HandlerOcData"))
{}
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 : qAsConst(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) << LOGFUNCTION;
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
+127
View File
@@ -0,0 +1,127 @@
/**
* Handler for all oc data at the client
* $Id$
* $HeadURL$
* $Author$
* Created by Philipp Dassow, NLST, 20-02-2018
*/
#pragma once
#include <QMap>
#include <QTimer>
#include <OcSituationServer/oc_situation.h>
#include "main_handler.h"
#include "logger.h"
namespace OcSituationClient
{
class HandlerOcAesData;
class HandlerOcSituationData;
class HandlerOcCentralAesData;
class HandlerOcData : public QObject
, protected Interface::Fts::SendDemandEvaluationSchemaRequestHandler
, protected Interface::Fts::SendEvaluationRequestHandler
, protected Interface::Fts::SendDemandSituationRequestHandler
, protected Interface::Fts::SendEquipmentErrorRegistrationRequestHandler
, protected Interface::Fts::SendEquipmentRegistrationRequestHandler
, protected OcSituationServer::Interface::Fts::SendEquipmentMessageOcRequestHandler
, protected Messaging::Interface::Ftc::CreateOperatorMessageReplyHandler
, protected Messaging::Interface::Ftc::ModifyOperatorMessageReplyHandler
, protected Evaluations::Interface::Ftc::EvlSchemaModifyReplyHandler
, protected TrainingAreaBase::Interface::Ftc::SendOcDataReplyHandler
{
Q_OBJECT
public:
explicit HandlerOcData(MainHandler *mainHandler,
QObject *parent = nullptr);
~HandlerOcData();
bool init();
protected:
void onEvlSchemaModifyReply(const Core::FunctionReplyObject &reply) override final;
void onCreateOperatorMessageReply(const Core::FunctionReplyObject &reply) override final;
void onModifyOperatorMessageReply(const Core::FunctionReplyObject &reply) override final;
void onSendOcDataReply(const Core::FunctionReplyObject &reply) override final;
private slots:
void onOcDataChanged(const TrainingAreaBase::OcData &data, DataModification modType);
void onTechnicalStateSfmChanged(const TrainingAreaBaseOC::TechnicalStateSfm &data, DataModification modType);
void onOwnPosition(const TrainingAreaBaseOC::OwnPosition &data, DataModification modType);
void onOperatorMessageChanged(const Messaging::OperatorMessage &data, DataModification modType);
void situationRequestCycleTimeout();
void onUserChanged(const OperatorManagement::User &data, DataModification modType);
private:
void onSendDemandEvaluationSchemaRequest(const rti::core::SampleIdentity &cookie,
const SendDemandEvaluationSchemaRequest &request) override final;
void onSendEvaluationRequest(const rti::core::SampleIdentity &cookie,
const SendEvaluationRequest &request) override final;
void onSendDemandSituationRequest(const rti::core::SampleIdentity &cookie,
const SendDemandSituationRequest &request) override final;
void onSendEquipmentMessageOcRequest(const rti::core::SampleIdentity &cookie,
const OcSituationServer::SendEquipmentMessageRequest &request) override final;
void onSendEquipmentErrorRegistrationRequest(const rti::core::SampleIdentity &cookie,
const SendEquipmentErrorRegistrationRequest &request) override final;
void onSendEquipmentRegistrationRequest(const rti::core::SampleIdentity &cookie,
const SendEquipmentRegistrationRequest &request) override final;
void demandEvaluationSchema(int schemaId);
void demandSituation(bool initial = false);
void demandAesItems(OcSituation::AesType aesType);
void sendNewMessages();
void handleMessage(const QByteArray &data);
void handleEvaluationSchema(const QByteArray &data);
void handleStateInformation(const QByteArray &data);
void setResetCnt(OcSituation::AesType aesType, int resetCnt);
int getParticipantIdByEquipmentNumber(int eqNumber);
std::shared_ptr<Interface::Fts> m_fts;
std::shared_ptr<Evaluations::Interface::Ftc> m_evlFtc;
std::shared_ptr<Messaging::Interface::Dtc> m_msgDtc;
std::shared_ptr<Messaging::Interface::Ftc> m_msgFtc;
std::shared_ptr<OperatorManagement::Interface::Dtc> m_opmDtc;
std::shared_ptr<OcSituationServer::Interface::Fts> m_ossFts;
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
std::shared_ptr<TrainingAreaBase::Interface::Dtc> m_tabDtc;
std::shared_ptr<TrainingAreaBase::Interface::Dts> m_tabDts;
std::shared_ptr<TrainingAreaBase::Interface::Ftc> m_tabFtc;
std::shared_ptr<TrainingAreaBaseOC::Interface::Dtc> m_tabocDtc;
std::shared_ptr<DatabaseInterface> m_dbHandler;
HandlerOcAesData *m_handlerOcAesData;
HandlerOcSituationData *m_handlerOcSituationData;
HandlerOcCentralAesData *m_handlerOcCentralAesData;
QTimer *m_situationRequestCycleTimer;
struct
{
unsigned int avticeEvaluationSchemaId;
unsigned int resetCounterDangerAreas;
unsigned int resetCounterIeds;
} m_stateInformation;
int m_centerEquipmentId;
int m_radius;
bool m_useFilter;
std::vector<int> m_partyList;
std::vector<int> m_typeClassList;
dds::core::optional<Core::GeoPosition2D> m_position;
OperatorManagement::User m_user;
bool m_licensed;
NGL::INGLLogger &m_logger;
};
} // namespace OcSituationClient
@@ -0,0 +1,610 @@
/**
* Handler for all oc situation data at the client
* $Id$
* $HeadURL$
* $Author$
* Created by Philipp Dassow, NLST, 01-03-2018
*/
#include "handler_oc_situation_data.h"
#include <LtsUtilsCore/qbytearray_byteaccess.h>
#include <LtsUtilsCore/dds_vector.h>
#include "main_handler.h"
#include "settings.h"
namespace OcSituationClient
{
HandlerOcSituationData::HandlerOcSituationData(const std::shared_ptr<DdsHandler> &dds,
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
const std::shared_ptr<ParticipantManagement::Interface::Ftc> &ppmFtc,
const std::shared_ptr<TrainingAreaBase::Interface::Dts> &tabDts,
const std::shared_ptr<TrainingAreaBaseOC::Interface::Dtc> &tabocDtc,
const std::shared_ptr<TrainingAreaBaseOC::Interface::Dts> &tabocDts,
QObject *parent)
: QObject(parent)
, m_dds(dds)
, m_ppmDtc(ppmDtc)
, m_ppmFtc(ppmFtc)
, m_tabDts(tabDts)
, m_tabocDtc(tabocDtc)
, m_tabocDts(tabocDts)
, m_logger(getLogger("HandlerOcSituationData"))
{}
HandlerOcSituationData::~HandlerOcSituationData()
{}
bool HandlerOcSituationData::init()
{
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::partyChanged,
this, &HandlerOcSituationData::onPartyChanged);
connect(m_ppmDtc.get(), &ParticipantManagement::Interface::Dtc::participantChanged,
this, &HandlerOcSituationData::onParticipantChanged);
// PPM DTC enable
if (!m_ppmDtc->enableParticipant() ||
!m_ppmDtc->enableParty() ||
!m_ppmDtc->enableType())
{
ERROR_LOG(m_logger) << "Enabling PPM Data-Topics failed.";
return false;
}
// PPM FTC enable
if (!m_ppmFtc->enableModifyParticipantData())
{
ERROR_LOG(m_logger) << "Enabling PPM Data-Topics failed.";
return false;
}
// TAB DTS enable
if (!m_tabDts->enableEquipmentPosition() ||
!m_tabDts->enableEquipmentState() ||
!m_tabDts->enableEquipmentOperationalState() ||
!m_tabDts->enableParticipantSanitation() ||
!m_tabDts->enableSpecialSensorData())
{
ERROR_LOG(m_logger) << "Enabling TAB DTS Data-Topics failed.";
return false;
}
// TAOBOC DTC enable
if (!m_tabocDtc->enableSpecificsEquipment())
{
ERROR_LOG(m_logger) << "Enabling TABOC Data-Topics failed.";
return false;
}
if (!m_tabocDts->enableParticipantsOverload())
{
ERROR_LOG(m_logger) << "Enabling TABOC fts-Topics failed.";
return false;
}
DEBUG_LOG(m_logger) << "Initialisation HandlerOcSituationData succesful.";
return true;
}
void HandlerOcSituationData::process(const QByteArray &data, bool bIsInitial)
{
if (bIsInitial)
{
DEBUG_LOG(m_logger) << "Processing initial situation data.";
int ownEquipmentNumber = m_tabocDtc->specificsEquipment(1).equipmentNumber();
int ownParticipantId = -1;
for (const int &participantId : qAsConst(m_participantId2EqId))
{
if (m_participantId2EqId.value(participantId) == ownEquipmentNumber)
{
ownParticipantId = participantId;
break;
} // if
} // for
removeAllPositions();
m_participantData.clear();
m_equipmentPositions.clear();
m_equipmentStates.clear();
m_equipmentOperationalStates.clear();
m_specialSensorData.clear();
m_participantId2EqId.clear();
if (ownParticipantId == -1)
ERROR_LOG(m_logger) << "Mapping of own participant id and equipment number is unknown.";
else
m_participantId2EqId.insert(ownParticipantId, ownEquipmentNumber);
} // if
if (!decodeSituationData(data))
return;
if (!m_participantData.isEmpty())
sendParticipantData(++m_requestId);
sendTrainingAreaBaseData();
}
void HandlerOcSituationData::removeAllPositions()
{
TrainingAreaBase::EquipmentPosition invalidPos;
invalidPos.position().position().lon(nan(""));
invalidPos.position().position().lat(nan(""));
invalidPos.position().reportingSource(Core::PositionReportingSource::SetByOperator); // SetByOperator -> nan is allowed
invalidPos.sampleTime(m_dds->currentPartitionTime());
for (const auto eqNumber : qAsConst(m_participantId2EqId))
{
invalidPos.equipmentNumber(eqNumber);
m_tabDts->publish(invalidPos);
}
}
void HandlerOcSituationData::setInvalidPositionForParticipant(int participantId)
{
TrainingAreaBase::EquipmentPosition invalidPos;
invalidPos.position().position().lon(nan(""));
invalidPos.position().position().lat(nan(""));
invalidPos.position().reportingSource(Core::PositionReportingSource::SetByOperator); // SetByOperator -> nan is allowed
invalidPos.sampleTime(m_dds->currentPartitionTime());
invalidPos.equipmentNumber(-participantId); // negative -> treat equipNo as participantId
m_tabDts->publish(invalidPos);
}
void HandlerOcSituationData::onModifyParticipantDataReply(const Core::FunctionReplyObject &reply)
{
if (!m_modifiyRequests.contains(reply.id()))
{
ERROR_LOG(m_logger) << "Got a ModifyParticipantDataReply without matching ID!";
return;
}
if (reply.error())
ERROR_LOG(m_logger) << "ModifyParticipantDataRequest " << reply.id() << " could not be handled: " << reply.str();
else
{
DEBUG_LOG(m_logger) << "ModifyParticipantDataRequest " << reply.id() << " handled successfully by PPM!";
delete (m_modifiyRequests.value(reply.id()));
m_modifiyRequests.remove(reply.id());
sendTrainingAreaBaseData(); // send TAB data for new participants
}
}
bool HandlerOcSituationData::decodeSituationData(const QByteArray &data)
{
if (data.isEmpty())
{
ERROR_LOG(m_logger) << "Got an empty QByteArray to decode.";
return false;
}
bool participantOverloaded = false;
LtsUtils::get1Byte(data, participantOverloaded);
//send overload topic
TrainingAreaBaseOC::ParticipantsOverload participantsOverload;
participantsOverload.id(1);
participantsOverload.hasOverload(participantOverloaded);
m_tabocDts->publish(participantsOverload);
DEBUG_LOG(m_logger) << "publish overload: " << participantOverloaded;
QByteArray data2 = data;
data2.remove(0, 1);
// shouldn't be needed in 99,9% of all cases but just to be sure
m_ppmDtc->waitForHistoricalDataParticipant(5000);
m_ppmDtc->waitForHistoricalDataParty(5000);
m_ppmDtc->waitForHistoricalDataType(5000);
QByteArray uncompressed = MainHandler::tryUncompress(data2, m_bWithCompression);
if (uncompressed.isEmpty())
{
INFO_LOG(m_logger) << "Got an empty QByteArray after uncompression.";
return false;
}
TRACE_LOG(m_logger) << "Uncompressed Data: " << uncompressed.toHex(' ');
DEBUG_LOG(m_logger) << " m_equipmentPositions size before decode: " << m_equipmentPositions.size()
<< " m_equipmentStates size before decode: " << m_equipmentStates.size()
<< " m_equipmentOperationalStates size before decode: " << m_equipmentOperationalStates.size()
<< " m_specialSensorData size before decode: " << m_specialSensorData.size();
size_t pos = 0;
int participantId = 0;
OcSituation::ModificationBits modifiedFlag;
int modId = 1000000;
while (getParticipantId(uncompressed, pos, participantId, modifiedFlag) && participantId != 0)
{
INFO_LOG(m_logger) << "Participant: " << participantId << " is modified: " << modifiedFlag;
// outdated handling
if (modifiedFlag == OcSituation::ModificationFlag::eNone)
{
// directly remove and go on with next participant
setInvalidPositionForParticipant(participantId);
continue;
}
// position
bool bRet = false;
TrainingAreaBase::EquipmentPosition position;
position.position().reportingSource(Core::PositionReportingSource::Gps); // we don't know better
bRet |= getPosition2D(uncompressed, pos, position, (modifiedFlag & OcSituation::ModificationFlag::ePosition2D) == OcSituation::ModificationFlag::ePosition2D);
bRet |= getPosition3D(uncompressed, pos, position, (modifiedFlag & OcSituation::ModificationFlag::ePosition3D) == OcSituation::ModificationFlag::ePosition3D);
if (bRet)
m_equipmentPositions.insert(participantId, position);
// state
TrainingAreaBase::EquipmentState state;
TrainingAreaBase::ParticipantSanitation sanitaion;
bRet = getVBG(uncompressed, pos, state, sanitaion, (modifiedFlag & OcSituation::ModificationFlag::eVBG) == OcSituation::ModificationFlag::eVBG);
if (bRet)
{
DEBUG_LOG(m_logger) << "Adding EquipmentState to internal map: " << state;
m_equipmentStates.insert(participantId, state);
DEBUG_LOG(m_logger) << "Adding ParticipantSanitation to internal map: " << sanitaion;
m_participantSanitations.insert(participantId, sanitaion);
}
// sensorData and operationalState
TrainingAreaBase::SpecialSensorData sensorData;
TrainingAreaBase::EquipmentOperationalState opState;
bRet = getState(uncompressed, pos, sensorData, opState, (modifiedFlag & OcSituation::ModificationFlag::eState) == OcSituation::ModificationFlag::eState);
if (bRet)
{
DEBUG_LOG(m_logger) << "Adding SpecialSensorData to internal map: " << sensorData;
DEBUG_LOG(m_logger) << "Adding EquipmentOperationalState to internal map: " << opState;
m_specialSensorData.insert(participantId, sensorData);
m_equipmentOperationalStates.insert(participantId, opState);
}
// participantData
bRet = false;
ParticipantManagement::ParticipantData participantData = m_ppmDtc->convertParticipantToParticipantData(m_participants.value(participantId));
bRet |= getStructure(uncompressed, pos, participantData, (modifiedFlag & OcSituation::ModificationFlag::eStructure) == OcSituation::ModificationFlag::eStructure);
bRet |= getDesignator(uncompressed, pos, participantData, (modifiedFlag & OcSituation::ModificationFlag::eDesignator) == OcSituation::ModificationFlag::eDesignator);
bRet |= getSymbolSidc(uncompressed, pos, participantData, (modifiedFlag & OcSituation::ModificationFlag::eSymbol) == OcSituation::ModificationFlag::eSymbol);
//sanity
bool bInsane = false;
if (bRet && (participantData.partyId() <= 0 || participantData.id() <= 0 || participantData.typeId() <= 0))
bInsane = true;
if (bRet && !bInsane)
{
int unitId = Settings::unitOffset() + participantData.partyId();
if (participantData.id() == 0) // if new participant
{
participantData.id(participantId);
participantData.modId(modId++);
participantData.hierarchyNumber(participantId); // it just needs to be unqiue here
}
//always set superiorModId! changeing party Id only won't work
participantData.superiorModId(unitId);
participantData.assignState(ParticipantManagement::ParticipantAssignState::HandoutExcon); // set always as we can deduce it anyway //TODO cant reasign EQ nr
if (!m_participantData.contains(unitId)) // Adding Unit to participantData, if not already added
{
m_participantData.insert(unitId, m_ppmDtc->convertParticipantToParticipantData(m_participants.value(unitId)));
DEBUG_LOG(m_logger) << "Adding unit to m_participantData: " << m_participantData.value(unitId);
}
m_participantData.insert(participantId, participantData);
DEBUG_LOG(m_logger) << "Adding ParticipantData to internal map: " << participantData;
if (participantData.equipmentNumber().is_set())
m_participantId2EqId[participantId] = participantData.equipmentNumber().get();
else
m_participantId2EqId[participantId] = 0; // so the positions can be removed, see e.g. removeAllPositions()
}
// no position update for ourself. Easier to filter here than in server but a bit overhead in TETRA
if (m_tabocDtc->specificsEquipment(1).equipmentNumber() == m_participantId2EqId.value(participantId))
m_equipmentPositions.remove(participantId);
}
DEBUG_LOG(m_logger) << " m_equipmentPositions size after decode: " << m_equipmentPositions.size()
<< " m_equipmentStates size after decode: " << m_equipmentStates.size()
<< " m_equipmentOperationalStates size after decode: " << m_equipmentOperationalStates.size()
<< " m_specialSensorData size after decode: " << m_specialSensorData.size();
return true;
}
void HandlerOcSituationData::sendParticipantData(int requestId)
{
if (m_modifiyRequests.contains(requestId))
{
WARNING_LOG(m_logger) << "Resending modfiyParticipantDataRequest: " << requestId;
m_ppmFtc->modifyParticipantDataRequest(*m_modifiyRequests.value(requestId), this);
return;
}
ParticipantManagement::ModifyParticipantDataRequest *newRequest = new ParticipantManagement::ModifyParticipantDataRequest();
newRequest->requestId(requestId);
newRequest->data(LtsUtils::convert<std::vector<ParticipantManagement::ParticipantData>>(m_participantData));
newRequest->forceAddWithId(true);
m_modifiyRequests.insert(requestId, newRequest);
m_participantData.clear();
INFO_LOG(m_logger) << "Sending modfiyParticipantDataRequest: " << requestId;
m_ppmFtc->modifyParticipantDataRequest(*newRequest, this);
}
template <typename T>
void HandlerOcSituationData::publishMap(QMap<int, T> &map)
{
for (auto it = map.begin(); it != map.end();)
{
if (m_participants.value(it.key()).id() > 0) // publishing only for existing participants
{
auto topic = it.value();
topic.equipmentNumber(m_participantId2EqId.value(it.key()));
m_tabDts->publish(topic);
it = map.erase(it);
}
else
++it;
}
}
void HandlerOcSituationData::sendTrainingAreaBaseData()
{
publishMap<TrainingAreaBase::EquipmentPosition>(m_equipmentPositions);
publishMap<TrainingAreaBase::EquipmentState>(m_equipmentStates);
publishMap<TrainingAreaBase::EquipmentOperationalState>(m_equipmentOperationalStates);
publishMap<TrainingAreaBase::SpecialSensorData>(m_specialSensorData);
publishMap<TrainingAreaBase::ParticipantSanitation>(m_participantSanitations);
}
bool HandlerOcSituationData::getParticipantId(const QByteArray &buf, size_t &pos, int &participantId, OcSituation::ModificationBits &modifiedFlags) const
{
bool bRet = true;
bRet &= LtsUtils::get2Byte(buf, pos, participantId);
bRet &= LtsUtils::get1Byte(buf, pos, modifiedFlags);
return bRet;
}
bool HandlerOcSituationData::getPosition2D(const QByteArray &buf, size_t &pos, TrainingAreaBase::EquipmentPosition &position, bool bAvailable) const
{
if (!bAvailable)
return false;
bool bRet = true;
// lon, lat, sampleTime
double tmp;
bRet &= LtsUtils::get8Byte(buf, pos, tmp);
position.position().position().lon(tmp);
bRet &= LtsUtils::get8Byte(buf, pos, tmp);
position.position().position().lat(tmp);
position.sampleTime(m_dds->currentPartitionTime());
return bRet;
}
bool HandlerOcSituationData::getPosition3D(const QByteArray &buf, size_t &pos, TrainingAreaBase::EquipmentPosition &position, bool bAvailable) const
{
if (!bAvailable)
return false;
bool bRet = true;
// lon, lat, sampleTime
bRet &= getPosition2D(buf, pos, position, bAvailable);
// z
double tmp;
int roomId = -1;
int buildingId = -1;
bRet &= LtsUtils::get8Byte(buf, pos, tmp);
position.position().position().z(tmp);
bRet &= LtsUtils::get2Byte(buf, pos, buildingId);
bRet &= LtsUtils::get4Byte(buf, pos, roomId);
if (buildingId > 0 && roomId > 0)
{
position.position().moutRoomId().set(roomId);
position.position().moutObjectId().set(buildingId);
position.position().reportingSource() = (tmp >= 0.0) ? Core::PositionReportingSource::Ops : Core::PositionReportingSource::OpsTunnel;
}
return bRet;
}
bool HandlerOcSituationData::getVBG(const QByteArray &buf, size_t &pos, TrainingAreaBase::EquipmentState &equipmentState, TrainingAreaBase::ParticipantSanitation &sanitation, bool bAvailable) const
{
if (!bAvailable)
return false;
bool bRet = true;
// vulnerabilityState, vulnerabilityBits, originatorParty, sampleTime
uint64_t tmp;
bRet &= LtsUtils::get1Byte(buf, pos, tmp);
equipmentState.vulnerabilityState(ProjectDataManagement::VulnerabilityState::inner_enum(tmp));
bRet &= LtsUtils::get4Byte(buf, pos, tmp);
equipmentState.vulnerabilityKindId(tmp);
bRet &= LtsUtils::get2Byte(buf, pos, tmp);
equipmentState.vulnerabilityBits(tmp);
bRet &= LtsUtils::get1Byte(buf, pos, tmp);
if (!m_knownParties.contains(tmp))
{
WARNING_LOG(m_logger) << "Party: " << tmp << " unknown, setting equipmentState.originatorId() to "
<< Settings::unitOffset() + 1;
//Sollte nicht passieren, doch falls ja gibt es goldene Kreuze beim Ausfall
tmp = 1;
}
equipmentState.originatorId(Settings::unitOffset() + tmp);
if (m_bWithVBGTime)
{
bRet &= LtsUtils::get4Byte(buf, pos, tmp);
equipmentState.sampleTime(tmp * 1000UL);
}
else
equipmentState.sampleTime(QDateTime::currentMSecsSinceEpoch());
quint8 vitRest;
bRet &= LtsUtils::get1Byte(buf, pos, vitRest);
if (bRet)
{
int vit = (vitRest & 0x0F) * 10;
equipmentState.vitality(vit);
TrainingAreaBase::SanitationResult result = static_cast<TrainingAreaBase::SanitationResult_def::type>(vitRest >> 4);
sanitation.sanitationResult(result);
sanitation.proceduresTaken(1);
sanitation.qualification(TrainingAreaBase::Qualification::SANPers);
}
qint8 originator = 0;
bRet &= LtsUtils::get1Byte(buf, pos, originator);
if (bRet)
equipmentState.originatorType(ProjectDataManagement::StateChangeOriginator::inner_enum(originator));
return bRet;
}
bool HandlerOcSituationData::getState(const QByteArray &buf, size_t &pos, TrainingAreaBase::SpecialSensorData &specialSensorData, TrainingAreaBase::EquipmentOperationalState &equipmentOperationalState, bool bAvailable) const
{
if (!bAvailable)
return false;
bool bRet = true;
// operationBits
int tmp;
bRet &= LtsUtils::get1Byte(buf, pos, tmp);
specialSensorData.sampleTime(m_dds->currentPartitionTime());
equipmentOperationalState.nbcProtectionActive((tmp & 0x02) || (tmp & 0x04));
equipmentOperationalState.isManipulation(tmp & 0x02);
equipmentOperationalState.sampleTime(m_dds->currentPartitionTime());
return bRet;
}
bool HandlerOcSituationData::getStructure(const QByteArray &buf, size_t &pos, ParticipantManagement::ParticipantData &participant, bool bAvailable) const
{
if (!bAvailable)
return false;
bool bRet = true;
// equipmentNumber, typeId, partyId
int tmp;
bRet &= LtsUtils::get2Byte(buf, pos, tmp);
participant.equipmentNumber(dds::core::optional<int32_t>(tmp));
bRet &= LtsUtils::get2Byte(buf, pos, tmp);
participant.typeId(tmp);
bRet &= LtsUtils::get2Byte(buf, pos, tmp);
if (m_knownParties.contains(tmp))
participant.partyId(tmp);
else
{
WARNING_LOG(m_logger) << "Not setting new party: " << tmp << " for participant: " << participant.id() << " as the party is unknown -> do a base download.";
bRet = false;
}
#ifndef GUEZ_MODE
bRet &= LtsUtils::get2Byte(buf, pos, tmp);
if (m_participants.contains(tmp))
participant.superiorModId(tmp);
else
WARNING_LOG(m_logger) << "Not setting new superioir ID: " << tmp << " for participant: " << participant.id() << " as the superior is unknown -> do a base download.";
#endif
return bRet;
}
bool HandlerOcSituationData::getDesignator(const QByteArray &buf, size_t &pos, ParticipantManagement::ParticipantData &participant, bool bAvailable) const
{
if (!bAvailable)
return false;
bool bRet = true;
// designator, tacticalIdentifier
int tmp;
bRet &= LtsUtils::get1Byte(buf, pos, tmp);
size_t len1 = tmp & 0x0F;
size_t len2 = (tmp & 0xF0) >> 4;
//hier wurde direkt auf dem Buffer zugegriffen ohne vorher zu prüfen ob es überhaupt passt
if ((size_t)buf.size() < pos + len1)
bRet = false;
if (bRet)
participant.designator(buf.mid(pos, len1).toStdString());
pos += len1;
if ((size_t)buf.size() < pos + len2)
bRet = false;
if (bRet)
participant.tacticalIdentifier(buf.mid(pos, len2).toStdString());
pos += len2;
return bRet;
}
bool HandlerOcSituationData::getSymbolSidc(const QByteArray &buf, size_t &pos, ParticipantManagement::ParticipantData &participant, bool bAvailable) const
{
if (!bAvailable)
return false;
bool bRet = true;
size_t len;
bRet &= LtsUtils::get1Byte(buf, pos, len);
if (len == 0)
{
// get symbol from type id
const auto type = m_ppmDtc->type(participant.typeId());
participant.symbol(type.symbol());
return bRet;
}
if ((size_t)buf.size() < pos + len)
bRet = false;
if (bRet)
participant.symbol(buf.mid(pos, len).toStdString());
pos += len;
return bRet;
}
void HandlerOcSituationData::onPartyChanged(const ParticipantManagement::Party &party, DataModification mod)
{
switch (mod)
{
case DataModification::eAdded:
case DataModification::eModified:
m_knownParties.insert(party.id());
break;
case DataModification::eRemoved:
m_knownParties.remove(party.id());
break;
}
}
void HandlerOcSituationData::onParticipantChanged(const ParticipantManagement::Participant &participant, DataModification mod)
{
switch (mod)
{
case DataModification::eAdded:
case DataModification::eModified:
m_participants[participant.id()] = participant;
// if there is a participant but it has (currently) no equipno, remove it from sitmap by setting invalid position
if (!m_participantId2EqId.contains(participant.id()))
setInvalidPositionForParticipant(participant.id());
break;
case DataModification::eRemoved:
m_participants.remove(participant.id());
break;
}
}
} // namespace OcSituationClient
+131
View File
@@ -0,0 +1,131 @@
/**
* Handler for all oc situation data at the client
* $Id$
* $HeadURL$
* $Author$
* Created by Philipp Dassow, NLST, 01-03-2018
*/
#pragma once
#include <QHash>
#include <ParticipantManagement/ppm_dtc.h>
#include <ParticipantManagement/ppm_ftc.h>
#include <OcSituationServer/oc_situation.h>
#include <TrainingAreaBase/tab_dts.h>
#include <TrainingAreaBaseOC/taboc_dtc.h>
#include <TrainingAreaBaseOC/taboc_dts.h>
#include "dds_handler.h"
#include "logger.h"
namespace OcSituationClient
{
class HandlerOcSituationData : public QObject
, protected ParticipantManagement::Interface::Ftc::ModifyParticipantDataReplyHandler
{
Q_OBJECT
public:
explicit HandlerOcSituationData(const std::shared_ptr<DdsHandler> &dds,
const std::shared_ptr<ParticipantManagement::Interface::Dtc> &ppmDtc,
const std::shared_ptr<ParticipantManagement::Interface::Ftc> &ppmFtc,
const std::shared_ptr<TrainingAreaBase::Interface::Dts> &tabDts,
const std::shared_ptr<TrainingAreaBaseOC::Interface::Dtc> &tabocDtc,
const std::shared_ptr<TrainingAreaBaseOC::Interface::Dts> &tabocDts,
QObject *parent);
~HandlerOcSituationData();
bool init();
void process(const QByteArray &data, bool bIsInitial);
void removeAllPositions();
void setInvalidPositionForParticipant(int participantId);
void onModifyParticipantDataReply(const Core::FunctionReplyObject &reply);
bool withCompression() const { return m_bWithCompression; }
void setWithCompression(bool bOn) { m_bWithCompression = bOn; }
bool withVBGTime() const { return m_bWithVBGTime; }
void setWithVBGTime(bool bOn) { m_bWithVBGTime = bOn; }
private:
bool decodeSituationData(const QByteArray &data);
void sendParticipantData(int requestId);
template <typename T>
void publishMap(QMap<int, T> &map);
void sendTrainingAreaBaseData();
bool getParticipantId(const QByteArray &buf,
size_t &pos,
int &participantId,
OcSituation::ModificationBits &modifiedFlags) const;
bool getPosition2D(const QByteArray &buf,
size_t &pos,
TrainingAreaBase::EquipmentPosition &position,
bool bAvailable) const;
bool getPosition3D(const QByteArray &buf,
size_t &pos,
TrainingAreaBase::EquipmentPosition &position,
bool bAvailable) const;
bool getVBG(const QByteArray &buf,
size_t &pos,
TrainingAreaBase::EquipmentState &equipmentState,
TrainingAreaBase::ParticipantSanitation &sanitation,
bool bAvailable) const;
bool getState(const QByteArray &buf,
size_t &pos,
TrainingAreaBase::SpecialSensorData &specialSensorData,
TrainingAreaBase::EquipmentOperationalState &equipmentOperationalState,
bool bAvailable) const;
bool getStructure(const QByteArray &buf,
size_t &pos,
ParticipantManagement::ParticipantData &participant,
bool bAvailable) const;
bool getDesignator(const QByteArray &buf,
size_t &pos,
ParticipantManagement::ParticipantData &participant,
bool bAvailable) const;
bool getSymbolSidc(const QByteArray &buf,
size_t &pos,
ParticipantManagement::ParticipantData &participant,
bool bAvailable) const;
void onPartyChanged(const ParticipantManagement::Party &party, DataModification mod);
void onParticipantChanged(const ParticipantManagement::Participant &participant, DataModification mod);
private:
// for partition time
std::shared_ptr<DdsHandler> m_dds;
// data publishing
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
std::shared_ptr<ParticipantManagement::Interface::Ftc> m_ppmFtc;
std::shared_ptr<TrainingAreaBase::Interface::Dts> m_tabDts;
std::shared_ptr<TrainingAreaBaseOC::Interface::Dtc> m_tabocDtc;
std::shared_ptr<TrainingAreaBaseOC::Interface::Dts> m_tabocDts;
// internal participant data
// all paired to thier participantId
QMap<int, ParticipantManagement::ParticipantData> m_participantData;
QMap<int, TrainingAreaBase::EquipmentPosition> m_equipmentPositions;
QMap<int, TrainingAreaBase::EquipmentState> m_equipmentStates;
QMap<int, TrainingAreaBase::ParticipantSanitation> m_participantSanitations;
QMap<int, TrainingAreaBase::EquipmentOperationalState> m_equipmentOperationalStates;
QMap<int, TrainingAreaBase::SpecialSensorData> m_specialSensorData;
// internal management data
QHash<int, int> m_participantId2EqId;
QHash<int, ParticipantManagement::ModifyParticipantDataRequest *> m_modifiyRequests;
QSet<int> m_knownParties;
QHash<int, ParticipantManagement::Participant> m_participants;
int m_requestId = 1;
// options, must be in sync with oss
bool m_bWithCompression = true;
bool m_bWithVBGTime = true;
LOGGER_T &m_logger;
};
} // namespace OcSituationClient
+85
View File
@@ -0,0 +1,85 @@
log4j.reset=true
log4j.rootLogger=WARN, file
# Service: OcSituationClient
###########################################################
#log4j.logger.OSC=DEBUG
#log4j.logger.OSC.main=DEBUG
#log4j.logger.OSC.DdsHandler=DEBUG
#log4j.logger.OSC.MainHandler=DEBUG
#log4j.logger.OSC.HandlerOcAesData=DEBUG
#log4j.logger.OSC.HandlerOcData=INFO
#log4j.logger.OSC.HandlerOcSituation=INFO
#log4j.logger.OSC.HandlerOcCentralAesData=DEBUG
#log4j.logger.OSC.CentralAesByteReader=DEBUG
#
# Lts::RollingFileAppender
log4j.appender.file=Lts::RollingFileAppender
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=9
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d %-5p %c |#| %m (%.50F:%L) %n
# Appnd_Console
###########################################################
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern= %d %p %c %c{1} - %m (%-.30F:%L) %n
# Appnd_Syslog
###########################################################
log4j.appender.syslog=org.apache.log4j.SyslogAppender
log4j.appender.syslog.Threshold=ERROR
log4j.appender.syslog.SysLogHost=localhost
log4j.appender.syslog.Facility=LOCAL7
log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
log4j.appender.syslog.layout.ConversionPattern= %-4r %-5p %c %x - %m
log4j.appender.syslog.LevelRangeFilter.AcceptOnMatch=true
log4j.appender.syslog.LevelRangeFilter.LevelMin=INFO
log4j.appender.syslog.LevelRangeFilter.LevelMax=FATAL
###########################################################
###########################################################
###########################################################
# 1) Available Levels in LOG4CXX Version 0.10.0:
# TRACE,
# DEBUG,
# INFO,
# WARN,
# ERROR
# FATAL
#
# d = date/time
# p = priority (Level)
# c = category/channel
# m = message
# F = file
# L = line
# n = platform dependent line separator character or characters.
# ....
#
# Examples for console:
# a)
# %d %p %c #%m# (%.50F:%L)%n
# date/time
# priority
# category/channel
# #message#
# (Maximal 50Character des Filename von rechts:Line)
# line separator
#
# b)
# %d (%.15F:%L) %-5p %c |#| %m%n
# date/time
# (Maximal 15Character des Filename von rechts:Line)
# priority, Right pad with spaces if the priority name is less than 5 characters long.
# category/channel
# message
# line separator
#
# Examples for files:
+37
View File
@@ -0,0 +1,37 @@
/**
* @RDE_HEADER@
* Building Config - logging facility
* $Id$
* $HeadURL$
* $Author$
*/
#include "logger.h"
#include <NGLLogger/NGLLoggerBootstrap.h>
namespace OcSituationClient
{
LOGGER_T getLogger(const char *name)
{
static const char ns[] = "OSC.";
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 OcSituationClient
+23
View File
@@ -0,0 +1,23 @@
/**
* @RDE_HEADER@
* Logging for OcSituationClient
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <NGLLogger/INGLLogger.h>
#include "osc_export.h"
namespace OcSituationClient
{
using LOGGER_T = NGL::INGLLogger &;
OSC_COMMON_EXPORT LOGGER_T getLogger(const char *name);
inline LOGGER_T getLogger(const QString &loggerName)
{
return getLogger(loggerName.toUtf8().constData());
}
} // namespace OcSituationClient
+42
View File
@@ -0,0 +1,42 @@
/**
* @RDE_HEADER@
* main for OcSituationClient
* $Id$
* $HeadURL$
* $Author$
*/
#include <nglapplication/nglcoreapplication.h>
#include <LtsCommandLineParser/LtsCommandLineParser.h>
#include "main_handler.h"
#include "logger.h"
#include "settings.h"
int main(int argc, char **argv)
{
NGLCoreApplication app(argc, argv);
LtsCommandLineParser::LtsCommandLineParser options;
if (!options.init())
return -1;
app.createLogger("OSC", options.exerciseId());
OcSituationClient::Settings::setIniFile(options.iniFile());
int iRet = -3;
{
std::unique_ptr<OcSituationClient::MainHandler> mainHandler(new OcSituationClient::MainHandler);
if (!mainHandler->init(options.domainId(), options.exerciseId()))
return iRet;
STARTUP_LOG(app.baseLogger());
iRet = app.exec();
SHUTDOWN_LOG(app.baseLogger());
}
return iRet;
}
+161
View File
@@ -0,0 +1,161 @@
/**
* MainHandler for OCSituationClient
* $Id$
* $HeadURL$
* $Author$
* Created by Philipp Dassow, NLST, 14-02-2018
*/
#include "main_handler.h"
#include <DDS/Core/pacemaker.h>
#include "handler_oc_data.h"
#include "settings.h"
namespace OcSituationClient
{
MainHandler::MainHandler(QObject *parent)
: QObject(parent)
, m_ddsHandler(nullptr)
, m_handlerOcData(nullptr)
, m_dbHandler(nullptr)
, m_aesDtc(nullptr)
, m_aesFtc(nullptr)
, m_evlFtc(nullptr)
, m_gimDtc(nullptr)
, m_msgDtc(nullptr)
, m_msgFtc(nullptr)
, m_opmDtc(nullptr)
, m_ossDts(nullptr)
, m_ossFts(nullptr)
, m_ppmDtc(nullptr)
, m_ppmFtc(nullptr)
, m_tabDtc(nullptr)
, m_tabFtc(nullptr)
, m_tabocDtc(nullptr)
, m_tabocDts(nullptr)
, m_logger(getLogger("MainHandler"))
{}
MainHandler::~MainHandler()
{
m_ddsHandler = nullptr;
m_handlerOcData = nullptr;
m_dbHandler = nullptr;
m_aesDtc = nullptr;
m_aesFtc = nullptr;
m_evlFtc = nullptr;
m_gimDtc = nullptr;
m_msgDtc = nullptr;
m_msgFtc = nullptr;
m_ossDts = nullptr;
m_ossFts = nullptr;
m_ppmDtc = nullptr;
m_ppmFtc = nullptr;
m_tabDtc = nullptr;
m_tabFtc = nullptr;
m_tabocDtc = nullptr;
m_tabocDts = nullptr;
}
bool MainHandler::init(int domainId, int exerciseId)
{
// initialize database
m_dbHandler = std::make_shared<DbHandler>();
if (!m_dbHandler->init(exerciseId, Settings::settings()))
{
ERROR_LOG(m_logger) << "Initialisation dbHandler failed.";
return false;
}
DEBUG_LOG(m_logger) << "Initialisation dbHandler succesful.";
// initialize DDS
m_ddsHandler = std::make_shared<DdsHandler>(domainId, exerciseId);
if (!m_ddsHandler->init())
{
ERROR_LOG(m_logger) << "Initialisation ddsHandler failed.";
return false;
}
DEBUG_LOG(m_logger) << "Initialisation ddsHandler succesful.";
// create AES Dtc
m_aesDtc = AreaEffectSimulation::Interface::Dtc::create(m_ddsHandler->dds());
DEBUG_LOG(m_logger) << "Created AES Dtc";
// create AES Ftc
m_aesFtc = AreaEffectSimulation::Interface::Ftc::create(m_ddsHandler->dds());
DEBUG_LOG(m_logger) << "Created AES Ftc";
// create EVL Ftc
m_evlFtc = Evaluations::Interface::Ftc::create(m_ddsHandler->dds());
DEBUG_LOG(m_logger) << "Created EVL Ftc";
// create GIM Dtc
m_gimDtc = GuezIedManagement::Interface::Dtc::create(m_ddsHandler->dds());
DEBUG_LOG(m_logger) << "Created GIM Dtc";
// create MSG Dtc
m_msgDtc = Messaging::Interface::Dtc::create(m_ddsHandler->dds());
DEBUG_LOG(m_logger) << "Created MSG Dtc";
// create MSG Ftc
m_msgFtc = Messaging::Interface::Ftc::create(m_ddsHandler->dds());
DEBUG_LOG(m_logger) << "Created MSG Ftc";
// create OPM Dtc
m_opmDtc = OperatorManagement::Interface::Dtc::create(m_ddsHandler->dds());
DEBUG_LOG(m_logger) << "Created OPM Dtc";
// create OSS Dts
m_ossDts = OcSituationServer::Interface::Dts::create(m_ddsHandler->dds());
DEBUG_LOG(m_logger) << "Created OSS Dts";
// create OSS Fts
m_ossFts = OcSituationServer::Interface::Fts::create(m_ddsHandler->dds());
DEBUG_LOG(m_logger) << "Created OSS Fts";
// create PPM Dtc
m_ppmDtc = ParticipantManagement::Interface::Dtc::create(m_ddsHandler->dds());
DEBUG_LOG(m_logger) << "Created PPM Dtc";
// create PPM Ftc
m_ppmFtc = ParticipantManagement::Interface::Ftc::create(m_ddsHandler->dds());
DEBUG_LOG(m_logger) << "Created PPM Ftc";
// create TAB Dtc
m_tabDtc = TrainingAreaBase::Interface::Dtc::create(m_ddsHandler->dds());
DEBUG_LOG(m_logger) << "Created TAB Dtc";
// create TAB Dts
m_tabDts = TrainingAreaBase::Interface::Dts::create(m_ddsHandler->dds());
DEBUG_LOG(m_logger) << "Created TAB Dts";
// create TAB Ftc
m_tabFtc = TrainingAreaBase::Interface::Ftc::create(m_ddsHandler->dds());
DEBUG_LOG(m_logger) << "Created TAB Ftc";
// create TABOC Dtc
m_tabocDtc = TrainingAreaBaseOC::Interface::Dtc::create(m_ddsHandler->dds());
DEBUG_LOG(m_logger) << "Created TABOC Dtc";
// create TABOC Dts
m_tabocDts = TrainingAreaBaseOC::Interface::Dts::create(m_ddsHandler->dds());
DEBUG_LOG(m_logger) << "Created TABOC Dts";
// create handler oc-data
m_handlerOcData = std::make_shared<HandlerOcData>(this, this);
if (!m_handlerOcData->init())
{
ERROR_LOG(m_logger) << "Initialisation HandlerOcData failed.";
return false;
}
m_ddsHandler->pacemaker()->setNewState(Core::RunningState::Running);
return true;
}
} // namespace OcSituationClient
+110
View File
@@ -0,0 +1,110 @@
/**
* MainHandler for OCSituationClient
* $Id$
* $HeadURL$
* $Author$
* Created by Philipp Dassow, NLST, 14-02-2018
*/
#pragma once
#include <QObject>
#include <memory>
#include <AreaEffectSimulation/aes_dtc.h>
#include <AreaEffectSimulation/aes_ftc.h>
#include <Evaluations/evl_ftc.h>
#include <GuezIedManagement/gim_dtc.h>
#include <Messaging/msg_dtc.h>
#include <Messaging/msg_ftc.h>
#include <OcSituationServer/oss_dts.h>
#include <OcSituationServer/oss_fts.h>
#include <OperatorManagement/opm_dtc.h>
#include <ParticipantManagement/ppm_dtc.h>
#include <ParticipantManagement/ppm_ftc.h>
#include <TrainingAreaBase/tab_dtc.h>
#include <TrainingAreaBase/tab_dts.h>
#include <TrainingAreaBase/tab_ftc.h>
#include <TrainingAreaBaseOC/taboc_dtc.h>
#include <TrainingAreaBaseOC/taboc_dts.h>
#include "dds_handler.h"
#include <ngldb/db_service_handler.h>
#include "osc_db.h"
#include "logger.h"
namespace NGLDB
{
template <typename DB> class DbServiceHandler;
}
namespace OcSituationClient
{
using DbHandler = NGLDB::DbServiceHandler<DatabaseInterface>;
class HandlerOcData;
class MainHandler : public QObject
{
Q_OBJECT
public:
explicit MainHandler(QObject *parent = nullptr);
~MainHandler();
bool init(int domainId, int exerciseId);
std::shared_ptr<DdsHandler> dds() const { return m_ddsHandler; }
std::shared_ptr<DatabaseInterface> db() const { return m_dbHandler->db(); }
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> aesDtc() const { return m_aesDtc; }
std::shared_ptr<AreaEffectSimulation::Interface::Ftc> aesFtc() const { return m_aesFtc; }
std::shared_ptr<Evaluations::Interface::Ftc> evlFtc() const { return m_evlFtc; }
std::shared_ptr<GuezIedManagement::Interface::Dtc> gimDtc() const { return m_gimDtc; }
std::shared_ptr<Messaging::Interface::Dtc> msgDtc() const { return m_msgDtc; }
std::shared_ptr<Messaging::Interface::Ftc> msgFtc() const { return m_msgFtc; }
std::shared_ptr<OcSituationServer::Interface::Dts> ossDts() const { return m_ossDts; }
std::shared_ptr<OcSituationServer::Interface::Fts> ossFts() const { return m_ossFts; }
std::shared_ptr<OperatorManagement::Interface::Dtc> opmDtc() const { return m_opmDtc; }
std::shared_ptr<ParticipantManagement::Interface::Dtc> ppmDtc() const { return m_ppmDtc; }
std::shared_ptr<ParticipantManagement::Interface::Ftc> ppmFtc() const { return m_ppmFtc; }
std::shared_ptr<TrainingAreaBase::Interface::Dtc> tabDtc() const { return m_tabDtc; }
std::shared_ptr<TrainingAreaBase::Interface::Dts> tabDts() const { return m_tabDts; }
std::shared_ptr<TrainingAreaBase::Interface::Ftc> tabFtc() const { return m_tabFtc; }
std::shared_ptr<TrainingAreaBaseOC::Interface::Dtc> tabocDtc() const { return m_tabocDtc; }
std::shared_ptr<TrainingAreaBaseOC::Interface::Dts> tabocDts() const { return m_tabocDts; }
static inline QByteArray tryUncompress(const QByteArray &data, bool bWithCompression)
{
if (!bWithCompression)
return data;
try
{
// may throw ... :/
return qUncompress(data);
}
catch (...)
{}
return {};
}
private:
std::shared_ptr<DdsHandler> m_ddsHandler;
std::shared_ptr<HandlerOcData> m_handlerOcData;
std::shared_ptr<DbHandler> m_dbHandler;
std::shared_ptr<AreaEffectSimulation::Interface::Dtc> m_aesDtc;
std::shared_ptr<AreaEffectSimulation::Interface::Ftc> m_aesFtc;
std::shared_ptr<Evaluations::Interface::Ftc> m_evlFtc;
std::shared_ptr<GuezIedManagement::Interface::Dtc> m_gimDtc;
std::shared_ptr<Messaging::Interface::Dtc> m_msgDtc;
std::shared_ptr<Messaging::Interface::Ftc> m_msgFtc;
std::shared_ptr<OperatorManagement::Interface::Dtc> m_opmDtc;
std::shared_ptr<OcSituationServer::Interface::Dts> m_ossDts;
std::shared_ptr<OcSituationServer::Interface::Fts> m_ossFts;
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_ppmDtc;
std::shared_ptr<ParticipantManagement::Interface::Ftc> m_ppmFtc;
std::shared_ptr<TrainingAreaBase::Interface::Dtc> m_tabDtc;
std::shared_ptr<TrainingAreaBase::Interface::Dts> m_tabDts;
std::shared_ptr<TrainingAreaBase::Interface::Ftc> m_tabFtc;
std::shared_ptr<TrainingAreaBaseOC::Interface::Dtc> m_tabocDtc;
std::shared_ptr<TrainingAreaBaseOC::Interface::Dts> m_tabocDts;
NGL::INGLLogger &m_logger;
};
} // namespace OcSituationClient
+52
View File
@@ -0,0 +1,52 @@
/**
* Export definitions
* $Id$
* $HeadURL$
* $Author$
* Created by Hanna E. Rathje, SLSE, 2015-08-04
*/
#pragma once
#include <QtCore/qglobal.h>
#ifndef OSC_COMMON_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define OSC_COMMON_EXPORT
# else
# if defined(MAKE_SVCOSCCOMMON_LIB)
# define OSC_COMMON_EXPORT Q_DECL_EXPORT
# ifndef WIN32
# ifdef NDDSUSERDllExport
# undef NDDSUSERDllExport
# endif
# define NDDSUSERDllExport Q_DECL_EXPORT
# endif
# else
# define OSC_COMMON_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
#ifndef OSC_CLIENT_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define OSC_CLIENT_EXPORT
# else
# if defined(MAKE_SVCOSCCLIENT_LIB)
# define OSC_CLIENT_EXPORT Q_DECL_EXPORT
# else
# define OSC_CLIENT_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
#ifndef OSC_SERVER_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define OSC_SERVER_EXPORT
# else
# if defined(MAKE_SVCOSCSERVER_LIB)
# define OSC_SERVER_EXPORT Q_DECL_EXPORT
# else
# define OSC_SERVER_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
+5
View File
@@ -0,0 +1,5 @@
-- Initial reset counter an creation
-- IED reset counter
INSERT INTO osc_reset_counter (aes_type_id, reset_counter) VALUES (1, 0);
-- Danger area reset counter
INSERT INTO osc_reset_counter (aes_type_id, reset_counter) VALUES (14, 0);
+64
View File
@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<service namespace="OcSituationClient" abbreviation="OSC" procNames="OcSituationClient" exerciseDependency="Exercise" groups="ExercisePreparation,ExerciseExecution,ExercisePaused">
<rcs>
<Id Id="$Id: ea_export_script.txt 36918 2017-11-08 07:54:09Z ehrlicher $"/>
<HeadURL HeadURL="$HeadURL: svn://slssvn/TDS/branches/product/devel/trunk/Lts/Common/CodeGen/ea_export_script.txt $"/>
<Author Author="$Author: ehrlicher $"/>
</rcs>
<tables>
<table name="osc_reset_counter">
<column name="aes_type_id" datatype="integer" isPrimaryKey="1">
<sequence start="1" increment="1"/>
</column>
<column name="reset_counter" datatype="integer"/>
</table>
</tables>
<views/>
<dbServiceStructs>
<serviceStruct name="OscResetCounter" table="osc_reset_counter"/>
<table name="osc_reset_counter"/>
</dbServiceStructs>
<topicTypes>
<topicType name="SendDemandEvaluationSchemaRequest">
<column name="schemaId" idlType="long"/>
</topicType>
<topicType name="SendDemandSituationRequest">
<column name="centerEquipmentId" idlType="long"/>
<column name="radius" idlType="long"/>
<column name="position" idlType="Core::GeoPosition2D" isOptional="1"/>
<column name="filterActive" idlType="boolean" />
<column name="partyList" idlType="sequence&lt;long&gt;"/>
<column name="typeClassList" idlType="sequence&lt;long&gt;"/>
</topicType>
<topicType name="SendEquipmentErrorRegistrationRequest">
<column name="ocEquipmentNumber" idlType="long"/>
<column name="faultEquipmentNumber" idlType="string"/>
<column name="device" idlType="string"/>
<column name="text" idlType="string"/>
</topicType>
<topicType name="SendEquipmentRegistrationRequest">
<column name="participantId" idlType="long"/>
<column name="equipmentNumber" idlType="long"/>
</topicType>
<topicType name="SendEvaluationRequest">
<column name="schemaId" idlType="long"/>
<column name="senderOperatorId" idlType="long"/>
<column name="receiverOperatorId" idlType="long" isOptional="1"/>
<column name="timeStamp" idlType="long long"/>
<column name="hierarchy" idlType="string"/>
<column name="text" idlType="string"/>
</topicType>
</topicTypes>
<functionTopics>
<functionTopic name="SendDemandEvaluationSchema" requestTopicType="SendDemandEvaluationSchemaRequest" replyTopicType="Core::FunctionReply" requestTopicName="SendDemandEvaluationSchemaRequest" replyTopicName="SendDemandEvaluationSchemaReply" routeInReplay="0"/>
<functionTopic name="SendDemandSituation" requestTopicType="SendDemandSituationRequest" replyTopicType="Core::FunctionReply" requestTopicName="SendDemandSituationRequest" replyTopicName="SendDemandSituationReply" routeInReplay="0"/>
<functionTopic name="SendEquipmentErrorRegistration" requestTopicType="SendEquipmentErrorRegistrationRequest" replyTopicType="Core::FunctionReply" requestTopicName="SendEquipmentErrorRegistrationRequest" replyTopicName="SendEquipmentErrorRegistrationReply" routeInReplay="0"/>
<functionTopic name="SendEquipmentRegistration" requestTopicType="SendEquipmentRegistrationRequest" replyTopicType="Core::FunctionReply" requestTopicName="SendEquipmentRegistrationRequest" replyTopicName="SendEquipmentRegistrationReply" routeInReplay="0"/>
<functionTopic name="SendEvaluation" requestTopicType="SendEvaluationRequest" replyTopicType="Core::FunctionReply" requestTopicName="SendEvaluationRequest" replyTopicName="SendEvaluationReply" routeInReplay="0"/>
</functionTopics>
<enumerations>
<enumeration name="DummyEnum">
<attribute key="dummy" value="0"/>
</enumeration>
</enumerations>
</service>
+58
View File
@@ -0,0 +1,58 @@
/**
* Settings for OcSituationClient
* $Id$
* $HeadURL$
* $Author$
*/
#include "settings.h"
#include <QtCore/QSettings>
#include <nglsettings/nglsettings_settings.h>
#include <ngltools/ngltools_filesystem.h>
namespace OcSituationClient
{
class NGLSettingsClass : public NGL::Settings
{
public:
NGLSettingsClass()
: NGL::Settings(s_iniFile.isEmpty() ? NGL::findProjectConfigFile() : s_iniFile)
{}
static void setIniFile(const QString &fn)
{
s_iniFile = fn;
}
static QString s_iniFile;
};
QString NGLSettingsClass::s_iniFile;
Q_GLOBAL_STATIC(NGLSettingsClass, s)
//-----------------------------------------------------------------------------
NGL::Settings *Settings::settings()
{
return s();
}
//-----------------------------------------------------------------------------
void Settings::setIniFile(const QString &ini)
{
NGLSettingsClass::setIniFile(ini);
}
//-----------------------------------------------------------------------------
int32_t Settings::unitOffset()
{
return settings()->settings()->value(QLatin1String("OcSituationParameter/AliveTimeout"), 0x40000000).toInt();
}
int32_t Settings::situationRequestCycleTime()
{
return settings()->settings()->value(QLatin1String("OcSituationParameter/SituationRequestCycleTime"), 4).toInt() * 60 * 1000; // 4 minutes
}
const QString Settings::baseCoord()
{
return settings()->settings()->value(QLatin1String("Canag/BaseCoord"), QStringLiteral("32UMD00000000000000")).toString();
}
} // namespace OcSituationClient
+28
View File
@@ -0,0 +1,28 @@
/**
* Settings for OcSituationClient
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <QString>
namespace NGL
{
class Settings;
}
namespace OcSituationClient
{
namespace Settings
{
NGL::Settings *settings();
void setIniFile(const QString &ini);
int32_t unitOffset();
int32_t situationRequestCycleTime();
const QString baseCoord();
}
} // namespace OcSituationClient