Initial commit

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

No files matched your search

+159
View File
@@ -0,0 +1,159 @@
#
# $Id$
# $HeadURL$
# $Author$
#
INCLUDE(MacroRTIDDSGen)
INCLUDE(MacroCodeGenIdl)
SET(xml_FILE som_service.xml)
#
# --- Library svcSomCommon --------------------------------------------------------------------------------
#
SET(SRCS_common
som_export.h
logger.cpp
logger.h
)
# Generate som_enums.idl / som.idl
CODEGEN_IDL_SVC(SRCS_common ${xml_FILE})
# Generate som_db_impl.cpp/.h, som_db.h
CODEGEN_DATABASE(SRCS_common ${xml_FILE})
# Generate *.cpp/*.hpp from idl
RTIDDSGEN(SRCS_common som_enums.idl)
RTIDDSGEN(SRCS_common som.idl)
# Generate som_dt[s,c]_types.h, som_ft[s,c]_types.h
CODEGEN_TOPIC_TYPEDEFS(SRCS_common ${xml_FILE})
# Generate som_[d|f]tc.h
CODEGEN_CLIENT_TOPICS_IFC(SRCS_common ${xml_FILE})
NGL_ADD_LIBRARY(AAR SV WS svcSomCommon SHARED ${SRCS_common})
NGL_TARGET_INCLUDE_DIRECTORIES(svcSomCommon
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../
${CMAKE_CURRENT_BINARY_DIR}/../
)
NGL_TARGET_LINK_LIBRARIES(svcSomCommon
PRIVATE
RTI::nddscpp2
PUBLIC
Qt5::Core
ddscore
ngldb
NGLLogger
)
NGL_INSTALL_TARGET(svcSomCommon)
#
# --- Library svcSomClient --------------------------------------------------------------------------------
#
SET(SRCS_client
som_export.h
)
# generate som_[d|f]tc.h, som_[d|f]tc_impl.[cpp|h]
CODEGEN_CLIENT_TOPICS_IMPL(SRCS_client ${xml_FILE})
NGL_ADD_LIBRARY(AAR SV WS svcSomClient SHARED ${SRCS_client})
NGL_TARGET_INCLUDE_DIRECTORIES(svcSomClient
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../
${CMAKE_CURRENT_BINARY_DIR}/../
)
NGL_TARGET_LINK_LIBRARIES(svcSomClient
PRIVATE
RTI::nddscpp2
ddsconnector
PUBLIC
svcSomCommon
ddsftc
)
NGL_INSTALL_TARGET(svcSomClient)
#
# --- Library svcSomServer --------------------------------------------------------------------------------
#
SET(SRCS_server
som_export.h
)
# generate som_[d|f]ts.h, som_[d|f]ts_impl.[cpp|h]
CODEGEN_SERVER_TOPICS(SRCS_server ${xml_FILE})
NGL_ADD_LIBRARY(AAR SV svcSomServer SHARED ${SRCS_server})
NGL_TARGET_INCLUDE_DIRECTORIES(svcSomServer
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}/../
${CMAKE_CURRENT_BINARY_DIR}/../
)
NGL_TARGET_LINK_LIBRARIES(svcSomServer
PRIVATE
RTI::nddscpp2
ddsconnector
ddsfts
ngldb
PUBLIC
svcSomCommon
)
NGL_INSTALL_TARGET(svcSomServer)
#
# --- Topic Type Plugin --------------------------------------------------------------
#
CREATE_TOPIC_TYPE_PLUGIN(${xml_FILE})
#
# --- Executable svcSoundManagement (sSOM) -------------------------------------------------
#
SET(SRCS_exe
main.cpp
main_handler.cpp
main_handler.h
dds_handler.cpp
dds_handler.h
handler_sounds.cpp
handler_sounds.h
settings.cpp
settings.h
${xml_FILE}
)
# Generate som.sql, som.xml
CODEGEN_SQL(SRCS_exe ${xml_FILE})
NGL_ADD_EXECUTABLE(AAR SV svcSoundManagement ${SRCS_exe})
NGL_TARGET_LINK_LIBRARIES(svcSoundManagement
Qt5::Core
Qt5::Network
ddsconnector
ddsQoS
svcSomCommon
svcSomServer
svcSomClient
svcIsmClient
ddsconnector
nglsettings
ProjectConfig
LtsCommandLineParser
LtsUtilsCore
LtsCoordTrans
NGLLogger
nglcoreapplication
svcCoreClient
ngltools
ngldb
)
NGL_INSTALL_TARGET(svcSoundManagement)
NGL_INSTALL(AAR SV FILES log4cxx_som.props DESTINATION bin)
NGL_ADD_TARGET_LINK(svcSoundManagement sSOM)
# Uncomment if necessary
#ADD_SUBDIRECTORY(UnitTests)
#ADD_SUBDIRECTORY(ModuleTests)
+79
View File
@@ -0,0 +1,79 @@
/**
* DdsHandler for DDS
* $Id$
* $HeadURL$
* $Author$
* Created by gr, SLSE, 2015-09-02
*/
#include "dds_handler.h"
#include <DDS/DTS/generic_dts_impl.h>
#include <DDS/Core/pacemaker.h>
namespace SoundManagement
{
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(" << m_ddsConnector->getDomainId() << ") 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();
// has to be false, because Snapshot Data Topics can be very large and fragmentation is not supported for batched writers!
m_ddsConnector->enableBatchedWriter(false);
// Pacemaker
m_pacemaker = std::make_shared<Core::Pacemaker>(m_ddsConnector);
m_topicLockMaster = std::make_shared<Core::TopicLockMaster>(m_ddsConnector);
m_dtcCore = Core::Interface::Dtc::create(m_ddsConnector);
m_dtcCore->enablePartitionTime();
m_dtsSom = SoundManagement::Interface::Dts::create(m_ddsConnector);
bool bRet = m_dtsSom->enableAll();
INFO_LOG(m_logger) << "Dts initialised";
m_ftsSom = SoundManagement::Interface::Fts::create(m_ddsConnector);
bRet &= m_ftsSom->enableAll();
INFO_LOG(m_logger) << "Fts initialised";
m_dtcSom = SoundManagement::Interface::Dtc::create(m_ddsConnector);
if (!m_dtcSom->enableAll())
{
ERROR_LOG(m_logger) << "Could not initialize SOM data topics";
return false;
}
m_dtcIsm = InfrastructureManagement::Interface::Dtc::create((m_ddsConnector));
if (!m_dtcIsm->enableMainStructureElement() ||
!m_dtcIsm->enableMountingPointAsset() ||
!m_dtcIsm->enableInstrumentationAsset())
{
ERROR_LOG(m_logger) << "Could not initialize ISM data topics";
return false;
}
return bRet;
} // end of init
//-----------------------------------------------------------------------------
qint64 DdsHandler::currentPartitionTime() const
{
return m_dtcCore->partitionTime().timeStamp();
}
} // Namespace SoundManagement
+66
View File
@@ -0,0 +1,66 @@
/**
* DdsHandler for DDS
* $Id$
* $HeadURL$
* $Author$
* Created by gr, SLSE, 2015-09-02
*/
#pragma once
#include <QObject>
#include <DDS/DDSConnector/dds_connector.h>
#include <DDS/Core/core_dtc.h>
#include <DDS/Core/topic_lock_master.h>
#include <DDS/Core/core_dts_types.h>
#include <SoundManagement/som_dts.h>
#include <SoundManagement/som_dtc.h>
#include <SoundManagement/som_fts.h>
#include <InfrastructureManagement/ism_dtc.h>
#include "logger.h"
namespace Core
{
class Pacemaker;
}
namespace SoundManagement
{
class DdsHandler final : public QObject
{
Q_OBJECT
public:
explicit 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<Core::TopicLockMaster> topicLockMaster() const { return m_topicLockMaster; }
std::shared_ptr<DDSConnector::DdsConnector> dds() const { return m_ddsConnector; }
std::shared_ptr<SoundManagement::Interface::Dts> dtsSom() const { return m_dtsSom;} ///< Pointer to DTS SoundManagement interface object
std::shared_ptr<SoundManagement::Interface::Dtc> dtcSom() const { return m_dtcSom;} ///< Pointer to DTC SoundManagement interface object
std::shared_ptr<SoundManagement::Interface::Fts> ftsSom() const { return m_ftsSom;} ///< Pointer to FTS SoundManagement interface object
std::shared_ptr<InfrastructureManagement::Interface::Dtc> dtcIsm() const { return m_dtcIsm;}
qint64 currentPartitionTime() const;
private:
std::shared_ptr<DDSConnector::DdsConnector> m_ddsConnector;
std::shared_ptr<Core::Interface::Dtc> m_dtcCore;
std::shared_ptr<Core::Pacemaker> m_pacemaker;
std::shared_ptr<Core::TopicLockMaster> m_topicLockMaster;
std::shared_ptr<InfrastructureManagement::Interface::Dtc> m_dtcIsm;
std::shared_ptr<SoundManagement::Interface::Dts> m_dtsSom; ///< Pointer to DTS SoundManagement interface object
std::shared_ptr<SoundManagement::Interface::Dtc> m_dtcSom; ///< Pointer to DTC SoundManagement interface object
std::shared_ptr<SoundManagement::Interface::Fts> m_ftsSom; ///< Pointer to FTS SoundManagement interface object
NGL::INGLLogger &m_logger;
};
}
+804
View File
@@ -0,0 +1,804 @@
/**
* Handler for message data request
* $Id$
* $HeadURL$
* $Author$
* Created by hjl, SLSE, 2016-10-12
*/
#include "handler_sounds.h"
#include "settings.h"
#include "dds_handler.h"
#include <QJsonObject>
#include <QJsonDocument>
#include <QJsonValue>
#include <QSet>
#include <QTimer>
#include <QNetworkReply>
#include <LtsUtilsCore/json_object.h>
namespace SoundManagement
{
HandlerSounds::HandlerSounds(const std::shared_ptr<DdsHandler> &ddsHandler,
const std::shared_ptr<DbHandler> &dbHandler,
QObject *parent)
: QObject(parent)
, GetActiveSoundsRequestHandler(ddsHandler->ftsSom())
, StopAllSoundsRequestHandler(ddsHandler->ftsSom())
, GetSoundsRequestHandler(ddsHandler->ftsSom())
, ControlSoundRequestHandler(ddsHandler->ftsSom())
, m_ddsHandler(ddsHandler)
, m_dbHandler(dbHandler)
, m_logger(getLogger("HandlerSounds"))
{
} // end of ctor()
//-----------------------------------------------------------------------------
bool HandlerSounds::init()
{
SoundManagement::Sounds topicData;
SoundManagement::Sound sound;
INFO_LOG(m_logger) << "HandlerConfigureSounds::init";
auto dtcIsm = m_ddsHandler->dtcIsm();
auto dtcSom = m_ddsHandler->dtcSom();
connect(dtcIsm.get(), &InfrastructureManagement::Interface::Dtc::instrumentationAssetChanged,
this, &HandlerSounds::onInstrumentationAssetChanged);
connect(dtcIsm.get(), &InfrastructureManagement::Interface::Dtc::mountingPointAssetChanged,
this, &HandlerSounds::onMountingPointAssetChanged);
connect(dtcSom.get(), &SoundManagement::Interface::Dtc::soundStateChanged,
this, &HandlerSounds::onSoundStateChanged);
m_updateActiveSoundsTimer->setSingleShot(true);
connect(m_updateActiveSoundsTimer, &QTimer::timeout, this, &HandlerSounds::onTimerTimeout);
// load data from db-table
QVector<Database::SomSound> soundVec;
if (!m_dbHandler->db()->select(soundVec))
{
ERROR_LOG(m_logger) << "Error reading data from database 'som_sound'!";
return false;
}
for (const Database::SomSound &data : qAsConst(soundVec))
{
static int index = 0;
DEBUG_LOG(m_logger) << "SomSound from DB data: id=" << data.id
<< " categoryId=" << data.categoryId
<< " name=" << data.name
<< " displayName=" << data.displayName;
SoundStr soundEntry;
soundEntry.index = data.id;
soundEntry.soundId = data.soundId;
soundEntry.category = static_cast<SoundManagement::SoundCategory>(data.categoryId);
soundEntry.name = data.name;
soundEntry.displayName = data.displayName;
soundEntry.duration = data.duration;
soundEntry.isRepeatable = data.isRepeatable;
m_soundNames.append(soundEntry);
DEBUG_LOG(m_logger) << "id=" << index
<< " SomSound from DB data: id=" << soundEntry.index
<< " categoryId=" << soundEntry.category
<< " name=" << soundEntry.name
<< " displayName=" << soundEntry.displayName;
sound.id(soundEntry.index);
sound.category(soundEntry.category);
sound.soundId(soundEntry.soundId);
sound.name(soundEntry.name.toStdString());
sound.displayName(soundEntry.displayName.toStdString());
sound.duration(soundEntry.duration);
sound.isRepeatable(soundEntry.isRepeatable);
topicData.sounds().push_back(sound);
index++;
}
m_ddsHandler->dtsSom()->publish(topicData);
getActiveSounds();
// Get 'static' data for all MountPointAsset
{
auto cb = [this](const InfrastructureManagement::MountingPointAsset & mpa)
{
onMountingPointAssetChanged(mpa, DataModification::eAdded);
};
if (!dtcIsm->mountingPointAssets(cb))
return false;
}
return true;
} // end init()
void HandlerSounds::getActiveSounds()
{
DEBUG_LOG(m_logger) << "getActiveSounds";
if (m_hostnames.size() == 0)
{
DEBUG_LOG(m_logger) << "No EGCUs available send empty topic ActiveSounds";
m_updateActiveSoundsTimer->stop();
// TODO alle aktiven Sounds vom DDS-Bus loeschen
return;
}
m_updateActiveSoundsTimer->start(2000);
m_activeSounds.clear();
QHashIterator<int, QString> i(m_hostnames);
while (i.hasNext())
{
i.next();
QString hostname = i.value();
DEBUG_LOG(m_logger) << "getActiveSound hostname=" << hostname;
getActiveSound(getAssetId(hostname));
}
}
// get the active sounds from each EGCU
void HandlerSounds::onGetActiveSoundsRequest(const rti::core::SampleIdentity &cookie,
const GetActiveSoundsRequest &request)
{
// 200{ "ID":"0x510","Name":"Sound Report","sounds":[{"category":"Explosions","sound":"0001"}]}
Core::FunctionReplyObject reply = Core::FunctionReplyObject(0, tr_lts("dds", "GetActiveSounds "));
DEBUG_LOG(m_logger) << "onGetActiveSoundsRequest: " << request;
m_ddsHandler->ftsSom()->getActiveSoundsReply(cookie, reply);
// Request each EGCU
// Wait for response from each EGCU
if (!m_updateActiveSoundsTimer->isActive())
getActiveSounds();
}
void HandlerSounds::onStopAllSoundsRequest(const rti::core::SampleIdentity &cookie,
const StopAllSoundsRequest &request)
{
DEBUG_LOG(m_logger) << "StopAllSounds: " << request;
int failedCount = 0;
if (request.egcuId() == -1) // stopp all sounds on each EGCU
{
QHashIterator<int, QString> i(m_hostnames);
while (i.hasNext())
{
i.next();
const QString hostname = m_hostnames.value(i.key());
DEBUG_LOG(m_logger) << "hostname=" << hostname;
if (!stopAllSounds(i.key()).isEmpty()) // BLOCKING
failedCount++;
}
m_soundStates.clear();
}
else
{
QString hostname = m_hostnames.value(request.egcuId());
DEBUG_LOG(m_logger) << "getActiveSound hostname=" << hostname;
if (!stopAllSounds(request.egcuId()).isEmpty()) // BLOCKING
failedCount++;
}
Core::FunctionReplyObject reply = Core::FunctionReplyObject(0);
if (failedCount > 0)
reply = Core::FunctionReplyObject(0, tr_lts("dds", "Failed to stop %1 sounds.")).arg(failedCount);
m_ddsHandler->ftsSom()->stopAllSoundsReply(cookie, reply);
}
void HandlerSounds::onGetSoundsRequest(const rti::core::SampleIdentity &cookie,
const GetSoundsRequest &request)
{
Core::FunctionReplyObject reply = Core::FunctionReplyObject(0, tr_lts("dds", "GetSounds"));
DEBUG_LOG(m_logger) << "GetSounds: " << request;
m_ddsHandler->ftsSom()->getSoundsReply(cookie, reply);
}
QString HandlerSounds::enumToString(const SoundCategory &category)
{
switch (category.underlying())
{
case SoundManagement::SoundCategory::Aircraft:
return QStringLiteral("Aircrafts");
case SoundManagement::SoundCategory::Battlefield:
return QStringLiteral("Battlefields");
case SoundManagement::SoundCategory::Boat:
return QStringLiteral("Boats");
case SoundManagement::SoundCategory::Explosion:
return QStringLiteral("Explosions");
case SoundManagement::SoundCategory::Helicopter:
return QStringLiteral("Helicopter");
case SoundManagement::SoundCategory::MotorsAndUrbanTraffic:
return QStringLiteral("Motors_and_urban_traffic");
case SoundManagement::SoundCategory::Vehicle:
return QStringLiteral("Vehicles");
case SoundManagement::SoundCategory::InsideBuilding:
return QStringLiteral("Inside_buildings");
case SoundManagement::SoundCategory::Unknown:
return QStringLiteral("Unknown");
}
return QStringLiteral("Unknown");
}
SoundManagement::SoundCategory HandlerSounds::stringToEnum(const QString &category)
{
if (category.contains(QStringLiteral("Aircrafts"), Qt::CaseInsensitive))
return SoundManagement::SoundCategory::Aircraft;
if (category.contains(QStringLiteral("Battlefields"), Qt::CaseInsensitive))
return SoundManagement::SoundCategory::Battlefield;
if (category.contains(QStringLiteral("Boats"), Qt::CaseInsensitive))
return SoundManagement::SoundCategory::Boat;
if (category.contains(QStringLiteral("Explosions"), Qt::CaseInsensitive))
return SoundManagement::SoundCategory::Explosion;
if (category.contains(QStringLiteral("Helicopter"), Qt::CaseInsensitive))
return SoundManagement::SoundCategory::Helicopter;
if (category.contains(QStringLiteral("Motors_and_urban_traffic"), Qt::CaseInsensitive))
return SoundManagement::SoundCategory::MotorsAndUrbanTraffic;
if (category.contains(QStringLiteral("Vehicles"), Qt::CaseInsensitive))
return SoundManagement::SoundCategory::Vehicle;
if (category.contains(QStringLiteral("Inside_buildings"), Qt::CaseInsensitive))
return SoundManagement::SoundCategory::InsideBuilding;
if (category.contains(QStringLiteral("Unknown"), Qt::CaseInsensitive))
return SoundManagement::SoundCategory::Unknown;
return SoundManagement::SoundCategory::Unknown;
}
/*
*
* void HandlerMenuStruct::onModifyMenuStructRequest(const rti::core::SampleIdentity &cookie,
const MenuStruct &request)
{
DEBUG_LOG(m_logger) << "onModifyMenuStructRequest: " << request;
auto ret = request.id() > 0 ? modifyMenuStructRequest(request) : createMenuStructRequest(request);
if (ret.error())
WARNING_LOG(m_logger) << ret();
m_fts->modifyMenuStructReply(cookie, ret);
}
Core::FunctionReplyObject HandlerMenuStruct::createMenuStructRequest(const MenuStruct &request)
{
ObjectMenuStruct *ifs = new ObjectMenuStruct(m_dts, m_db);
DEBUG_LOG(m_logger) << "request.menuEntries.size() : " << request.menuEntries().size();
Core::FunctionReplyObject ret = ifs->createFromDds(request);
if (ret.error())
delete ifs;
else
m_objMap.insert(ifs->getId(), ifs);
return ret;
}
*/
void HandlerSounds::onControlSoundRequest(const rti::core::SampleIdentity &cookie,
const ControlSoundRequest &request)
{
DEBUG_LOG(m_logger) << "ControlSound: " << request
<< " category=" << request.category();
const QString user = Settings::somUser();
const QString passwd = Settings::somPasswd();
const QString hostname = m_hostnames.value(request.egcuId());
switch (request.control().underlying())
{
case SoundManagement::PlayControl::StopSound:
{
onStopSingleSound(request.egcuId(), request.category(), request.soundId());
Core::FunctionReplyObject reply = Core::FunctionReplyObject(0);
m_ddsHandler->ftsSom()->controlSoundReply(cookie, reply);
break;
}
case SoundManagement::PlayControl::PlaySingle:
case SoundManagement::PlayControl::PlayLoop: // NOTE: falls through if PlaySingle !
{
const bool loop = (request.control().underlying() == SoundManagement::PlayControl::PlayLoop);
const int durationMs = getDuration(request.category(), request.soundId());
// QTimer::singleShot(1 * 60 * 1000, this, [id, this]() { m_mainHandler->dds()->dtsAlm()->removeNotificationByKey(id); });
const int soundId = request.soundId();
const int egcuId = request.egcuId();
const SoundManagement::SoundCategory category = request.category();
DEBUG_LOG(m_logger) << "Play: durationMs=" << durationMs
<< " egcuId=" << egcuId
<< " soundId=" << soundId
<< " loop=" << loop;
const int control = static_cast<int>(request.control().underlying());
const int volumePercent = static_cast<int>(request.volumePercent());
const QString msg(playBackgroundSound(user, passwd, hostname, enumToString(request.category()), request.soundId(), volumePercent, control)); // => blocking !!
if (!msg.isEmpty())
{
Core::FunctionReplyObject reply = Core::FunctionReplyObject(-1, tr_lts("dds", "Playing sound failed: %1"), { msg.toStdString() });
m_ddsHandler->ftsSom()->controlSoundReply(cookie, reply);
return;
}
if (!loop)
QTimer::singleShot(durationMs, this, [ egcuId, category, soundId, this]() { onStopSingleSound(egcuId, category, soundId); }); // stop sound after n ms (aka. after clip ends)
// Publish on DDS
// insert into m_soundStates
SoundManagement::SoundState soundState;
soundState.egcuId(egcuId);
soundState.soundId(soundId);
soundState.category(request.category());
soundState.id(m_indexActiveSound);
soundState.sampleTime(QDateTime::currentMSecsSinceEpoch());
soundState.inLoop(loop);
DEBUG_LOG(m_logger) << "id=" << m_indexActiveSound
<< " category=" << request.category()
<< " egcuId=" << request.egcuId()
<< " soundId=" << request.soundId()
<< " time=" << soundState.sampleTime();
m_ddsHandler->dtsSom()->publish(soundState);
m_soundStates.append(soundState);
m_indexActiveSound++;
Core::FunctionReplyObject reply = Core::FunctionReplyObject(0);
m_ddsHandler->ftsSom()->controlSoundReply(cookie, reply);
break;
}
case SoundManagement::PlayControl::StopAllSounds:
{
stopAllSounds(request.egcuId());
Core::FunctionReplyObject reply = Core::FunctionReplyObject(0);
m_ddsHandler->ftsSom()->controlSoundReply(cookie, reply);
break;
}
case SoundManagement::PlayControl::GetState:
{
getActiveSound(request.egcuId());
Core::FunctionReplyObject reply = Core::FunctionReplyObject(0);
m_ddsHandler->ftsSom()->controlSoundReply(cookie, reply);
break;
}
}
}
void HandlerSounds::onStopSingleSound(const int egcuId, const SoundManagement::SoundCategory soundCategory, const int soundId)
{
QString user = Settings::somUser();
QString passwd = Settings::somPasswd();
QString host = m_hostnames.value(egcuId);
DEBUG_LOG(m_logger) << "egcuId=" << egcuId
<< " soundId=" << soundId
<< " category=" << enumToString(soundCategory);
// QMutableVectorIterator simplifies and is less errorprone :-)
QMutableVectorIterator<SoundState> it(m_soundStates);
while (it.hasNext())
{
const SoundState &item = it.next();
if ((item.soundId() == soundId) && (item.egcuId() == egcuId) && item.category() == soundCategory)
{
DEBUG_LOG(m_logger) << "remove Sound from DDS-BUS id=" << item.id()
<< " egcuId=" << item.egcuId();
{
// start update request
// http://ubeecu0001/bgsound.php?category=Vehicles&sound=2&control=2
QUrl url;
int control = SoundManagement::PlayControl::StopSound;
QString category = enumToString(soundCategory);
QString request = QStringLiteral("http://%1/bgsound.php?category=%2&sound=%3&control=%4")
.arg(host)
.arg(category)
.arg(soundId)
.arg(control);
url.setUrl(request);
url.setUserName(user);
url.setPassword(passwd);
startRequest(url);
}
m_ddsHandler->dtsSom()->removeSoundStateByKey(item.id());
it.remove();
// combination of soundId and egcuId may occur more than once, do not break the loop
}
} //while
}
QString HandlerSounds::stopAllSounds(const int egcuId)
{
const QString user(Settings::somUser());
const QString passwd(Settings::somPasswd());
const QString host(m_hostnames.value(egcuId));
// http://ubeecu0001/bgsound.php?control=5
// 200{ "ID":"0x510","Name":"Sound Report","sounds":[{"category":"Explosions","sound":"0001"}]}
// 200{ "ID":"0x510","Name":"Sound Report","sounds":[{"category":"Explosions","sound":"0001"},{"category":"Explosions","sound":"0001"}]}
QUrl url;
const int control = SoundManagement::PlayControl::StopAllSounds;
const QString request = QStringLiteral("http://%1/bgsound.php?control=%2")
.arg(host)
.arg(control);
url.setUrl(request);
url.setUserName(user);
url.setPassword(passwd);
const QString msg(startRequestBlocking(url));
if (!msg.isEmpty())
return msg;
QMutableVectorIterator<SoundState> it(m_soundStates);
while (it.hasNext())
{
const SoundState &ss(it.next());
DEBUG_LOG(m_logger) << "Sound EGCU=" << ss.egcuId() << " soundId=" << ss.soundId();
if (ss.egcuId() != egcuId)
continue;
DEBUG_LOG(m_logger) << "remove Sound from DDS-BUS id=" << ss.id()
<< " egcuId=" << ss.egcuId();
m_ddsHandler->dtsSom()->removeSoundStateByKey(ss.id());
it.remove();
}
return {}; // no error
}
void HandlerSounds::getActiveSound(const int egcuId)
{
QString user = Settings::somUser();
QString passwd = Settings::somPasswd();
QString host = m_hostnames.value(egcuId);
// http://ubeecu0001/bgsound.php?control=5
// 200{ "ID":"0x510","Name":"Sound Report","sounds":[{"category":"Explosions","sound":"0001"}]}
// 200{ "ID":"0x510","Name":"Sound Report","sounds":[{"category":"Explosions","sound":"0001"},{"category":"Explosions","sound":"0001"}]}
QUrl url;
int control = SoundManagement::PlayControl::GetState;
QString request = QStringLiteral("http://%1/bgsound.php?control=%2")
.arg(host)
.arg(control);
url.setUrl(request);
url.setUserName(user);
url.setPassword(passwd);
DEBUG_LOG(m_logger) << "startRequest: " << url.toString();
startRequest(url);
}
QString HandlerSounds::playBackgroundSound(const QString &user,
const QString &passwd,
const QString &host,
const QString &category,
const int sound,
const int volume,
const int control)
{
QUrl url;
//http://localhost/bgsound.php?category=Aircrafts&sound=2&control=3&vol=50
QString request = QStringLiteral("http://%1/bgsound.php?category=%2&sound=%3&control=%4&vol=%5")
.arg(host)
.arg(category)
.arg(sound)
.arg(control)
.arg(volume);
url.setUrl(request);
url.setUserName(user);
url.setPassword(passwd);
DEBUG_LOG(m_logger) << "startRequest: " << url.toString()
<< " host=" << host;
return startRequestBlocking(url);
}
QString HandlerSounds::startRequestBlocking(const QUrl &requestedUrl)
{
DEBUG_LOG(m_logger) << "startRequest: " << requestedUrl.toString();
m_httpRequestAborted = false;
auto reply = m_qnam.get(QNetworkRequest(requestedUrl));
await(reply, &QNetworkReply::finished);
return httpFinishedBlocking(reply);
}
void HandlerSounds::startRequest(const QUrl &requestedUrl)
{
DEBUG_LOG(m_logger) << "startRequest: " << requestedUrl.toString();
m_httpRequestAborted = false;
auto reply = m_qnam.get(QNetworkRequest(requestedUrl));
connect(reply, &QNetworkReply::finished, this, &HandlerSounds::httpFinished);
}
QString HandlerSounds::httpFinishedBlocking(QNetworkReply *reply)
{
DEBUG_LOG(m_logger) << "httpFinishedBlocking";
QUrl url;
// auto reply = qobject_cast<QNetworkReply *>(sender());
// Q_ASSERT(reply);
// if (!reply)
// return {};
QNetworkRequest request = reply->request();
url = request.url();
if (m_httpRequestAborted)
{
ERROR_LOG(m_logger) << "httpRequestAborted";
reply->deleteLater();
return QString::fromStdString(tr_lts("dds", "httpRequestAborted"));
}
if (reply->error())
{
QByteArray data = reply->readAll();
QString dataStr = QString::fromStdString(data.toStdString());
ERROR_LOG(m_logger) << "reply->error: " << reply->errorString()
<< " host=" << url.host()
<< " query='" << url.query()
<< "' '" << qUtf8Printable(url.toString()) << "'"
<< " data=" << dataStr;
// Also add unsuccessful feedback
QString query = url.query();
if (query.contains(QStringLiteral("control=5")))
{
DEBUG_LOG(m_logger) << "m_activeSounds.insert host=" << url.host();
m_activeSounds.insert(url.host(), QString());
}
reply->deleteLater();
return reply->errorString();
}
// Sucess
//parse the reply JSON and display result in the UI
const QByteArray json(reply->readAll());
DEBUG_LOG(m_logger) << "Sucess " << json;
QString jsonStr = QString::fromStdString(json.toStdString());
if (jsonStr.contains(QStringLiteral("510"))) // 510 = Sound Report
handleSoundReport(jsonStr, url.host());
reply->deleteLater();
return {};
}
void HandlerSounds::httpFinished()
{
DEBUG_LOG(m_logger) << "httpFinished";
QUrl url;
auto reply = qobject_cast<QNetworkReply *>(sender());
if (!reply)
return;
QNetworkRequest request = reply->request();
url = request.url();
if (m_httpRequestAborted)
{
ERROR_LOG(m_logger) << "httpRequestAborted";
reply->deleteLater();
return;
}
if (reply->error())
{
QByteArray data = reply->readAll();
QString dataStr = QString::fromStdString(data.toStdString());
ERROR_LOG(m_logger) << "reply->error: " << reply->errorString()
<< " host=" << url.host()
<< " query='" << url.query()
<< "' '" << qUtf8Printable(url.toString()) << "'"
<< " data=" << dataStr;
// Also add unsuccessful feedback
QString query = url.query();
if (query.contains(QStringLiteral("control=5")))
{
DEBUG_LOG(m_logger) << "m_activeSounds.insert host=" << url.host();
m_activeSounds.insert(url.host(), QString());
}
reply->deleteLater();
return;
}
// Sucess
//parse the reply JSON and display result in the UI
const QByteArray json(reply->readAll());
DEBUG_LOG(m_logger) << "Sucess " << json;
QString jsonStr = QString::fromStdString(json.toStdString());
if (jsonStr.contains(QStringLiteral("510"))) // 510 = Sound Report
handleSoundReport(jsonStr, url.host());
reply->deleteLater();
}
int HandlerSounds::getAssetId(const QString &hostName)
{
QHashIterator<int, QString> i(m_hostnames);
while (i.hasNext())
{
i.next();
QString name = i.value();
if (name.contains(hostName, Qt::CaseInsensitive))
return i.key();
}
return 0;
}
int HandlerSounds::getSoundIndex(const SoundCategory &category, const QString &name)
{
for (const SoundStr &soundName: qAsConst(m_soundNames))
if ((category == soundName.category) && (name == soundName.name))
return soundName.index;
return -1;
}
int HandlerSounds::getDuration(const SoundManagement::SoundCategory& category,const int soundId)
{
for (const SoundStr &soundName: qAsConst(m_soundNames))
{
if ( soundId == soundName.soundId
&& category == soundName.category)
{
DEBUG_LOG(m_logger) << "Duration=" << soundName.duration << "ms";
return soundName.duration;
}
} // for
return -1;
}
void HandlerSounds::handleSoundReport(const QString &json, const QString &host)
{
SoundManagement::SoundState soundState;
QString jsonString;
QString jsonStr = QString::fromStdString(json.toStdString());
DEBUG_LOG(m_logger) << "remove 200";
jsonString = jsonStr.remove(QStringLiteral("200"));
m_activeSounds.insert(host, jsonString);
// Send Result Topic
DEBUG_LOG(m_logger) << "Send Result Topic";
DEBUG_LOG(m_logger) << "m_updateActiveSoundsTimer->stop();";
DEBUG_LOG(m_logger) << "host=" << host
<< " jsonString= " << jsonString;
// decode JSON-Object
QJsonDocument doc = QJsonDocument::fromJson(jsonString.toUtf8());
QJsonObject jsonObject;
// check validity of the document
if (!doc.isNull())
{
if (doc.isObject())
{
jsonObject = doc.object();
const QJsonArray &sounds = jsonObject[QStringLiteral("sounds")].toArray();
// TODO Pruefen, ob in der lokalen Verwaltung noch Sounds sind, die geloescht und vom DDS-Bus genommen
// werden muessen.
for (const QJsonValue &valSound : qAsConst(sounds))
{
const QJsonObject &sound = valSound.toObject();
bool found = false;
QString categoryStr = sound.value(QStringLiteral("category")).toString();
QString name = sound.value(QStringLiteral("sound")).toString();
int egcuId = getAssetId(host);
SoundManagement::SoundCategory category = stringToEnum(categoryStr);
int soundId = getSoundIndex(category, name);
soundState.egcuId(egcuId);
soundState.soundId(soundId);
soundState.category(category);
soundState.id(m_indexActiveSound);
soundState.sampleTime(QDateTime::currentMSecsSinceEpoch());
DEBUG_LOG(m_logger) << "id=" << m_indexActiveSound
<< " category=" << categoryStr
<< " name=" << name
<< " egcuId=" << egcuId
<< " soundId=" << soundId
<< " time=" << soundState.sampleTime();
for (const SoundManagement::SoundState& item : qAsConst(m_soundStates))
{
if ( (item.egcuId() == soundState.egcuId()) &&
(item.category() == soundState.category()) &&
(item.soundId() == soundState.soundId()) )
{
DEBUG_LOG(m_logger) << "Sound is already on DDS-Bus";
found = true;
break;
}
} // for
if (!found)
{
m_indexActiveSound++;
DEBUG_LOG(m_logger) << "Sound publish";
m_ddsHandler->dtsSom()->publish(soundState);
m_soundStates.append(soundState);
}
}
}
else
ERROR_LOG(m_logger) << "Document is not an object";
}
else
{
if (jsonStr.size() == 0)
DEBUG_LOG(m_logger) << "No Sounds for " << host;
else
ERROR_LOG(m_logger) << "Invalid JSON...\n" << jsonStr;
}
m_updateActiveSoundsTimer->stop();
}
void HandlerSounds::onTimerTimeout()
{
ERROR_LOG(m_logger) << "Problem when querying the active sounds from the EGCU's";
}
void HandlerSounds::onInstrumentationAssetChanged(const InfrastructureManagement::InstrumentationAsset &data, DataModification modType)
{
if (modType != DataModification::eAdded &&
modType != DataModification::eModified)
return;
DEBUG_LOG(m_logger) << "onInstrumentationAssetChanged id=" << data.id()
<< " hostname=" << QString::fromStdString(data.hostname())
<< " mountingPointTypeId=" << data.mountingPointTypeId()
<< " assetStateId=" << data.assetStateId();
if ((data.mountingPointTypeId() == InfrastructureManagement::MountingPointType::EffectGenerationControlUnit)
&& data.assetStateId() == InfrastructureManagement::InstrumentationAssetState::Mounted
&& data.hostname().size() > 0)
{
QString hostname = QString::fromStdString(data.hostname());
DEBUG_LOG(m_logger) << "m_hostnames.insert id=" << data.id()
<< " hostname=" << hostname
<< " hostname.size=" << hostname.size()
<< " mountingPointTypeId=" << data.mountingPointTypeId()
<< " assetStateId=" << data.assetStateId();
if (hostname.size() > 0 )
{
DEBUG_LOG(m_logger) << "insert EGCU in m_hostnames " << data.hostname();
m_hostnames.insert(data.id(), QString::fromStdString(data.hostname()));
}
}
}
void HandlerSounds::onMountingPointAssetChanged(const InfrastructureManagement::MountingPointAsset &data, DataModification modType)
{
if (modType != DataModification::eAdded &&
modType != DataModification::eModified)
return;
DEBUG_LOG(m_logger) << "onMountingPointAssetChanged"
<< " id= " << data.id()
<< " assetId= " << data.assetId()
<< " structureElementId= " << data.structureElementId();
m_mountingPointAsset.insert(data.structureElementId(),data.assetId());
}
void HandlerSounds::onSoundStateChanged(const SoundManagement::SoundState &data, DataModification modType)
{
DEBUG_LOG(m_logger) << "onSoundStateChanged"
<< " id= " << data.id()
<< " egcuId= " << data.egcuId()
<< " soundId=" << data.soundId()
<< " modType=" << modType;
if (modType != DataModification::eAdded &&
modType != DataModification::eModified)
return;
}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
} // namespace SoundManagement
+137
View File
@@ -0,0 +1,137 @@
/**
* Handler for table-io message data request
* $Id$
* $HeadURL$
* $Author$
* Created by hjl, SLSE, 2016-10-12
*/
#pragma once
#include <QObject>
#include "dds_handler.h"
#include "logger.h"
#include <som_db.h>
#include <ngldb/db_service_handler.h>
#include "main_handler.h"
#include <SoundManagement/som_fts.h>
#include <SoundManagement/som_dts.h>
#include <InfrastructureManagement/ism_dtc.h>
#include <LtsCoordTrans/lts_coord_trans.h>
// HTTP Request
#include <QNetworkAccessManager>
#include <QTimer>
#include <QEventLoop>
namespace SoundManagement
{
template <typename Func1>
void await(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal)
{
QEventLoop x;
QObject::connect(sender, signal, &x, &QEventLoop::quit);
x.exec();
}
using DbHandler = NGLDB::DbServiceHandler<DatabaseInterface>;
inline QPointF geographic2Utm(const Core::GeoPosition2D &geoPos, int *zone = nullptr)
{
const int zoneToUse = zone ? *zone : -1;
auto utm = LtsCoordTrans::UtmCoordinate::fromGeographic(geoPos.lon(), geoPos.lat(), zoneToUse);
if (zone)
*zone = utm.zone;
return {utm.x, utm.y};
}
class HandlerSounds final
: public QObject
, protected Interface::Fts::GetActiveSoundsRequestHandler
, protected Interface::Fts::StopAllSoundsRequestHandler
, protected Interface::Fts::GetSoundsRequestHandler
, protected Interface::Fts::ControlSoundRequestHandler
{
Q_OBJECT
public:
explicit HandlerSounds(const std::shared_ptr<DdsHandler> &ddsHandler,
const std::shared_ptr<DbHandler> &dbHandler,
QObject *parent = nullptr);
~HandlerSounds() = default;
bool init();
private Q_SLOTS:
void onInstrumentationAssetChanged(const InfrastructureManagement::InstrumentationAsset &data, DataModification modType);
void onMountingPointAssetChanged(const InfrastructureManagement::MountingPointAsset &data, DataModification modType);
void onSoundStateChanged(const SoundManagement::SoundState &data, DataModification modType);
void httpFinished();
void onStopSingleSound(const int egcuId, const SoundManagement::SoundCategory soundCategory, const int soundId);
private: // methods
QString httpFinishedBlocking(QNetworkReply *reply);
void onGetActiveSoundsRequest(const rti::core::SampleIdentity &cookie,
const GetActiveSoundsRequest &request) override;
void onStopAllSoundsRequest(const rti::core::SampleIdentity &cookie,
const StopAllSoundsRequest &request) override;
void onGetSoundsRequest(const rti::core::SampleIdentity &cookie,
const GetSoundsRequest &request) override;
void onControlSoundRequest(const rti::core::SampleIdentity &cookie,
const ControlSoundRequest &request) override;
void onTimerTimeout();
QString stopAllSounds(const int egcuId); // BLOCKING!
void getActiveSounds();
void getActiveSound(const int egcuId);
QString playBackgroundSound(const QString &user,
const QString &passwd,
const QString &host,
const QString &category,
const int sound,
const int volume,
const int control);
void startRequest(const QUrl &requestedUrl);
QString startRequestBlocking(const QUrl &requestedUrl);
QString enumToString(const SoundManagement::SoundCategory &category);
SoundManagement::SoundCategory stringToEnum(const QString &category);
void handleSoundReport(const QString &json, const QString &host);
int getAssetId(const QString &hostName);
int getDuration(const SoundCategory &category, const int soundId);
int getSoundIndex(const SoundCategory &category, const QString &name);
private: // attributes
struct SoundStr
{
int index = 0;
int soundId = 0;
SoundManagement::SoundCategory category = SoundManagement::SoundCategory::Unknown;
QString name = QString();
QString displayName = QString();
int duration = 0;
bool isRepeatable = false;
};
std::shared_ptr<DdsHandler> m_ddsHandler; ///< Pointer to DDS handler
std::shared_ptr<DbHandler> m_dbHandler; ///< Pointer to DB handler
QHash<int, QString> m_hostnames; // key = assetId, value = hostname
QHash<QString, QString> m_activeSounds; // key = hostname
QNetworkAccessManager m_qnam;
QTimer *m_updateActiveSoundsTimer{new QTimer(this)};
bool m_httpRequestAborted{false};
QVector<SoundStr> m_soundNames{QVector<SoundStr>()};
int m_indexActiveSound{0};
QVector<SoundState> m_soundStates{QVector<SoundManagement::SoundState>()};
int m_topicId{0};
QHash <int, int> m_mountingPointAsset; // Key= structureElementId, value= assetId
NGL::INGLLogger &m_logger;
};
} // namespace SoundManagement
+90
View File
@@ -0,0 +1,90 @@
log4j.reset=true
log4j.rootLogger=WARN, file
# Service: SoundManagement
###########################################################
#log4j.logger.SOM=WARN
#log4j.logger.SOM.main=DEBUG
#log4j.logger.SOM.DdsHandler=DEBUG
#log4j.logger.SOM.MainHandler=DEBUG
#log4j.logger.SOM.HandlerSounds=DEBUG
### LineOfSightCalculation
# Service: SituationMap
###########################################################
log4j.logger.SituationMap.LineOfSightCalculation=WARN
#
# Lts::RollingFileAppender
log4j.appender.file=Lts::RollingFileAppender
log4j.appender.file.MaxFileSize=1MB
log4j.appender.file.MaxBackupIndex=9
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d %-5p %c |#| %m (%.50F:%L) %n
# Appnd_Console
###########################################################
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern= %d %p %c %c{1} - %m (%-.30F:%L) %n
# Appnd_Syslog
###########################################################
log4j.appender.syslog=org.apache.log4j.SyslogAppender
log4j.appender.syslog.Threshold=ERROR
log4j.appender.syslog.SysLogHost=localhost
log4j.appender.syslog.Facility=LOCAL7
log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
log4j.appender.syslog.layout.ConversionPattern= %-4r %-5p %c %x - %m
log4j.appender.syslog.LevelRangeFilter.AcceptOnMatch=true
log4j.appender.syslog.LevelRangeFilter.LevelMin=INFO
log4j.appender.syslog.LevelRangeFilter.LevelMax=FATAL
###########################################################
###########################################################
###########################################################
# 1) Available Levels in LOG4CXX Version 0.10.0:
# TRACE,
# DEBUG,
# INFO,
# WARN,
# ERROR
# FATAL
#
# d = date/time
# p = priority (Level)
# c = category/channel
# m = message
# F = file
# L = line
# n = platform dependent line separator character or characters.
# ....
#
# Examples for console:
# a)
# %d %p %c #%m# (%.50F:%L)%n
# date/time
# priority
# category/channel
# #message#
# (Maximal 50Character des Filename von rechts:Line)
# line separator
#
# b)
# %d (%.15F:%L) %-5p %c |#| %m%n
# date/time
# (Maximal 15Character des Filename von rechts:Line)
# priority, Right pad with spaces if the priority name is less than 5 characters long.
# category/channel
# message
# line separator
#
# Examples for files:
+37
View File
@@ -0,0 +1,37 @@
/**
* @RDE_HEADER@
* Building Config - logging facility
* $Id$
* $HeadURL$
* $Author$
*/
#include "logger.h"
#include <NGLLogger/NGLLoggerBootstrap.h>
namespace SoundManagement
{
LOGGER_T getLogger(const char *name)
{
static const char ns[] = "SOM.";
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 SoundManagement
+23
View File
@@ -0,0 +1,23 @@
/**
* @RDE_HEADER@
* Logging for SoundManagement
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <NGLLogger/INGLLogger.h>
#include "som_export.h"
namespace SoundManagement
{
using LOGGER_T = NGL::INGLLogger &;
SOM_COMMON_EXPORT LOGGER_T getLogger(const char *name);
inline LOGGER_T getLogger(const QString &loggerName)
{
return getLogger(loggerName.toUtf8().constData());
}
} // namespace SoundManagement
+42
View File
@@ -0,0 +1,42 @@
/**
* @RDE_HEADER@
* main for SoundManagement
* $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("SOM", options.exerciseId());
SoundManagement::Settings::setIniFile(options.iniFile());
int iRet = -3;
{
std::unique_ptr<SoundManagement::MainHandler> mainHandler(new SoundManagement::MainHandler);
if (!mainHandler->init(options.domainId(), options.exerciseId()))
return iRet;
STARTUP_LOG(app.baseLogger());
iRet = app.exec();
SHUTDOWN_LOG(app.baseLogger());
}
return iRet;
}
+80
View File
@@ -0,0 +1,80 @@
/**
* MainHandler for AssetManagement
* $Id$
* $HeadURL$
* $Author$
*/
#include "main_handler.h"
#include <DDS/DDSConnector/dds_connector.h>
#include <DDS/Core/pacemaker.h>
#include <ngldb/db_service_handler.h>
#include "som_db.h"
#include "settings.h"
#include <QFileInfo>
namespace SoundManagement
{
MainHandler::MainHandler(QObject *parent)
: QObject(parent)
, m_ddsHandler(nullptr)
, m_dbHandler(nullptr)
, m_logger(getLogger("MainHandler"))
{}
MainHandler::~MainHandler()
{
m_handlerSounds.reset();
m_ddsHandler.reset();
m_dbHandler = nullptr;
}
bool MainHandler::init(int domainId, int exerciseId)
{
INFO_LOG(m_logger) << "MainHandler::init";
// initialize database
m_dbHandler = std::make_shared<DbHandler>();
if (!m_dbHandler->init(0, 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.";
NOTICE_LOG(m_logger) << "setNewState Core::RunningState::Starting ";
m_ddsHandler->pacemaker()->setNewState(Core::RunningState::Starting);
// initialize handlerSounds
m_handlerSounds = std::make_shared<HandlerSounds>(m_ddsHandler,
m_dbHandler, this);
if (!m_handlerSounds->init())
{
ERROR_LOG(m_logger) << "Initialisation HandlerSounds failed.";
m_ddsHandler->pacemaker()->setNewState(Core::RunningState::StartingError);
return false;
}
NOTICE_LOG(m_logger) << "setNewState Core::RunningState::Running ";
m_ddsHandler->pacemaker()->setNewState(Core::RunningState::Running);
return true;
}
} // namespace SoundManagement
+50
View File
@@ -0,0 +1,50 @@
/**
* MainHandler for AereaEffectSimulation
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <QObject>
#include "dds_handler.h"
#include "handler_sounds.h"
#include "logger.h"
#include <ngldb/db_service_handler.h>
namespace NGLDB
{
template <typename DB> class DbServiceHandler;
}
namespace SoundManagement
{
using DbHandler = NGLDB::DbServiceHandler<DatabaseInterface>;
class HandlerSounds;
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<HandlerSounds> handlerSounds() const { return m_handlerSounds; }
private:
std::shared_ptr<DdsHandler> m_ddsHandler;
std::shared_ptr<DbHandler> m_dbHandler;
std::shared_ptr<HandlerSounds> m_handlerSounds;
NGL::INGLLogger &m_logger;
};
} // namespace SoundManagement
+52
View File
@@ -0,0 +1,52 @@
/**
* Settings for TargetManagement
* $Id$
* $HeadURL$
* $Author$
*/
#include "settings.h"
#include <QtCore/QSettings>
#include <nglsettings/nglsettings_settings.h>
#include <ngltools/ngltools_filesystem.h>
namespace SoundManagement
{
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);
}
QString Settings::somUser()
{
return s()->settings()->value(QStringLiteral("SOM/user"), QStringLiteral("katar")).toString();
}
QString Settings::somPasswd()
{
return s()->settings()->value(QStringLiteral("SOM/passwd"), QStringLiteral("mout11de")).toString();
}
} // namespace SoundManagement
+27
View File
@@ -0,0 +1,27 @@
/**
* Settings for TargetManagement
* $Id$
* $HeadURL$
* $Author$
*/
#pragma once
#include <QString>
namespace NGL
{
class Settings;
}
namespace SoundManagement
{
namespace Settings
{
NGL::Settings *settings();
void setIniFile(const QString &ini);
QString somUser();
QString somPasswd();
}
} // namespace SoundManagement
+52
View File
@@ -0,0 +1,52 @@
/**
* Export definitions
* $Id$
* $HeadURL$
* $Author$
* Created by Hanna E. Rathje, SLSE, 2015-08-04
*/
#pragma once
#include <QtCore/qglobal.h>
#ifndef SOM_COMMON_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define SOM_COMMON_EXPORT
# else
# if defined(MAKE_SVCSOMCOMMON_LIB)
# define SOM_COMMON_EXPORT Q_DECL_EXPORT
# ifndef WIN32
# ifdef NDDSUSERDllExport
# undef NDDSUSERDllExport
# endif
# define NDDSUSERDllExport Q_DECL_EXPORT
# endif
# else
# define SOM_COMMON_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
#ifndef SOM_CLIENT_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define SOM_CLIENT_EXPORT
# else
# if defined(MAKE_SVCSOMCLIENT_LIB)
# define SOM_CLIENT_EXPORT Q_DECL_EXPORT
# else
# define SOM_CLIENT_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
#ifndef SOM_SERVER_EXPORT
# ifdef BUILD_STATIC_LIBRARIES
# define SOM_SERVER_EXPORT
# else
# if defined(MAKE_SVCSOMSERVER_LIB)
# define SOM_SERVER_EXPORT Q_DECL_EXPORT
# else
# define SOM_SERVER_EXPORT Q_DECL_IMPORT
# endif
# endif
#endif
+124
View File
@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<service namespace="SoundManagement" abbreviation="SOM" procNames="SoundManagement" exerciseDependency="Global" groups="Core">
<rcs>
<Id Id="$Id: ea_export_script.txt 41311 2018-04-23 09:43:45Z ehrlicher $"/>
<HeadURL HeadURL="$HeadURL: svn://slssvn/TDS/branches/product/devel/trunk/Lts/Common/CodeGen/ea_export_script.txt $"/>
<Author Author="$Author: ehrlicher $"/>
</rcs>
<operatorRights offset="52">
<guiPlugin name="SoundManagement" offset="1">
<operatorRightGroup name="Sound Management (Global)" description="Sound Management">
<operatorRight right="StartSoundDialog" value="1" description="Configure Sounds"/>
</operatorRightGroup>
</guiPlugin>
</operatorRights>
<tables>
<table name="som_device_type" comment="static data (&lt;b&gt;not&lt;/b&gt; project specific) generate from enum">
<column name="id" datatype="integer" isPrimaryKey="1">
<sequence start="1" increment="1"/>
</column>
<column name="name" datatype="text"/>
</table>
<table name="som_sound">
<column name="id" datatype="integer" isPrimaryKey="1">
<sequence start="1" increment="1"/>
</column>
<column name="category_id" datatype="integer" isForeignKey="1"/>
<column name="sound_id" datatype="integer"/>
<column name="name" datatype="text"/>
<column name="display_name" datatype="text"/>
<column name="duration" datatype="integer" comment="[ms]"/>
<column name="is_repeatable" datatype="boolean"/>
<foreignKey name="FK_som_sound_som_sound_category" referential_integrity="DeleteCascade">
<source table="som_sound" column="category_id"/>
<destination table="som_sound_category" column="id"/>
</foreignKey>
</table>
<table name="som_sound_category" comment="static data (&lt;b&gt;not&lt;/b&gt; project specific) generate from enum">
<column name="id" datatype="integer" isPrimaryKey="1">
<sequence start="1" increment="1"/>
</column>
<column name="name" datatype="text"/>
</table>
<table name="som_sound_type" comment="static data (&lt;b&gt;not&lt;/b&gt; project specific) generate from enum">
<column name="id" datatype="integer" isPrimaryKey="1">
<sequence start="1" increment="1"/>
</column>
<column name="name" datatype="text"/>
</table>
</tables>
<views/>
<dbServiceStructs>
<serviceStruct name="SomSound" table="som_sound"/>
<table name="som_sound"/>
</dbServiceStructs>
<topicTypes>
<topicType name="ControlSoundRequest">
<column name="egcuId" idlType="long"/>
<column name="soundId" idlType="long"/>
<column name="category" idlType="SoundCategory"/>
<column name="volumePercent" idlType="long"/>
<column name="control" idlType="PlayControl"/>
</topicType>
<topicType name="GetActiveSoundsRequest">
<column name="dummy" idlType="long"/>
</topicType>
<topicType name="GetSoundsRequest">
<column name="dummy" idlType="long"/>
</topicType>
<topicType name="Sound">
<column name="id" idlType="long"/>
<column name="name" idlType="string"/>
<column name="displayName" idlType="string"/>
<column name="category" idlType="SoundCategory"/>
<column name="soundId" idlType="long"/>
<column name="duration" idlType="long" comment="[ms]"/>
<column name="isRepeatable" idlType="boolean"/>
</topicType>
<topicType name="Sounds" isDataObject="1" autosubscribe="1" routeToClient="1" routeToServer="0" routeInReplay="0">
<column name="sounds" idlType="sequence&lt;Sound&gt;"/>
</topicType>
<topicType name="SoundState" isDataObject="1" autosubscribe="1" routeToClient="1" routeToServer="0" routeInReplay="0" recordTopic="1">
<column name="id" idlType="long" isKey="1"/>
<column name="soundId" idlType="long"/>
<column name="egcuId" idlType="long"/>
<column name="category" idlType="SoundCategory"/>
<column name="sampleTime" idlType="long long"/>
<column name="inLoop" idlType="boolean"/>
</topicType>
<topicType name="StopAllSoundsRequest">
<column name="egcuId" idlType="long" comment="if egcuId=-1 stopp all Sounds on each EGCU (EffectGenerationControlUnit)"/>
</topicType>
</topicTypes>
<functionTopics>
<functionTopic name="ControlSound" requestTopicType="ControlSoundRequest" replyTopicType="Core::FunctionReply" requestTopicName="ControlSoundRequest" replyTopicName="ControlSoundReply" routeInReplay="0"/>
<functionTopic name="GetActiveSounds" requestTopicType="GetActiveSoundsRequest" replyTopicType="Core::FunctionReply" requestTopicName="GetActiveSoundsRequest" replyTopicName="GetActiveSoundsReply" routeInReplay="0"/>
<functionTopic name="GetSounds" requestTopicType="GetSoundsRequest" replyTopicType="Core::FunctionReply" requestTopicName="GetSoundsRequest" replyTopicName="GetSoundsReply" routeInReplay="0"/>
<functionTopic name="StopAllSounds" requestTopicType="StopAllSoundsRequest" replyTopicType="Core::FunctionReply" requestTopicName="StopAllSoundsRequest" replyTopicName="StopAllSoundsReply" routeInReplay="0"/>
</functionTopics>
<enumerations>
<enumeration name="PlayControl">
<attribute key="PlaySingle" value="1"/>
<attribute key="StopSound" value="2"/>
<attribute key="PlayLoop" value="3"/>
<attribute key="StopAllSounds" value="4"/>
<attribute key="GetState" value="5"/>
</enumeration>
<enumeration name="SoundCategory" table="som_sound_category">
<attribute key="Aircraft" value="1"/>
<attribute key="Battlefield" value="2"/>
<attribute key="Boat" value="3"/>
<attribute key="Explosion" value="4"/>
<attribute key="Helicopter" value="5"/>
<attribute key="MotorsAndUrbanTraffic" value="6"/>
<attribute key="Vehicle" value="7"/>
<attribute key="InsideBuilding" value="8"/>
<attribute key="Unknown" value="9"/>
</enumeration>
<enumeration name="SoundType" table="som_sound_type">
<attribute key="OneTimeSound" value="1"/>
<attribute key="OneTimeSoundNotParallel" value="2"/>
<attribute key="LoopSounds" value="3"/>
</enumeration>
</enumerations>
</service>