Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+186
@@ -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)
|
||||
|
||||
+126
@@ -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
|
||||
+106
@@ -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
|
||||
+32
@@ -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
|
||||
+72
@@ -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
|
||||
+90
@@ -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
@@ -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 ¢ralAngle) 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
@@ -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 ¢ralAngle) 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
@@ -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
|
||||
Executable
+53
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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:
|
||||
Executable
+37
@@ -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
|
||||
Executable
+23
@@ -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
|
||||
Executable
+42
@@ -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
@@ -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
@@ -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
|
||||
Executable
+52
@@ -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
|
||||
@@ -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
@@ -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<long>"/>
|
||||
<column name="typeClassList" idlType="sequence<long>"/>
|
||||
</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>
|
||||
Executable
+58
@@ -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
|
||||
Executable
+28
@@ -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
|
||||
Reference in new issue
Block a user