Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
+54
@@ -0,0 +1,54 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
# Created by hjl, SLSE, 2016-06-22
|
||||
#
|
||||
|
||||
SET(xml_FILE vom_service.xml)
|
||||
|
||||
# --- Executable svcVideoOverlayManagement (sVOM) -------------------------------------------------
|
||||
#
|
||||
SET(SRCS_exe
|
||||
avs_interface.cpp
|
||||
avs_interface.h
|
||||
dds_handler.cpp
|
||||
dds_handler.h
|
||||
handler_participant_data.cpp
|
||||
handler_participant_data.h
|
||||
handler_infrastructure_data.cpp
|
||||
handler_infrastructure_data.h
|
||||
handler_overlays.cpp
|
||||
handler_overlays.h
|
||||
logger.cpp
|
||||
logger.h
|
||||
main.cpp
|
||||
main_handler.cpp
|
||||
main_handler.h
|
||||
settings.cpp
|
||||
settings.h
|
||||
)
|
||||
# make sure xml file is properly installed
|
||||
CODEGEN_HANDLE_SVC_XML(SRCS_exe ${xml_FILE})
|
||||
|
||||
NGL_ADD_SVC_ICON(SRCS_exe)
|
||||
NGL_ADD_EXECUTABLE(AAR SV svcVideoOverlayManagement ${SRCS_exe})
|
||||
NGL_TARGET_LINK_LIBRARIES(svcVideoOverlayManagement
|
||||
Qt5::Core
|
||||
Qt5::Network
|
||||
ddsconnector
|
||||
ddsQoS
|
||||
svcCoreClient
|
||||
svcIsmClient
|
||||
svcPpmClient
|
||||
nglsettings
|
||||
LtsCommandLineParser
|
||||
NGLLogger
|
||||
nglcoreapplication
|
||||
ddscore
|
||||
ngltools
|
||||
)
|
||||
NGL_INSTALL_TARGET(svcVideoOverlayManagement)
|
||||
NGL_INSTALL(AAR SV FILES log4cxx_vom.props DESTINATION bin)
|
||||
NGL_ADD_TARGET_LINK(svcVideoOverlayManagement sVOM)
|
||||
|
||||
+263
@@ -0,0 +1,263 @@
|
||||
/**
|
||||
* AVS-Interface for VideoOverlayManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2016-06-24
|
||||
*/
|
||||
|
||||
#include "avs_interface.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include <QTcpSocket>
|
||||
#include <QTimer>
|
||||
#include <QHostInfo>
|
||||
#include <ngltools/ngltools_convert.h>
|
||||
|
||||
namespace VideoOverlayManagement
|
||||
{
|
||||
|
||||
AvsInterface::AvsInterface(bool enableTryReconnect, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_waitTime(1)
|
||||
, m_enableTryReconnect(enableTryReconnect)
|
||||
, m_tryReconnect(false)
|
||||
, m_avsKeepAliveTimer(new QTimer(this))
|
||||
, m_keepAliveTime(Settings::getAvsKeepAliveTime())
|
||||
, m_avsIfConnectionState(AvsIfConnectionState::Undefined)
|
||||
, m_socket(nullptr)
|
||||
, m_logger(getLogger("AVS_Interface"))
|
||||
{
|
||||
doConnect();
|
||||
|
||||
connect(m_avsKeepAliveTimer, &QTimer::timeout,
|
||||
this, &AvsInterface::onAvsKeepAliveTimeout);
|
||||
|
||||
} // end of ctor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
AvsInterface::~AvsInterface()
|
||||
{
|
||||
if (m_socket)
|
||||
m_socket->close();
|
||||
delete m_socket;
|
||||
} // end of dtor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void AvsInterface::doConnect()
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "doConnect TCP-Socket ";
|
||||
|
||||
if (m_socket)
|
||||
m_socket->deleteLater();
|
||||
|
||||
m_socket = new QTcpSocket(this);
|
||||
connect(m_socket, &QTcpSocket::connected,
|
||||
this, &AvsInterface::onConnected);
|
||||
connect(m_socket, &QTcpSocket::disconnected,
|
||||
this, &AvsInterface::onDisonnected);
|
||||
connect(m_socket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error),
|
||||
this, &AvsInterface::onError);
|
||||
connect(m_socket, &QTcpSocket::readyRead,
|
||||
this, &AvsInterface::onReadyRead);
|
||||
|
||||
if (m_tryReconnect)
|
||||
{
|
||||
INFO_LOG(m_logger) << "Try reconnect to host: " << m_hostName
|
||||
<< " port: " << m_hostPort
|
||||
<< " ip-address: " << m_ipAddressDNS;
|
||||
|
||||
m_socket->connectToHost(m_hostName, m_hostPort);
|
||||
}
|
||||
} // end of doConnect()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void AvsInterface::start(const QString &hostName, quint16 port)
|
||||
{
|
||||
QHostInfo hostInfo = QHostInfo::fromName(hostName);
|
||||
|
||||
const QList<QHostAddress> ipList = hostInfo.addresses();
|
||||
if (ipList.isEmpty())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Non ip-address found for hostname: " << hostName;
|
||||
m_ipAddressDNS.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
INFO_LOG(m_logger) << "Try connect to AVS: " << hostName
|
||||
<< " port: " << port
|
||||
<< " ip-address: " << ipList.at(0).toString();
|
||||
|
||||
m_ipAddressDNS = ipList.at(0).toString();
|
||||
}
|
||||
m_hostName = hostName;
|
||||
m_hostPort = port;
|
||||
m_socket->connectToHost(m_hostName, m_hostPort);
|
||||
} // end of start()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void AvsInterface::onConnected()
|
||||
{
|
||||
INFO_LOG(m_logger) << "Connected to "
|
||||
<< m_socket->peerAddress().toString()
|
||||
<< ":" << m_socket->peerPort();
|
||||
m_waitTime = 1;
|
||||
m_buffer.clear();
|
||||
|
||||
m_avsIfConnectionState = AvsIfConnectionState::Connected;
|
||||
emit avsIfConnectionState(AvsIfConnectionState::Connected);
|
||||
|
||||
m_avsKeepAliveTimer->start(m_keepAliveTime);
|
||||
} // end of onConnected()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void AvsInterface::onDisonnected()
|
||||
{
|
||||
INFO_LOG(m_logger) << "Disconnected from " << m_socket->peerAddress().toString()
|
||||
<< ":" << m_socket->peerPort();
|
||||
|
||||
m_avsKeepAliveTimer->stop();
|
||||
m_avsIfConnectionState = AvsIfConnectionState::Disconnected;
|
||||
emit avsIfConnectionState(AvsIfConnectionState::Disconnected);
|
||||
} // end of onDisonnected()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void AvsInterface::onError(QAbstractSocket::SocketError err)
|
||||
{
|
||||
if (m_enableTryReconnect)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Socket error: " << err
|
||||
<< " \"" << m_socket->errorString() << "\""
|
||||
<< " Hostname: " << m_hostName
|
||||
<< " Port:" << m_hostPort
|
||||
<< " ip-Address:" << m_ipAddressDNS
|
||||
<< " - trying to reconnect in " << m_waitTime << " seconds";
|
||||
}
|
||||
else
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Socket error: " << err
|
||||
<< " \"" << m_socket->errorString() << "\""
|
||||
<< " Hostname: " << m_hostName
|
||||
<< " Port:" << m_hostPort
|
||||
<< " ip-Address:" << m_ipAddressDNS;
|
||||
}
|
||||
|
||||
m_socket->disconnectFromHost();
|
||||
m_avsKeepAliveTimer->stop();
|
||||
|
||||
m_avsIfConnectionState = AvsIfConnectionState::ConnectionError;
|
||||
emit avsIfConnectionState(AvsIfConnectionState::ConnectionError);
|
||||
|
||||
// try reconnects ....
|
||||
if (m_enableTryReconnect)
|
||||
tryReconnect();
|
||||
} // end of onError()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void AvsInterface::tryReconnect()
|
||||
{
|
||||
m_tryReconnect = true;
|
||||
m_avsIfConnectionState = AvsIfConnectionState::TryReconnect;
|
||||
emit avsIfConnectionState(AvsIfConnectionState::TryReconnect);
|
||||
|
||||
if (m_socket->state() != QAbstractSocket::UnconnectedState)
|
||||
m_socket->waitForDisconnected();
|
||||
|
||||
m_waitTime += 2;
|
||||
|
||||
if (m_waitTime > 120)
|
||||
m_waitTime = 120;
|
||||
|
||||
QTimer::singleShot(m_waitTime * 1000, this, &AvsInterface::doConnect);
|
||||
} // end of tryReconnect()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void AvsInterface::onReadyRead()
|
||||
{
|
||||
while (m_socket->canReadLine())
|
||||
{
|
||||
const QByteArray data = m_socket->readLine().trimmed();
|
||||
if (data.isEmpty())
|
||||
continue;
|
||||
|
||||
INFO_LOG(m_logger) << "Incoming RCP_AVA: '" << data << "'";
|
||||
int cmdNr = -1;
|
||||
bool bOk = false;
|
||||
|
||||
const QVector<QByteArray> cmdList = NGL::parseFromTelnet(data);
|
||||
|
||||
if (cmdList.size() > 1)
|
||||
cmdNr = cmdList.at(0).toInt(&bOk);
|
||||
|
||||
if (bOk)
|
||||
{
|
||||
// Fuer VOM sind nur diese 4 Command relavant
|
||||
switch (cmdNr)
|
||||
{
|
||||
case int(AvsCmdState::Ok):
|
||||
emit avsCmdState(AvsCmdState::Ok);
|
||||
break;
|
||||
case int(AvsCmdState::KeepAlive):
|
||||
emit avsCmdState(AvsCmdState::KeepAlive);
|
||||
m_avsKeepAliveTimer->start(m_keepAliveTime);
|
||||
break;
|
||||
case int(AvsCmdState::BadArguments):
|
||||
emit avsCmdState(AvsCmdState::BadArguments);
|
||||
break;
|
||||
case int(AvsCmdState::CommandNotStateValid):
|
||||
emit avsCmdState(AvsCmdState::CommandNotStateValid);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // while
|
||||
} // end of onReadyRead()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void AvsInterface::onAvsKeepAliveTimeout()
|
||||
{
|
||||
emit avsKeepAliveTimeout();
|
||||
|
||||
// try reconnects ....
|
||||
if (m_enableTryReconnect)
|
||||
{
|
||||
m_socket->disconnectFromHost();
|
||||
m_avsKeepAliveTimer->stop();
|
||||
|
||||
if (m_socket->state() != QAbstractSocket::UnconnectedState)
|
||||
m_socket->waitForDisconnected();
|
||||
|
||||
tryReconnect();
|
||||
}
|
||||
} // end of onAvsKeepAliveTimeout()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool AvsInterface::sendCommand(const QByteArray &qba)
|
||||
{
|
||||
bool bOk = true;
|
||||
|
||||
INFO_LOG(m_logger) << "Send command: " << qba.trimmed();
|
||||
|
||||
if (m_socket->state() != QTcpSocket::ConnectedState)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "sendCommand()"
|
||||
<< " '" << qba.trimmed()
|
||||
<< "' No socket connection established.";
|
||||
return false;
|
||||
}
|
||||
|
||||
int trxBytes = m_socket->write(qba);
|
||||
|
||||
if (trxBytes != qba.size())
|
||||
{
|
||||
bOk = false;
|
||||
ERROR_LOG(m_logger) << "Insufficient number of tansfered bytes."
|
||||
<< " Soll: " << trxBytes << " Ist: " << qba.size();
|
||||
}
|
||||
m_socket->flush();
|
||||
return bOk;
|
||||
} // end of sendCommand()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
} // namespace VideoOverlayManagement
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
/**
|
||||
* AVS-Interface for VideoOverlayManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2016-06-24
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtNetwork/QHostAddress>
|
||||
#include "logger.h"
|
||||
|
||||
// Forwarddeclarations
|
||||
class QTcpSocket;
|
||||
class QTimer;
|
||||
|
||||
namespace VideoOverlayManagement
|
||||
{
|
||||
|
||||
enum class AvsIfConnectionState
|
||||
{
|
||||
Undefined = 0,
|
||||
Connected,
|
||||
Disconnected,
|
||||
TryReconnect,
|
||||
ConnectionError,
|
||||
};
|
||||
|
||||
enum class AvsCmdState
|
||||
{
|
||||
Ok = 200,
|
||||
KeepAlive = 298,
|
||||
BadArguments = 402,
|
||||
CommandNotStateValid = 455
|
||||
};
|
||||
|
||||
|
||||
class AvsInterface
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Constructor connect to plugboard
|
||||
* @param[in] enableTryReconnect if true, try reconnection
|
||||
* @param[in] parent Pointer to parent qObject
|
||||
*/
|
||||
AvsInterface(bool enableTryReconnect, QObject *parent = nullptr);
|
||||
|
||||
~AvsInterface();
|
||||
|
||||
/**
|
||||
* Connect to AVS RCP_AVA
|
||||
* @param[in] hostName Hostname or Ip address to get access to AVS
|
||||
* @param[in] port Ip port to get access to AVS
|
||||
*/
|
||||
void start(const QString &hostName, quint16 port);
|
||||
|
||||
AvsIfConnectionState getAvsIfState()
|
||||
{
|
||||
return m_avsIfConnectionState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send data to connected TcpSocket
|
||||
* @param[in] qba Data to be transfered completed with "\r\n"
|
||||
*/
|
||||
bool sendCommand(const QByteArray &qba);
|
||||
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* Signals current AVS connection state
|
||||
*/
|
||||
void avsIfConnectionState(AvsIfConnectionState);
|
||||
/**
|
||||
* Signals current AVS command state
|
||||
*/
|
||||
void avsCmdState(AvsCmdState);
|
||||
|
||||
/**
|
||||
* Signals an missing AVS keep-alive
|
||||
* If the parameter 'enableTryReconnect' is set
|
||||
* the connection attempting to restore automatically
|
||||
*/
|
||||
void avsKeepAliveTimeout();
|
||||
|
||||
/**
|
||||
* Define the signal/slots connects uesd for TcpSocket
|
||||
*/
|
||||
protected Q_SLOTS:
|
||||
void doConnect();
|
||||
void onConnected();
|
||||
void onDisonnected();
|
||||
void onError(QAbstractSocket::SocketError);
|
||||
void onReadyRead();
|
||||
void onAvsKeepAliveTimeout();
|
||||
|
||||
private: // methode
|
||||
void tryReconnect();
|
||||
|
||||
private: // attributes
|
||||
QString m_hostName; ///< Hostname or Ip address to get access to AVS
|
||||
QString m_ipAddressDNS; ///< DNS IP address of AVS
|
||||
quint16 m_hostPort; ///< Ip port to get access to AVS
|
||||
qint32 m_waitTime; ///< delay before try reconnection
|
||||
bool m_enableTryReconnect; ///< if true, enables try reconnection
|
||||
bool m_tryReconnect; ///< if true, try reconnection
|
||||
|
||||
QTimer *m_avsKeepAliveTimer; ///< AVS keep-alive timer
|
||||
qint32 m_keepAliveTime; ///< AVS keep-alive time intervall in msec
|
||||
|
||||
AvsIfConnectionState m_avsIfConnectionState; ///< AVS Interface connection state
|
||||
|
||||
QTcpSocket *m_socket; ///< pointer to tcpsocket object
|
||||
|
||||
QByteArray m_buffer; ///< data buffer to hold incoming data form tcpsocket
|
||||
NGL::INGLLogger &m_logger; ///< Interface to the Logging-Facility
|
||||
|
||||
};
|
||||
|
||||
} // namespace VideoOverlayManagement
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* DdsHandler for VideoOverlayManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2016-07-06
|
||||
*/
|
||||
|
||||
#include "dds_handler.h"
|
||||
|
||||
#include <DDS/Core/pacemaker.h>
|
||||
|
||||
namespace VideoOverlayManagement
|
||||
{
|
||||
|
||||
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();
|
||||
} // end of ctor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool DdsHandler::init(const QStringList &qosFileList)
|
||||
{
|
||||
INFO_LOG(m_logger) << "--- Start VideoOverlayManagement DDSHandler.";
|
||||
|
||||
if (!m_ddsConnector->init(qosFileList))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Error initializing dds connections - aborting";
|
||||
return false;
|
||||
}
|
||||
|
||||
// default initialize Publisher and Subscriber
|
||||
m_ddsConnector->initPublisherSubscriber();
|
||||
|
||||
// Pacemaker
|
||||
m_pacemaker = std::make_shared<Core::Pacemaker>(m_ddsConnector);
|
||||
|
||||
return true;
|
||||
} // end of init()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
} // Namespace VideoOverlayManagement
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* DdsHandler for VideoOverlayManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2016-07-06
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <DDS/DDSConnector/dds_connector.h>
|
||||
|
||||
#include "logger.h"
|
||||
|
||||
namespace Core
|
||||
{
|
||||
class Pacemaker;
|
||||
}
|
||||
|
||||
namespace VideoOverlayManagement
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
|
||||
std::shared_ptr<Core::Pacemaker> m_pacemaker;
|
||||
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
} // namespace VideoOverlayManagement
|
||||
@@ -0,0 +1,162 @@
|
||||
/**
|
||||
* Handler for infrastructure data
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author:
|
||||
* Created by hjl, SLSE, 2016-07-22
|
||||
*/
|
||||
|
||||
#include "handler_infrastructure_data.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include <QVector>
|
||||
|
||||
using namespace VideoOverlayManagement;
|
||||
|
||||
HandlerInfrastructureData::HandlerInfrastructureData(const std::shared_ptr<DdsHandler> &ddsHandler, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_ddsHandler(ddsHandler)
|
||||
, m_exerciseId(0)
|
||||
, m_logger(getLogger("HandlerInfrastructureData"))
|
||||
{
|
||||
} // end of ctor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
HandlerInfrastructureData::~HandlerInfrastructureData()
|
||||
{
|
||||
} // end of dtor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool HandlerInfrastructureData::init(int exerciseId)
|
||||
{
|
||||
m_exerciseId = exerciseId;
|
||||
// DTC InfrastructureManagement
|
||||
m_dtc = InfrastructureManagement::Interface::Dtc::create(m_ddsHandler->dds());
|
||||
if (m_dtc == nullptr)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not create DTC InfrastructureManagement";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_dtc->enableMainStructureElement() ||
|
||||
!m_dtc->enableMountingPointAsset() ||
|
||||
!m_dtc->enableInstrumentationAsset() ||
|
||||
!m_dtc->waitForHistoricalDataMainStructureElement() ||
|
||||
!m_dtc->waitForHistoricalDataMountingPointAsset() ||
|
||||
!m_dtc->waitForHistoricalDataInstrumentationAsset())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "init() DTC InfrastructureManagement failed";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get 'static' data for all rooms where a camera is available
|
||||
QMap<int, QVector<InfrastructureManagement::InstrumentationAsset>> assetsMap; // (roomId, QVector<Asset>)
|
||||
|
||||
auto predicate =
|
||||
[](const InfrastructureManagement::InstrumentationAsset & a)
|
||||
{
|
||||
return a.mountingPointTypeId() == InfrastructureManagement::MountingPointType::IndoorCamera;
|
||||
};
|
||||
if (!m_dtc->getAllAssetsPerRoom(predicate, assetsMap))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "HandlerInfrastructureData::getAllAssetsPerRoom() failed"
|
||||
<< " assetsMap.size(): " << assetsMap.size();
|
||||
}
|
||||
|
||||
for (auto i = assetsMap.cbegin(); i != assetsMap.cend(); ++i)
|
||||
{
|
||||
const int roomId = i.key();
|
||||
for (const InfrastructureManagement::InstrumentationAsset &asset : i.value())
|
||||
{
|
||||
auto it = std::find(asset.availableInExercise().begin(),
|
||||
asset.availableInExercise().end(), m_exerciseId);
|
||||
if (it == asset.availableInExercise().end())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Asset " << asset.id()
|
||||
<< " is not available in current exercise - skipping";
|
||||
continue;
|
||||
}
|
||||
// in interne m_roomId2CameraNameMap eintragen, zur Zeit nur eine Kamera pro Raum möglich
|
||||
m_roomId2CameraNameMap.insert(roomId, QString::fromStdString(asset.name()));
|
||||
// und fuer subscribe in m_assetId2RoomIdMap eintragen
|
||||
m_assetId2RoomIdMap.insert(asset.id(), roomId);
|
||||
DEBUG_LOG(m_logger) << " assetId: " << asset.id()
|
||||
<< " mountingPointTypeId: " << asset.mountingPointTypeId()
|
||||
<< " name: " << asset.name();
|
||||
}
|
||||
} // for(auto i = assetMap...
|
||||
|
||||
INFO_LOG(m_logger) << "m_roomId2CameraNameMap.size(): " << m_roomId2CameraNameMap.size();
|
||||
for (auto i = m_roomId2CameraNameMap.begin(); i != m_roomId2CameraNameMap.end(); ++i)
|
||||
{
|
||||
INFO_LOG(m_logger) << "roomId: " << i.key()
|
||||
<< " cameraName: " << i.value();
|
||||
}
|
||||
|
||||
// Subsribe for AssetChanged (Daten der cameras aus den Assets ermitteln)
|
||||
connect(m_dtc.get(), &InfrastructureManagement::Interface::Dtc::instrumentationAssetChanged,
|
||||
this, &HandlerInfrastructureData::onAssetChanged);
|
||||
|
||||
// we don't need them now anymore -> unsubscribe (really?)
|
||||
m_dtc->enableMainStructureElement(false);
|
||||
m_dtc->enableMountingPointAsset(false);
|
||||
|
||||
INFO_LOG(m_logger) << "HandlerInfrastructureData::init() finished. "
|
||||
<< " m_roomId2CameraNameMap.size(): " << m_roomId2CameraNameMap.size();
|
||||
return true;
|
||||
} // end of init()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool HandlerInfrastructureData::isCameraAvailable(int roomId) const
|
||||
{
|
||||
return m_roomId2CameraNameMap.contains(roomId);
|
||||
} // end of isCameraAvailable()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
QString HandlerInfrastructureData::getStreamNameFromRoomId(int roomId) const
|
||||
{
|
||||
auto it = m_roomId2CameraNameMap.find(roomId);
|
||||
const QString qs(it == m_roomId2CameraNameMap.end() ? QString() : it.value());
|
||||
DEBUG_LOG(m_logger) << "streamName for roomId: " << roomId << " '" << qs << "' ";
|
||||
|
||||
return qs;
|
||||
} // end of getStreamNameFromRoomId()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void HandlerInfrastructureData::onAssetChanged(const InfrastructureManagement::InstrumentationAsset &data, DataModification modType)
|
||||
{
|
||||
Q_UNUSED(modType);
|
||||
if (data.mountingPointTypeId() != InfrastructureManagement::MountingPointType::IndoorCamera)
|
||||
return;
|
||||
|
||||
INFO_LOG(m_logger) << "onAssetChanged()"
|
||||
<< " assetId: " << data.id()
|
||||
<< " name: " << data.name();
|
||||
|
||||
auto it = std::find(data.availableInExercise().begin(),
|
||||
data.availableInExercise().end(), m_exerciseId);
|
||||
if (it == data.availableInExercise().end())
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "Asset " << data.id()
|
||||
<< " is not available in current exercise - skipping";
|
||||
return;
|
||||
}
|
||||
|
||||
// Hier muss aus der AssetId die zugehoerige roomid verwendet werden !!
|
||||
m_roomId2CameraNameMap.insert(getRoomIdFromAssetId(data.id()), QString::fromStdString(data.name()));
|
||||
|
||||
for (auto i = m_roomId2CameraNameMap.begin(); i != m_roomId2CameraNameMap.end(); ++i)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "m_roomId2CameraNameMap changed... "
|
||||
<< " m_roomId2CameraNameMap.size(): " << m_roomId2CameraNameMap.size()
|
||||
<< " roomId: " << i.key()
|
||||
<< " cameraName: " << *i;
|
||||
}
|
||||
} // end of onAssetChanged()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int HandlerInfrastructureData::getRoomIdFromAssetId(int assetId) const
|
||||
{
|
||||
return m_assetId2RoomIdMap.value(assetId, -1);
|
||||
} // end of getRoomIdFromAssetId()
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Handler for infrastructure data
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2016-07-22
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "dds_handler.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <InfrastructureManagement/ism_dtc.h>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QMap>
|
||||
|
||||
namespace VideoOverlayManagement
|
||||
{
|
||||
|
||||
class HandlerInfrastructureData : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit HandlerInfrastructureData(const std::shared_ptr<DdsHandler> &ddsHandler, QObject *parent = nullptr);
|
||||
|
||||
~HandlerInfrastructureData();
|
||||
|
||||
/**
|
||||
* Initialize the handler to manage information from infrastructure management
|
||||
*/
|
||||
bool init(int exerciseId);
|
||||
|
||||
/**
|
||||
* Check if there is a camera in the room
|
||||
* @param[in] roomId Id of the room to get information about camera availability
|
||||
* @returns true if camera is available, otherwise false
|
||||
*/
|
||||
bool isCameraAvailable(int roomId) const;
|
||||
|
||||
/**
|
||||
* Returns the streamname of the camera for the given roomId
|
||||
* @param[in] roomId Id of the room to get the streamname for this camera
|
||||
* @returns returns the streamname if camera is available, otherwise string is empty
|
||||
*/
|
||||
QString getStreamNameFromRoomId(int roomId) const;
|
||||
|
||||
|
||||
Q_SIGNALS:
|
||||
|
||||
private Q_SLOTS:
|
||||
/**
|
||||
* Handle the signals from 'InfrastructureManagement'
|
||||
*/
|
||||
void onAssetChanged(const InfrastructureManagement::InstrumentationAsset &data, DataModification modType);
|
||||
|
||||
private: // methoden
|
||||
/**
|
||||
* Returns the room id for the given assetId
|
||||
* @param[in] assetId Id of the asset to get the room id for
|
||||
* @returns returns the room id if available, otherwise -1
|
||||
*/
|
||||
int getRoomIdFromAssetId(int assetId) const;
|
||||
|
||||
private: // attributes
|
||||
std::shared_ptr<DdsHandler> m_ddsHandler; ///< Pointer to VOM DDS handler
|
||||
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_dtc; ///< Pointer to DTC InfrastructureManagement interface object
|
||||
|
||||
QMap<int, int> m_assetId2RoomIdMap; ///< optional nur noetig bei subscribe for AssetChanged
|
||||
|
||||
QMap<int, QString> m_roomId2CameraNameMap; ///< Reference map roomId to camera name(roomId, cameraName) Condition: per room one camera!
|
||||
int m_exerciseId;
|
||||
|
||||
NGL::INGLLogger &m_logger; ///< Interface to the Logging-Facility
|
||||
|
||||
};
|
||||
} // namespace VideoOverlayManagement
|
||||
|
||||
+240
@@ -0,0 +1,240 @@
|
||||
/**
|
||||
* Handler for Video Overlays
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2016-07-07
|
||||
*/
|
||||
|
||||
#include "handler_overlays.h"
|
||||
#include "handler_participant_data.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include <QByteArray>
|
||||
|
||||
using namespace VideoOverlayManagement;
|
||||
|
||||
HandlerOverlays::HandlerOverlays(AvsInterface *avsIf,
|
||||
const std::shared_ptr<HandlerParticipantData> &handlerParticipantData,
|
||||
const std::shared_ptr<HandlerInfrastructureData> &handlerInfrastructureData,
|
||||
int exerciseId,
|
||||
QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_avsIf(avsIf)
|
||||
, m_handlerParticipantData(handlerParticipantData)
|
||||
, m_handlerInfrastructureData(handlerInfrastructureData)
|
||||
, m_exerciseId(exerciseId)
|
||||
, m_logger(getLogger("HandlerOverlays"))
|
||||
{
|
||||
} // end of ctor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
HandlerOverlays::~HandlerOverlays()
|
||||
{
|
||||
} // end of dtor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool HandlerOverlays::init()
|
||||
{
|
||||
INFO_LOG(m_logger) << "Start VideoOverlay Handler.";
|
||||
|
||||
// internal Signal/Slot connection (must be done before calling initParticipantsInRoomMap() !)
|
||||
connect(this, &HandlerOverlays::participantsInRoomMapChanged,
|
||||
this, &HandlerOverlays::onParticipantsInRoomMapChanged);
|
||||
|
||||
// Get assigned participants to roomId data from Player Management ...
|
||||
initParticipantsInRoomMap();
|
||||
// Subscribe for external changes
|
||||
connect(m_handlerParticipantData.get(), &HandlerParticipantData::participantPositionChanged,
|
||||
this, &HandlerOverlays::onParticipantPositionChanged);
|
||||
|
||||
INFO_LOG(m_logger) << "VOM Handler initialized. ";
|
||||
|
||||
return true;
|
||||
} // end of init()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void HandlerOverlays::onParticipantPositionChanged(int oldRoomId, int newRoomId, int participantId)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onParticipantPositionChanged() "
|
||||
<< " oldRoomId: " << oldRoomId
|
||||
<< " newRoomId: " << newRoomId
|
||||
<< " participantId: " << participantId
|
||||
;
|
||||
|
||||
if (oldRoomId > 0) // is valid
|
||||
removePartIdFromParticipantsInRoomMap(oldRoomId, participantId);
|
||||
|
||||
if (newRoomId > 0)
|
||||
addPartIdToParticipantsInRoomMap(newRoomId, participantId);
|
||||
} // end of onParticipantPositionChanged()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void HandlerOverlays::onParticipantsInRoomMapChanged(int roomId, const QSet<int> &participants)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "onParticipantsInRoomMapChanged() "
|
||||
<< " roomId: " << roomId
|
||||
<< " partId: " << getAllEquipmentNumbers(participants, false)
|
||||
<< " eqNo: " << getAllEquipmentNumbers(participants, true)
|
||||
<< " participants.size(): " << participants.size()
|
||||
;
|
||||
|
||||
if (!m_handlerInfrastructureData->isCameraAvailable(roomId))
|
||||
{
|
||||
WARNING_LOG(m_logger) << "onParticipantsInRoomMapChanged() Non camera available in roomId: " << roomId << " No data will be send to AVS.";
|
||||
return;
|
||||
}
|
||||
|
||||
// SetStreamOverlayText Command String zusammenstellen
|
||||
QString cmd;
|
||||
QString contextName = getContextName();
|
||||
QString streamName = m_handlerInfrastructureData->getStreamNameFromRoomId(roomId);
|
||||
QString overlayTemplateName = getOverlayTemplateName();
|
||||
|
||||
if (streamName.isEmpty())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "onParticipantsInRoomMapChanged() No streamName found for roomId: " << roomId << " No data will be send to AVS.";
|
||||
return;
|
||||
}
|
||||
|
||||
cmd.append(QLatin1String("SetStreamOverlayText "));
|
||||
cmd.append(contextName);
|
||||
cmd.append(QLatin1String(" "));
|
||||
cmd.append(streamName);
|
||||
cmd.append(QLatin1String(" "));
|
||||
cmd.append(overlayTemplateName);
|
||||
cmd.append(QLatin1String(" "));
|
||||
cmd.append(QLatin1String("0 "));
|
||||
cmd.append(QLatin1String("\""));
|
||||
|
||||
cmd.append(QLatin1String("Participants(EqNo) in roomId "));
|
||||
cmd.append((QString::number(roomId)));
|
||||
cmd.append(QLatin1String(": "));
|
||||
cmd.append(getAllEquipmentNumbers(participants, true));
|
||||
cmd.append(QLatin1String("\""));
|
||||
|
||||
QByteArray qba = cmd.toLatin1();
|
||||
qba += "\r\n";
|
||||
|
||||
INFO_LOG(m_logger) << "onParticipantsInRoomMapChanged() sendCommand: " << qba ;
|
||||
m_avsIf->sendCommand(qba);
|
||||
|
||||
// room entry der keine participants enthaelt loeschen
|
||||
if (participants.isEmpty())
|
||||
m_participantsInRoomMap.remove(roomId);
|
||||
} // end of onParticipantsInRoomMapChanged()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void HandlerOverlays::initParticipantsInRoomMap()
|
||||
{
|
||||
// QMap<participantId, roomId>
|
||||
const QMap<int, int> qm = m_handlerParticipantData->getAllAssignedParticipants();
|
||||
|
||||
for (auto i = qm.begin(); i != qm.end(); ++i)
|
||||
onParticipantPositionChanged(0, i.value(), i.key());
|
||||
} // end of initParticipantsInRoomMap()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void HandlerOverlays::addPartIdToParticipantsInRoomMap(int roomId, int participantId)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "addPartIdToParticipantsInRoomMap() "
|
||||
<< " roomId: " << roomId
|
||||
<< " participantId: " << participantId
|
||||
;
|
||||
|
||||
QSet<int> participants;
|
||||
|
||||
if (m_participantsInRoomMap.contains(roomId))
|
||||
{
|
||||
QMap<int, QSet<int>>::const_iterator i = m_participantsInRoomMap.constFind(roomId);
|
||||
participants = i.value();
|
||||
}
|
||||
|
||||
participants.insert(participantId);
|
||||
m_participantsInRoomMap.insert(roomId, participants);
|
||||
|
||||
///
|
||||
DEBUG_LOG(m_logger) << "emit participantsInRoomMapChanged()"
|
||||
<< " roomId: " << roomId
|
||||
<< " partId: " << getAllEquipmentNumbers(participants, false)
|
||||
<< " eqNo: " << getAllEquipmentNumbers(participants, true)
|
||||
<< " participants.size(): " << participants.size()
|
||||
;
|
||||
|
||||
emit participantsInRoomMapChanged(roomId, participants);
|
||||
} // end of addPartIdToParticipantsInRoomMap()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void HandlerOverlays::removePartIdFromParticipantsInRoomMap(int roomId, int participantId)
|
||||
{
|
||||
DEBUG_LOG(m_logger) << "removePartIdFromParticipantsInRoomMap() "
|
||||
<< " roomId: " << roomId
|
||||
<< " participantId: " << participantId
|
||||
;
|
||||
|
||||
if (m_participantsInRoomMap.contains(roomId))
|
||||
{
|
||||
QMap<int, QSet<int>>::const_iterator i = m_participantsInRoomMap.constFind(roomId);
|
||||
QSet<int> participants = i.value();
|
||||
|
||||
// remove participant from the set
|
||||
participants.remove(participantId);
|
||||
m_participantsInRoomMap.insert(roomId, participants);
|
||||
|
||||
DEBUG_LOG(m_logger) << "emit participantsInRoomMapChanged()"
|
||||
<< " roomId: " << roomId
|
||||
<< " partId: " << getAllEquipmentNumbers(participants, false)
|
||||
<< " eqNo: " << getAllEquipmentNumbers(participants, true)
|
||||
<< " participants.size(): " << participants.size()
|
||||
;
|
||||
|
||||
emit participantsInRoomMapChanged(roomId, participants);
|
||||
}
|
||||
} // end of removePartIdFromParticipantsInRoomMap()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
QString HandlerOverlays::getContextName() const
|
||||
{
|
||||
QString qs(Settings::getContextName());
|
||||
qs.append(QString::number(m_exerciseId));
|
||||
return qs;
|
||||
} // end of getContextName()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
QString HandlerOverlays::getOverlayTemplateName() const
|
||||
{
|
||||
return Settings::getOverlayTemplateName();
|
||||
} // end of getOverlayTemplateName()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
QSet<int> HandlerOverlays::convertParticipantIdsToEquipmentNo(const QSet<int> &participants) const
|
||||
{
|
||||
QSet<int> equipmentNumbers;
|
||||
|
||||
for (int currentParticipantId : participants)
|
||||
{
|
||||
int equipmentNumber = m_handlerParticipantData->getEquipmentNumber(currentParticipantId);
|
||||
equipmentNumbers.insert(equipmentNumber);
|
||||
}
|
||||
return equipmentNumbers;
|
||||
} // end of convertParticipantIdsToEquipmentNo()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
QString HandlerOverlays::getAllEquipmentNumbers(QSet<int> data, bool isParticipantIds) const
|
||||
{
|
||||
QString qs;
|
||||
|
||||
if (isParticipantIds)
|
||||
data = convertParticipantIdsToEquipmentNo(data);
|
||||
|
||||
for (int currentDataId : qAsConst(data))
|
||||
{
|
||||
qs.append(QString::number(currentDataId));
|
||||
qs.append(QLatin1String(", "));
|
||||
}
|
||||
// remove last ", "
|
||||
if (!qs.isEmpty())
|
||||
qs.chop(2);
|
||||
return qs;
|
||||
} // end of getAllEquipmentNumbers()
|
||||
//-----------------------------------------------------------------------------
|
||||
+123
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* Handler for Video Overlays
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2016-07-07
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QSet>
|
||||
|
||||
#include "avs_interface.h"
|
||||
#include "handler_participant_data.h"
|
||||
#include "handler_infrastructure_data.h"
|
||||
#include "logger.h"
|
||||
|
||||
|
||||
namespace VideoOverlayManagement
|
||||
{
|
||||
// Forwarddeclarations
|
||||
class AvsInterface;
|
||||
|
||||
class HandlerOverlays
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit HandlerOverlays(AvsInterface *avsIf,
|
||||
const std::shared_ptr<HandlerParticipantData> &handlerParticipantData,
|
||||
const std::shared_ptr<HandlerInfrastructureData> &handlerInfrastructureData,
|
||||
int exerciseId,
|
||||
QObject *parent = nullptr);
|
||||
~HandlerOverlays();
|
||||
|
||||
bool init();
|
||||
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* Emits when a participant position was changed to another room (internal signal/slot)
|
||||
* @param[in] roomId Id of the room where the participant association to be change
|
||||
* @param[in] participants List of all participants assigned to roomId
|
||||
*/
|
||||
void participantsInRoomMapChanged(int roomId, const QSet<int> &participants);
|
||||
|
||||
|
||||
private Q_SLOTS:
|
||||
/**
|
||||
* Handle incoming position changed signals
|
||||
* @param[in] oldRoomId ID of the room where the participant was at the last message.
|
||||
* @param[in] newRoomId ID of the room where the participant was at this message.
|
||||
* @param[in] participantId Id of the participant who is assigned to the message
|
||||
*/
|
||||
void onParticipantPositionChanged(int oldRoomId, int newRoomId, int participantId);
|
||||
/**
|
||||
* Build the video overlay string based on the given data
|
||||
* @param[in] roomId Id of the room to get information about camera availability
|
||||
* @param[in] participants List of all participants assigned to roomId
|
||||
*/
|
||||
void onParticipantsInRoomMapChanged(int roomId, const QSet<int> &participants);
|
||||
|
||||
private: // methodes
|
||||
/**
|
||||
* Initialize 'participantsInRoomMap'
|
||||
*/
|
||||
void initParticipantsInRoomMap();
|
||||
|
||||
/**
|
||||
* Add participant in 'participantsInRoomMap' for the given roomId entry
|
||||
* and emits onParticipantsInRoomMapChanged(...) to build the video overlay string
|
||||
* @param[in] roomId Id of the room which entry will to be modified
|
||||
* @param[in] participantId Id of the participant who has to be modified
|
||||
*/
|
||||
void addPartIdToParticipantsInRoomMap(int roomId, int participantId);
|
||||
|
||||
/**
|
||||
* Remove participant in 'participantsInRoomMap' for the given roomId entry
|
||||
* and emits onParticipantsInRoomMapChanged(...) to build the video overlay string
|
||||
* @param[in] roomId Id of the room which entry will to be modified
|
||||
* @param[in] participantId Id of the participant who has to be remove
|
||||
*/
|
||||
void removePartIdFromParticipantsInRoomMap(int roomId, int participantId);
|
||||
|
||||
/**
|
||||
* Returns the 'context' name used for AVS output
|
||||
* @returns returns the context name
|
||||
*/
|
||||
QString getContextName() const;
|
||||
|
||||
/**
|
||||
* Returns the name for the overlay template used for AVS output
|
||||
* @returns overlay template name
|
||||
*/
|
||||
QString getOverlayTemplateName() const;
|
||||
|
||||
/**
|
||||
* Convert the given list of participants to their assigned equipment number
|
||||
* @param[in] participants Set of participant ids to get the equipment number for
|
||||
* @returns Converted QSet (if an participantId could not be converted the entry will be empty)
|
||||
*/
|
||||
QSet<int> convertParticipantIdsToEquipmentNo(const QSet<int> &participants) const;
|
||||
|
||||
/**
|
||||
* Returns a comma separated string with equipment numbers for the given list of participantIds/equipment numbers
|
||||
* @param[in] data Set of participant ids or equipment numbers to get the string for
|
||||
* @param[in] isParticipantIds true means data are participantIds otherwise equipment numbers
|
||||
* @returns String with equipment numbers (if an participantId could not be converted the entry will be empty)
|
||||
*/
|
||||
QString getAllEquipmentNumbers(QSet<int> data, bool isParticipantIds) const;
|
||||
|
||||
private: // attributes
|
||||
AvsInterface *m_avsIf; ///< Pointer to AVS-Interface
|
||||
|
||||
std::shared_ptr<HandlerParticipantData> m_handlerParticipantData; ///< Pointer to participant data handler
|
||||
std::shared_ptr<HandlerInfrastructureData> m_handlerInfrastructureData; ///< Pointer to infrastructure data handler
|
||||
int m_exerciseId; ///< Exercise id
|
||||
NGL::INGLLogger &m_logger; ///< Interface to the Logging-Facility
|
||||
|
||||
QMap<int, QSet<int>> m_participantsInRoomMap; ///< Includes all participants (player) in one room (roomId, Set<participantId>)
|
||||
};
|
||||
} // namespace VideoOverlayManagement
|
||||
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* Handler for player data
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2016-07-05
|
||||
*/
|
||||
|
||||
#include "handler_participant_data.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include <QSet>
|
||||
|
||||
using namespace VideoOverlayManagement;
|
||||
|
||||
HandlerParticipantData::HandlerParticipantData(const std::shared_ptr<DdsHandler> &ddsHandler, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_ddsHandler(ddsHandler)
|
||||
, m_logger(getLogger("HandlerParticipantData"))
|
||||
{
|
||||
} // end of ctor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
HandlerParticipantData::~HandlerParticipantData()
|
||||
{
|
||||
} // end of dtor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool HandlerParticipantData::init()
|
||||
{
|
||||
// DTC ParticipantManagement
|
||||
m_dtc = ParticipantManagement::Interface::Dtc::create(m_ddsHandler->dds());
|
||||
if (m_dtc == nullptr)
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Could not create DTC ParticipantManagement";
|
||||
return false;
|
||||
}
|
||||
|
||||
// only subscribe to the topics we're interested in
|
||||
if (!m_dtc->enableParticipant() || !m_dtc->enableParticipantPosition())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "init() DTC ParticipantManagement failed";
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get 'static' data for all participants (playerdata)
|
||||
// Subsribe for ParticipantChanged
|
||||
connect(m_dtc.get(), &ParticipantManagement::Interface::Dtc::participantChanged,
|
||||
this, &HandlerParticipantData::onParticipantChanged);
|
||||
// Player in Referenzmap eintragen
|
||||
m_dtc->participants([this](const ParticipantManagement::Participant &p) { onParticipantChanged(p, DataModification::eAdded);});
|
||||
|
||||
// Get last position ('dynamic' data) of all participants
|
||||
// Subsribe for participantPositionChanged
|
||||
connect(m_dtc.get(), &ParticipantManagement::Interface::Dtc::participantPositionChanged,
|
||||
this, &HandlerParticipantData::onParticipantPositionChanged);
|
||||
// Position in ParticipantsPositionMap eintragen
|
||||
auto cbParticipantPos = [this](const ParticipantManagement::ParticipantPosition &participantPos)
|
||||
{
|
||||
m_participantsPositionMap.insert(participantPos.participantId(), participantPos.roomId());
|
||||
};
|
||||
m_dtc->participantPositions(cbParticipantPos);
|
||||
|
||||
INFO_LOG(m_logger) << "HandlerParticipantData::init() finished. "
|
||||
<< " m_partId2EquipNoMap.size(): " << m_partId2EquipNoMap.size()
|
||||
<< " m_participantsPositionMap.size(): " << m_participantsPositionMap.size();
|
||||
return true;
|
||||
} // end of init()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
int HandlerParticipantData::getEquipmentNumber(int participantId) const
|
||||
{
|
||||
return m_partId2EquipNoMap.value(participantId);
|
||||
} // end of getEquipmentNumber()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
QMap<int, int> HandlerParticipantData::getAllAssignedParticipants() const
|
||||
{
|
||||
QMap<int, int> qMap;
|
||||
for (auto i = m_participantsPositionMap.begin(); i != m_participantsPositionMap.end(); ++i)
|
||||
{
|
||||
if (i.value() > 0)
|
||||
qMap.insert(i.key(), i.value());
|
||||
}
|
||||
return qMap;
|
||||
} // end of getAllAssignedParticipants()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void HandlerParticipantData::onParticipantChanged(const ParticipantManagement::Participant &data, DataModification modType)
|
||||
{
|
||||
INFO_LOG(m_logger) << "onParticipantChanged() participantId:" << data.id();
|
||||
|
||||
if (modType != DataModification::eRemoved && data.equipmentNumber().is_set())
|
||||
m_partId2EquipNoMap.insert(data.id(), data.equipmentNumber().get());
|
||||
else
|
||||
m_partId2EquipNoMap.remove(data.id());
|
||||
|
||||
if (m_logger.isDebugEnabled())
|
||||
{
|
||||
for (auto i = m_partId2EquipNoMap.begin(); i != m_partId2EquipNoMap.end(); ++i)
|
||||
DEBUG_LOG(m_logger) << " partId2EquipNoMap.size(): " << m_partId2EquipNoMap.size()
|
||||
<< " partId: " << i.key()
|
||||
<< " eqNo: " << i.value();
|
||||
}
|
||||
} // end of onParticipantChanged()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void HandlerParticipantData::onParticipantPositionChanged(const ParticipantManagement::ParticipantPosition &data, DataModification modType)
|
||||
{
|
||||
const int newRoomId = data.roomId();
|
||||
// get reference to room (will be created if not exist)
|
||||
int &roomId = m_participantsPositionMap[data.participantId()];
|
||||
// remember old room
|
||||
const int oldRoomId = roomId;
|
||||
// assing new room
|
||||
roomId = modType == DataModification::eRemoved ? 0 : newRoomId;
|
||||
if (newRoomId != oldRoomId)
|
||||
emit participantPositionChanged(oldRoomId, newRoomId, data.participantId());
|
||||
|
||||
INFO_LOG(m_logger) << "onParticipantPositionChanged()"
|
||||
<< " oldRoomId: " << oldRoomId
|
||||
<< " newRoomId: " << newRoomId
|
||||
<< " participantId: " << data.participantId();
|
||||
|
||||
if (modType == DataModification::eRemoved)
|
||||
m_participantsPositionMap.remove(data.participantId());
|
||||
|
||||
} // end of onParticipantPositionChanged()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Handler for player data
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2016-07-05
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "dds_handler.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <ParticipantManagement/ppm_dtc.h>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QMap>
|
||||
|
||||
namespace VideoOverlayManagement
|
||||
{
|
||||
|
||||
class HandlerParticipantData : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit HandlerParticipantData(const std::shared_ptr<DdsHandler> &ddsHandler, QObject *parent = nullptr);
|
||||
|
||||
~HandlerParticipantData();
|
||||
|
||||
/**
|
||||
* Initialize the handler to manage information from player management
|
||||
*/
|
||||
bool init();
|
||||
|
||||
/**
|
||||
* Get equipment number for the given participant
|
||||
* @param participantId participant id to get the equipment number for
|
||||
* @return equipment number or 0 in case of failure
|
||||
*/
|
||||
int getEquipmentNumber(int participantId) const;
|
||||
|
||||
/**
|
||||
* Get all participants which are assigned to a room
|
||||
* @return QMap<participantId, roomId>
|
||||
*/
|
||||
QMap<int, int> getAllAssignedParticipants() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
/**
|
||||
* Signal is emitted when participant position changed (Signal to HandlerOverlay)
|
||||
*/
|
||||
void participantPositionChanged(int oldRoomId, int newRoomId, int participantId);
|
||||
|
||||
private Q_SLOTS:
|
||||
/**
|
||||
* Handle the signals from 'ParticipantManagement'
|
||||
*/
|
||||
void onParticipantChanged(const ParticipantManagement::Participant &data, DataModification modType);
|
||||
void onParticipantPositionChanged(const ParticipantManagement::ParticipantPosition &data, DataModification modType);
|
||||
|
||||
private: // methoden
|
||||
|
||||
private: // attributes
|
||||
std::shared_ptr<DdsHandler> m_ddsHandler; ///< Pointer to VOM DDS handler
|
||||
|
||||
std::shared_ptr<ParticipantManagement::Interface::Dtc> m_dtc; ///< Pointer to DTC ParticipantManagement interface object
|
||||
|
||||
QMap<int, int> m_partId2EquipNoMap; ///< Reference map participant (player) to equipment number (participantId, equipmentNo)
|
||||
QMap<int, int> m_participantsPositionMap; ///< Reference map participant (player) to room id (participantId, roomId)
|
||||
|
||||
NGL::INGLLogger &m_logger; ///< Interface to the Logging-Facility
|
||||
|
||||
};
|
||||
} // namespace VideoOverlayManagement
|
||||
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
log4j.reset=true
|
||||
log4j.rootLogger=WARN, file
|
||||
|
||||
# Service: VideoOverlayManagement
|
||||
###########################################################
|
||||
|
||||
#log4j.logger.VOM=DEBUG
|
||||
#log4j.logger.VOM.main=DEBUG
|
||||
#log4j.logger.VOM.AVS_Interface=DEBUG
|
||||
#log4j.logger.VOM.DdsHandler=DEBUG
|
||||
#log4j.logger.VOM.HandlerInfrastructureData=DEBUG
|
||||
#log4j.logger.VOM.HandlerOverlays=DEBUG
|
||||
#log4j.logger.VOM.HandlerParticipantData=DEBUG
|
||||
#log4j.logger.VOM.MainHandler=DEBUG
|
||||
|
||||
# File
|
||||
###########################################################
|
||||
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:
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Building Config - logging facility
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2016-06-23
|
||||
*/
|
||||
|
||||
#include "logger.h"
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
|
||||
namespace VideoOverlayManagement
|
||||
{
|
||||
|
||||
LOGGER_T getLogger(const char *name)
|
||||
{
|
||||
static const char ns[] = "VOM.";
|
||||
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 VideoOverlayManagement
|
||||
Executable
+23
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Logging for VideoOverlayManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2016-06-23
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
#include "vom_export.h"
|
||||
|
||||
namespace VideoOverlayManagement
|
||||
{
|
||||
using LOGGER_T = NGL::INGLLogger &;
|
||||
|
||||
LOGGER_T getLogger(const char *name);
|
||||
inline LOGGER_T getLogger(const QString &loggerName)
|
||||
{
|
||||
return getLogger(loggerName.toUtf8().constData());
|
||||
}
|
||||
} // namespace VideoOverlayManagement
|
||||
Executable
+53
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Main for VideoOverlayManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2016-06-22
|
||||
*/
|
||||
|
||||
#include <nglapplication/nglcoreapplication.h>
|
||||
#include <LtsCommandLineParser/LtsCommandLineParser.h>
|
||||
#include <QNetworkProxy>
|
||||
|
||||
#include "main_handler.h"
|
||||
#include "logger.h"
|
||||
#include "settings.h"
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
NGLCoreApplication app(argc, argv);
|
||||
QNetworkProxy::setApplicationProxy(QNetworkProxy());
|
||||
|
||||
LtsCommandLineParser::LtsCommandLineParser options;
|
||||
if (!options.init())
|
||||
return -1;
|
||||
app.createLogger("VOM", options.exerciseId());
|
||||
|
||||
if (options.exerciseId() < 0)
|
||||
{
|
||||
fprintf(stdout, "=> exerciseId is required (>=0)");
|
||||
return -2;
|
||||
}
|
||||
|
||||
INFO_LOG(app.baseLogger()) << "*** Start Video Overlay Management Service (VOM)";
|
||||
INFO_LOG(app.baseLogger()) << "### domainId: " << options.domainId() << ", exerciseId: #" << options.exerciseId();
|
||||
|
||||
VideoOverlayManagement::Settings::setIniFile(options.iniFile());
|
||||
int iRet = -1;
|
||||
{
|
||||
std::unique_ptr<VideoOverlayManagement::MainHandler> mainHandler(new VideoOverlayManagement::MainHandler);
|
||||
if (!mainHandler->init(options.domainId(), options.exerciseId()))
|
||||
return iRet;
|
||||
|
||||
STARTUP_LOG(app.baseLogger());
|
||||
|
||||
iRet = app.exec();
|
||||
|
||||
SHUTDOWN_LOG(app.baseLogger());
|
||||
}
|
||||
|
||||
return iRet;
|
||||
} // end of main()
|
||||
//-----------------------------------------------------------------------------
|
||||
+214
@@ -0,0 +1,214 @@
|
||||
/**
|
||||
* MainHandler for VideoOverlayManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2016-06-23
|
||||
*/
|
||||
|
||||
#include "main_handler.h"
|
||||
#include "settings.h"
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
#include <DDS/Core/pacemaker.h>
|
||||
|
||||
using namespace VideoOverlayManagement;
|
||||
|
||||
MainHandler::MainHandler(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_exerciseId(0)
|
||||
, m_avsIf(new AvsInterface(true, this))
|
||||
, m_avsConnectionState(AvsIfConnectionState::Undefined)
|
||||
, m_ddsHandler(nullptr)
|
||||
, m_handlerParticipantData(nullptr)
|
||||
, m_handlerInfrastructureData(nullptr)
|
||||
, m_handlerOverlays(nullptr)
|
||||
, m_checkConnectTimer(new QTimer(this))
|
||||
, m_keepAliveTriggerTimer(new QTimer(this))
|
||||
, m_bAvsSocketWarnedOnce(false)
|
||||
, m_logger(getLogger("MainHandler"))
|
||||
{
|
||||
} // end of ctor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
MainHandler::~MainHandler()
|
||||
{
|
||||
m_ddsHandler.reset();
|
||||
} // end of dtor()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool MainHandler::init(int domainId, int exerciseId)
|
||||
{
|
||||
INFO_LOG(m_logger) << "Start VideoOverlayManagement MainHandler.";
|
||||
|
||||
m_exerciseId = exerciseId;
|
||||
|
||||
// init AVS-Interface
|
||||
QString hostName = Settings::getAvsHostname();
|
||||
quint16 port = Settings::getAvsAvaPort();
|
||||
INFO_LOG(m_logger) << "Init AVS-Interface Hostname/Ip:" << hostName
|
||||
<< " Port: " << port;
|
||||
|
||||
m_avsIf->start(hostName, port);
|
||||
|
||||
connect(m_avsIf, &AvsInterface::avsIfConnectionState,
|
||||
this, &MainHandler::onAvsIfConnectionState);
|
||||
|
||||
connect(m_avsIf, &AvsInterface::avsCmdState,
|
||||
this, &MainHandler::onAvsCmdState);
|
||||
|
||||
connect(m_avsIf, &AvsInterface::avsKeepAliveTimeout,
|
||||
this, &MainHandler::onAvsKeepAliveTimeout);
|
||||
|
||||
connect(m_keepAliveTriggerTimer, &QTimer::timeout,
|
||||
this, &MainHandler::onSendKeepAlive);
|
||||
|
||||
// initialize DDS
|
||||
// for VideoOverlayManagement => exerciseId = partitionId
|
||||
m_ddsHandler.reset(new DdsHandler(domainId, exerciseId));
|
||||
if (!m_ddsHandler->init())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Initialisation DdsHandler failed.";
|
||||
if (m_ddsHandler->pacemaker())
|
||||
m_ddsHandler->pacemaker()->setNewState(Core::RunningState::StartingError);
|
||||
return false;
|
||||
}
|
||||
|
||||
// initialize handlerParticipantData
|
||||
m_handlerParticipantData.reset(new HandlerParticipantData(m_ddsHandler, this));
|
||||
|
||||
if (!m_handlerParticipantData->init())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Initialisation HandlerPlayerData failed.";
|
||||
m_ddsHandler->pacemaker()->setNewState(Core::RunningState::StartingError);
|
||||
return false;
|
||||
}
|
||||
|
||||
// initialize handlerInfraStructureData
|
||||
m_handlerInfrastructureData.reset(new HandlerInfrastructureData(m_ddsHandler, this));
|
||||
|
||||
if (!m_handlerInfrastructureData->init(m_exerciseId))
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Initialisation HandlerInfrastructreData failed.";
|
||||
m_ddsHandler->pacemaker()->setNewState(Core::RunningState::StartingError);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Initialisation of OverlayHandler wait until AVS is connected
|
||||
connect(m_checkConnectTimer, &QTimer::timeout,
|
||||
this, &MainHandler::onTryToInitOverlayHandler);
|
||||
m_checkConnectTimer->start(1000);
|
||||
|
||||
INFO_LOG(m_logger) << "VOM Handler initialized. (Connection to AVS may be still pending) ";
|
||||
m_ddsHandler->pacemaker()->setNewState(Core::RunningState::Starting);
|
||||
|
||||
return true;
|
||||
} // end of init()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool MainHandler::onTryToInitOverlayHandler()
|
||||
{
|
||||
m_avsConnectionState = m_avsIf->getAvsIfState();
|
||||
if (m_avsConnectionState != AvsIfConnectionState::Connected)
|
||||
{
|
||||
if (!m_bAvsSocketWarnedOnce)
|
||||
{
|
||||
m_bAvsSocketWarnedOnce = true;
|
||||
WARNING_LOG(m_logger) << "MainHandler::onTryToInitOverlayHandler()"
|
||||
<< " Wait for AvsIfConnectionState::Connected... ";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
m_bAvsSocketWarnedOnce = true; // reset
|
||||
|
||||
m_checkConnectTimer->stop();
|
||||
|
||||
// initialize handlerOverlays
|
||||
m_handlerOverlays.reset(new HandlerOverlays(m_avsIf, m_handlerParticipantData, m_handlerInfrastructureData, m_exerciseId, this));
|
||||
|
||||
if (!m_handlerOverlays->init())
|
||||
{
|
||||
ERROR_LOG(m_logger) << "Initialisation HandlerOverlays failed.";
|
||||
m_ddsHandler->pacemaker()->setNewState(Core::RunningState::StoppedError);
|
||||
return false;
|
||||
}
|
||||
|
||||
INFO_LOG(m_logger) << "VOM Handler initialized. (Connection to AVS established) ";
|
||||
m_ddsHandler->pacemaker()->setNewState(Core::RunningState::Running);
|
||||
|
||||
return true;
|
||||
} // end of onTryToInitOverlayHandler()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void MainHandler::onAvsIfConnectionState(AvsIfConnectionState state)
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case AvsIfConnectionState::Connected:
|
||||
INFO_LOG(m_logger) << "AvsIfConnectionState::Connected ... start keepAliveTriggerTimer";
|
||||
m_keepAliveTriggerTimer->start(Settings::getAvsKeepAliveTriggerRequestTime());
|
||||
break;
|
||||
case AvsIfConnectionState::Disconnected:
|
||||
m_keepAliveTriggerTimer->stop();
|
||||
break;
|
||||
case AvsIfConnectionState::TryReconnect:
|
||||
m_keepAliveTriggerTimer->stop();
|
||||
break;
|
||||
case AvsIfConnectionState::ConnectionError:
|
||||
ERROR_LOG(m_logger) << "AvsIfConnectionState::ConnectionError !";
|
||||
m_keepAliveTriggerTimer->stop();
|
||||
m_ddsHandler->pacemaker()->setNewState(Core::RunningState::StoppedError);
|
||||
break;
|
||||
case AvsIfConnectionState::Undefined:
|
||||
default:
|
||||
WARNING_LOG(m_logger) << "Undefined AvsIfConnectionState !";
|
||||
break;
|
||||
}
|
||||
} // end of onAvsIfConnectionState()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void MainHandler::onAvsCmdState(AvsCmdState state)
|
||||
{
|
||||
bool bOk = false;
|
||||
switch (state)
|
||||
{
|
||||
case AvsCmdState::Ok:
|
||||
INFO_LOG(m_logger) << "AvsCmdState::Ok";
|
||||
bOk = true;
|
||||
break;
|
||||
case AvsCmdState::BadArguments:
|
||||
WARNING_LOG(m_logger) << "AvsCmdState::BadArguments";
|
||||
break;
|
||||
case AvsCmdState::CommandNotStateValid:
|
||||
WARNING_LOG(m_logger) << "AvsCmdState::CommandNotStateValid";
|
||||
break;
|
||||
case AvsCmdState::KeepAlive:
|
||||
DEBUG_LOG(m_logger) << "AvsCmdState::KeepAlive";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!bOk)
|
||||
{
|
||||
// ToDo: Fehlermeldung an ServiceManagement senden
|
||||
}
|
||||
} // end of onAvsCmdState()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void MainHandler::onAvsKeepAliveTimeout()
|
||||
{
|
||||
// ToDo: Fehlermeldung an ServiceManagement senden
|
||||
WARNING_LOG(m_logger) << "AVS KeepAlive timeout !";
|
||||
} // end of onAvsKeepAliveTimeout()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void MainHandler::onSendKeepAlive()
|
||||
{
|
||||
QString cmd(QLatin1String("KEEPALIVE"));
|
||||
QByteArray qba = cmd.toLatin1();
|
||||
qba += "\r\n";
|
||||
m_avsIf->sendCommand(qba);
|
||||
} // end of onSendKeepAlive()
|
||||
//-----------------------------------------------------------------------------
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* MainHandler for VideoOverlayManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2016-06-23
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include "avs_interface.h"
|
||||
#include "handler_participant_data.h"
|
||||
#include "handler_infrastructure_data.h"
|
||||
#include "handler_overlays.h"
|
||||
#include "dds_handler.h"
|
||||
#include "logger.h"
|
||||
|
||||
class QTimer;
|
||||
|
||||
namespace VideoOverlayManagement
|
||||
{
|
||||
// Forwarddeclarations
|
||||
class AvsInterface;
|
||||
|
||||
class MainHandler
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MainHandler(QObject *parent = nullptr);
|
||||
~MainHandler();
|
||||
|
||||
bool init(int domainId, int exerciseId);
|
||||
|
||||
private Q_SLOTS:
|
||||
/**
|
||||
* Handle signals for AVS Handling
|
||||
*/
|
||||
void onAvsIfConnectionState(AvsIfConnectionState state);
|
||||
void onAvsCmdState(AvsCmdState state);
|
||||
void onAvsKeepAliveTimeout();
|
||||
bool onTryToInitOverlayHandler(); ///< Initialize OverlayHandler after sucessfully AVS connection
|
||||
|
||||
/**
|
||||
* Sends a keep alive request to the server. Normally this method is
|
||||
* called periodically by the KeepAliveTimer.
|
||||
*/
|
||||
void onSendKeepAlive();
|
||||
|
||||
|
||||
private: // attributes
|
||||
int m_exerciseId; ///< Exercise id
|
||||
AvsInterface *m_avsIf; ///< Pointer to AVS-Interface
|
||||
AvsIfConnectionState m_avsConnectionState; ///< AVS connection state
|
||||
std::shared_ptr<DdsHandler> m_ddsHandler; ///< Pointer to DDS handler
|
||||
std::shared_ptr<HandlerParticipantData> m_handlerParticipantData; ///< Pointer to participant data handler
|
||||
std::shared_ptr<HandlerInfrastructureData> m_handlerInfrastructureData; ///< Pointer to infrastructure data handler
|
||||
std::unique_ptr<HandlerOverlays> m_handlerOverlays; ///< Pointer to overlay handler
|
||||
|
||||
QTimer *m_checkConnectTimer; ///< Wait for AVS connected.
|
||||
QTimer *m_keepAliveTriggerTimer; ///< Timer for triggering the keep alive request
|
||||
bool m_bAvsSocketWarnedOnce;
|
||||
|
||||
NGL::INGLLogger &m_logger; ///< Interface to the Logging-Facility
|
||||
|
||||
};
|
||||
} // namespace VideoOverlayManagement
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
* Settings for VideoOverlayManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2016-06-30
|
||||
*/
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
#include <QtCore/QSettings>
|
||||
#include <nglsettings/nglsettings_settings.h>
|
||||
#include <nglsettings/nglsettings_connections.h>
|
||||
#include <ngltools/ngltools_filesystem.h>
|
||||
|
||||
namespace VideoOverlayManagement
|
||||
{
|
||||
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)
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
QString Settings::getAvsHostname()
|
||||
{
|
||||
return NGL::Connections::hostName(NGL::Connections::eConnection::AVS_AVA);
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
quint16 Settings::getAvsAvaPort()
|
||||
{
|
||||
return NGL::Connections::port(NGL::Connections::eConnection::AVS_AVA);
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
quint16 Settings::getAvsKeepAliveTriggerRequestTime()
|
||||
{
|
||||
// Info: AVS schickt alle 20 sec '298 KEEPALIVE' aufgrund eines KEEPALIVE Requesttrigger aus MainHandler!
|
||||
quint16 keepAliveTriggerRequestTime = settings()->settings()->value(QLatin1String("zwav_connection/keepAliveTriggerRequestTime"), 1000 * 20).toUInt();
|
||||
return keepAliveTriggerRequestTime;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
quint16 Settings::getAvsKeepAliveTime()
|
||||
{
|
||||
// Mit dieser Timeoutzeit wird beim Ausbleiben von '298 KEEPALIVE' der Fehlerfall dedektiert.
|
||||
quint16 keepAliveTime = settings()->settings()->value(QLatin1String("zwav_connection/keepAliveTime"), 1000 * 25).toUInt();
|
||||
return keepAliveTime;
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
QString Settings::getOverlayTemplateName()
|
||||
{
|
||||
return QLatin1String("bottomcenter");
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
QString Settings::getContextName()
|
||||
{
|
||||
// ToDo: Nach Umstellung von AVS den 'EXCON' Namen 'ex_' verwenden!
|
||||
return QLatin1String("uebung_");
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
NGL::Settings *Settings::settings()
|
||||
{
|
||||
return s();
|
||||
}
|
||||
//---------------------------------------------------------------------
|
||||
void Settings::setIniFile(const QString &ini)
|
||||
{
|
||||
NGLSettingsClass::setIniFile(ini);
|
||||
}
|
||||
|
||||
} // namespace VideoOverlayManagement
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/**
|
||||
* Settings for VideoOverlayManagement
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2016-06-30
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <QString>
|
||||
|
||||
namespace NGL
|
||||
{
|
||||
class Settings;
|
||||
}
|
||||
|
||||
namespace VideoOverlayManagement
|
||||
{
|
||||
namespace Settings
|
||||
{
|
||||
//!< Get the hostname for AVS
|
||||
QString getAvsHostname();
|
||||
|
||||
//!< Get the port for AVS RCP_AVA
|
||||
quint16 getAvsAvaPort();
|
||||
|
||||
//!< Get AVS keep-alive trigger request time intervall in msec
|
||||
quint16 getAvsKeepAliveTriggerRequestTime();
|
||||
|
||||
//!< Get AVS keep-alive time intervall in msec
|
||||
quint16 getAvsKeepAliveTime();
|
||||
|
||||
//!< Get overlay template name used for AVS textoutput
|
||||
QString getOverlayTemplateName();
|
||||
|
||||
//!< Get context name used for AVS textoutput
|
||||
QString getContextName();
|
||||
|
||||
//!< The real NGL::Settings - object
|
||||
NGL::Settings *settings();
|
||||
void setIniFile(const QString &ini);
|
||||
}
|
||||
|
||||
} // namespace VideoOverlayManagement
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Export definitions
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
* Created by hjl, SLSE, 2016-06-23
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#ifndef VOM_COMMON_EXPORT
|
||||
# ifdef BUILD_STATIC_LIBRARIES
|
||||
# define VOM_COMMON_EXPORT
|
||||
# else
|
||||
# if defined(MAKE_SVCVOMCOMMON_LIB)
|
||||
# define VOM_COMMON_EXPORT Q_DECL_EXPORT
|
||||
# ifndef WIN32
|
||||
# ifdef NDDSUSERDllExport
|
||||
# undef NDDSUSERDllExport
|
||||
# endif
|
||||
# define NDDSUSERDllExport Q_DECL_EXPORT
|
||||
# endif
|
||||
# else
|
||||
# define VOM_COMMON_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef VOM_CLIENT_EXPORT
|
||||
# ifdef BUILD_STATIC_LIBRARIES
|
||||
# define VOM_CLIENT_EXPORT
|
||||
# else
|
||||
# if defined(MAKE_SVCVOMCLIENT_LIB)
|
||||
# define VOM_CLIENT_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define VOM_CLIENT_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef VOM_SERVER_EXPORT
|
||||
# ifdef BUILD_STATIC_LIBRARIES
|
||||
# define VOM_SERVER_EXPORT
|
||||
# else
|
||||
# if defined(MAKE_SVCVOMSERVER_LIB)
|
||||
# define VOM_SERVER_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define VOM_SERVER_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<service namespace="VideoOverlayManagement" procNames="VideoOverlayManagement" abbreviation="VOM" exerciseDependency="Exercise" groups="ExerciseExecution,ExercisePaused,ExerciseAfterActionReview">
|
||||
<rcs>
|
||||
<Id Id="$Id$"/>
|
||||
<HeadURL HeadURL="$HeadURL$"/>
|
||||
<Author Author="$Author$"/>
|
||||
</rcs>
|
||||
<tables/>
|
||||
<dbServiceStructs/>
|
||||
<topicTypes/>
|
||||
<functionTopics/>
|
||||
<enumerations/>
|
||||
</service>
|
||||
Reference in new issue
Block a user