Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
Executable
+41
@@ -0,0 +1,41 @@
|
||||
#
|
||||
# $Id$
|
||||
# $HeadURL$
|
||||
# $Author$
|
||||
#
|
||||
# CMakeLists.txt fuer topicdiscover
|
||||
#
|
||||
|
||||
SET(topicdiscover_SRCS
|
||||
topic_discoverer.cpp
|
||||
topic_discoverer.h
|
||||
)
|
||||
|
||||
NGL_ADD_LIBRARY(AAR SV WS NO_TRANSLATION topicdiscover SHARED ${topicdiscover_SRCS})
|
||||
NGL_TARGET_INCLUDE_DIRECTORIES(topicdiscover
|
||||
INTERFACE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../
|
||||
)
|
||||
NGL_TARGET_LINK_LIBRARIES(topicdiscover
|
||||
PRIVATE
|
||||
ddsQoS
|
||||
NGLLogger
|
||||
RTI::nddsc
|
||||
RTI::nddscore
|
||||
PUBLIC
|
||||
Qt5::Core
|
||||
RTI::nddscpp2
|
||||
ddsQoS
|
||||
)
|
||||
|
||||
NGL_INSTALL_TARGET(topicdiscover)
|
||||
|
||||
##################
|
||||
|
||||
NGL_ADD_EXECUTABLE(topicdiscoverexe AAR SV WS main.cpp)
|
||||
|
||||
NGL_TARGET_LINK_LIBRARIES(topicdiscoverexe
|
||||
LtsCommandLineParser
|
||||
nglcoreapplication
|
||||
topicdiscover
|
||||
)
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
log4j.reset=true
|
||||
log4j.rootLogger=WARN, file
|
||||
|
||||
# TopicDiscoverer
|
||||
###########################################################
|
||||
|
||||
log4j.logger.TopicDiscoverer=INFO
|
||||
log4j.logger.TopicDiscoverer.BuiltinSubscriberListener=INFO
|
||||
log4j.logger.TopicDiscoverer.BuiltinParticipantListener=INFO
|
||||
|
||||
log4j.appender.file=org.apache.log4j.RollingFileAppender
|
||||
log4j.appender.file.MaxFileSize=1MB
|
||||
log4j.appender.file.MaxBackupIndex=9
|
||||
log4j.appender.file.file=${LOG4QT_LOGDIR}/${LOG4QT_USER}_topicDiscoverer.log
|
||||
log4j.appender.file.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.file.layout.ConversionPattern=%d %-5p %c |#| %m (%.50F:%L) %n
|
||||
|
||||
|
||||
# Appnd_Console
|
||||
###########################################################
|
||||
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern= %d %p %c %c{1} - %m (%-.30F:%L) %n
|
||||
|
||||
|
||||
# Appnd_Syslog
|
||||
###########################################################
|
||||
log4j.appender.syslog=org.apache.log4j.SyslogAppender
|
||||
log4j.appender.syslog.Threshold=ERROR
|
||||
log4j.appender.syslog.SysLogHost=localhost
|
||||
log4j.appender.syslog.Facility=LOCAL7
|
||||
log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
|
||||
log4j.appender.syslog.layout.ConversionPattern= %-4r %-5p %c %x - %m
|
||||
log4j.appender.syslog.LevelRangeFilter.AcceptOnMatch=true
|
||||
log4j.appender.syslog.LevelRangeFilter.LevelMin=INFO
|
||||
log4j.appender.syslog.LevelRangeFilter.LevelMax=FATAL
|
||||
|
||||
|
||||
###########################################################
|
||||
###########################################################
|
||||
###########################################################
|
||||
# 1) Available Levels in LOG4CXX Version 0.10.0:
|
||||
# TRACE,
|
||||
# DEBUG,
|
||||
# INFO,
|
||||
# WARN,
|
||||
# ERROR
|
||||
# FATAL
|
||||
#
|
||||
# d = date/time
|
||||
# p = priority (Level)
|
||||
# c = category/channel
|
||||
# m = message
|
||||
# F = file
|
||||
# L = line
|
||||
# n = platform dependent line separator character or characters.
|
||||
# ....
|
||||
#
|
||||
# Examples for console:
|
||||
# a)
|
||||
# %d %p %c #%m# (%.50F:%L)%n
|
||||
# date/time
|
||||
# priority
|
||||
# category/channel
|
||||
# #message#
|
||||
# (Maximal 50Character des Filename von rechts:Line)
|
||||
# line separator
|
||||
#
|
||||
# b)
|
||||
# %d (%.15F:%L) %-5p %c |#| %m%n
|
||||
# date/time
|
||||
# (Maximal 15Character des Filename von rechts:Line)
|
||||
# priority, Right pad with spaces if the priority name is less than 5 characters long.
|
||||
# category/channel
|
||||
# message
|
||||
# line separator
|
||||
#
|
||||
# Examples for files:
|
||||
Executable
+69
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* DDS View -> The "LogView" for DDS
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
|
||||
/*!
|
||||
*
|
||||
* \page OCLaptop O/C Laptop
|
||||
*
|
||||
* This part of the TDS software is needed to assist the O/C in the field. It is
|
||||
* designed to provide a subset of the workstation software to help the O/C to
|
||||
* evaluate the situation in the field. It has also the possibility to do short
|
||||
* after action reviews (prepared with the workstation software) and to do evaluations
|
||||
* for later usage in the workstation i.e. for the after action review. The TakeHomePackage-Viewer
|
||||
* is also a part of this software component.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <QtGui/QDesktopServices>
|
||||
#include <QtCore/QSettings>
|
||||
|
||||
#include <LtsCommandLineParser/LtsCommandLineParser.h>
|
||||
|
||||
#include <NGLLogger/INGLLogger.h>
|
||||
#include <nglsettings/nglsettings_settings.h>
|
||||
#include <nglapplication/nglcoreapplication.h>
|
||||
|
||||
#include "topic_discoverer.h"
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
NGLCoreApplication app ( argc, argv );
|
||||
QCoreApplication::setApplicationName(QLatin1String("Topic Discoverer"));
|
||||
QCoreApplication::setOrganizationName(QLatin1String("RME"));
|
||||
app.createLogger("TopicDiscover", "log4cxx_topicdiscover.props");
|
||||
NGL::INGLLogger &logger = app.baseLogger();
|
||||
|
||||
LtsCommandLineParser::LtsCommandLineParser options;
|
||||
|
||||
options.addOption( { QStringList() << QLatin1String("lang") << QLatin1String("language")
|
||||
, QLatin1String("language / region code (e.g. de_DE or en_US)")
|
||||
, QLatin1String("de_DE|en_US")
|
||||
, QLatin1String("en_US") } );
|
||||
|
||||
if(!options.init())
|
||||
{
|
||||
options.showHelp();
|
||||
return -1;
|
||||
}
|
||||
|
||||
QString langCodeArg = options.isSet(QLatin1String("lang")) ? options.value(QLatin1String("lang")) : QLatin1String("en_US");
|
||||
|
||||
Q_UNUSED(langCodeArg);
|
||||
|
||||
STARTUP_LOG(logger);
|
||||
|
||||
TopicDiscoverer td(0);
|
||||
td.init(DDS::QosProfile::ConnectionType::ShmUdp, QUrl());
|
||||
|
||||
int retval = app.exec();
|
||||
|
||||
SHUTDOWN_LOG(logger);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
Executable
+194
@@ -0,0 +1,194 @@
|
||||
|
||||
#include "topic_discoverer.h"
|
||||
|
||||
#include <NGLLogger/NGLLoggerBootstrap.h>
|
||||
#include <QCoreApplication>
|
||||
#include <DDS/QosProfile/DDS_DefaultQos.h>
|
||||
|
||||
BuiltinAnyListener::BuiltinAnyListener(QObject *parent)
|
||||
: m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("TopicDiscoverer.BuiltinAnyListener"))
|
||||
{
|
||||
Q_UNUSED(parent)
|
||||
}
|
||||
|
||||
dds::core::xtypes::StructType BuiltinAnyListener::structType(const std::string &typeName)
|
||||
{
|
||||
QReadLocker l(&m_safeTypeLock);
|
||||
return m_structTypes.value(typeName, dds::core::xtypes::StructType("NULL"));
|
||||
}
|
||||
|
||||
// This gets called when a participant has been discovered
|
||||
template <typename S>
|
||||
void BuiltinAnyListener::on_data_available(dds::sub::DataReader<S> &reader)
|
||||
{
|
||||
// We only process newly seen participants
|
||||
dds::sub::LoanedSamples<S> samples
|
||||
= reader.select().state(dds::sub::status::DataState::new_instance()).take();
|
||||
|
||||
for (typename dds::sub::LoanedSamples<S>::iterator sampleIt = samples.begin();
|
||||
sampleIt != samples.end();
|
||||
++sampleIt)
|
||||
{
|
||||
if (!sampleIt->info().valid())
|
||||
continue;
|
||||
|
||||
const std::string &topicName = sampleIt->data().topic_name();
|
||||
const std::string &typeName = sampleIt->data().type_name();
|
||||
|
||||
if (QString::fromStdString(typeName).contains(QLatin1String("rti::"), Qt::CaseInsensitive))
|
||||
continue;
|
||||
|
||||
dds::core::optional<dds::core::xtypes::DynamicType> dynamicType = sampleIt->data()->type();
|
||||
if (!dynamicType.is_set() || dynamicType.get().kind() != dds::core::xtypes::TypeKind::STRUCTURE_TYPE)
|
||||
continue;
|
||||
|
||||
const dds::core::xtypes::StructType &structType = static_cast<dds::core::xtypes::StructType&>(dynamicType.get());
|
||||
|
||||
DEBUG_LOG(m_logger) << "Built-in Reader: found subscriber: "
|
||||
<< " topicName: " << topicName
|
||||
<< " topicType: " << typeName
|
||||
;
|
||||
|
||||
{
|
||||
QWriteLocker l(&m_safeTypeLock);
|
||||
m_structTypes.insert(typeName, structType);
|
||||
}
|
||||
emit topicDescription(topicName, typeName);
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************************************/
|
||||
|
||||
BuiltinPublicationListener::BuiltinPublicationListener(QObject *parent)
|
||||
: BuiltinAnyListener(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BuiltinPublicationListener::on_data_available(dds::sub::DataReader<dds::topic::PublicationBuiltinTopicData> &reader)
|
||||
{
|
||||
BuiltinAnyListener::on_data_available(reader);
|
||||
}
|
||||
|
||||
/***********************************************************************************************/
|
||||
|
||||
BuiltinSubscriberListener::BuiltinSubscriberListener(QObject *parent)
|
||||
: BuiltinAnyListener(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void BuiltinSubscriberListener::on_data_available(dds::sub::DataReader<dds::topic::SubscriptionBuiltinTopicData> &reader)
|
||||
{
|
||||
BuiltinAnyListener::on_data_available(reader);
|
||||
}
|
||||
|
||||
/***********************************************************************************************/
|
||||
|
||||
TopicDiscoverer::TopicDiscoverer(int domainId, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_domainId(domainId)
|
||||
, m_domainParticipant(nullptr)
|
||||
, m_publisherListener(nullptr)
|
||||
, m_subscriberListener(nullptr)
|
||||
, m_logger(NGL::NGLLoggerBootstrap::getNGLRootLogger().getNGLLogger("TopicDiscoverer"))
|
||||
{
|
||||
qRegisterMetaType<std::string>("std::string");
|
||||
}
|
||||
|
||||
void TopicDiscoverer::init(DDS::QosProfile::ConnectionType ct, const QUrl &tcpDiscoveryUrl)
|
||||
{
|
||||
// make sure to get the same qos as a normal dp/publisher/subscriber
|
||||
DDS::QosProfile::setDefault();
|
||||
|
||||
// By default, the participant is enabled upon construction.
|
||||
// At that time our listeners for the builtin topics have not
|
||||
// been installed, so we disable the participant until we
|
||||
// set up the listeners.
|
||||
|
||||
dds::domain::qos::DomainParticipantFactoryQos factoryQos =
|
||||
dds::domain::DomainParticipant::participant_factory_qos();
|
||||
|
||||
factoryQos << dds::core::policy::EntityFactory::ManuallyEnable();
|
||||
dds::domain::DomainParticipant::participant_factory_qos(factoryQos);
|
||||
|
||||
// Create a DomainParticipant with given Qos.
|
||||
m_domainParticipant = dds::domain::DomainParticipant(m_domainId, DDS::QosProfile::domainParticipantDefault(ct, tcpDiscoveryUrl));
|
||||
dds::domain::qos::DomainParticipantQos dpQos = m_domainParticipant.qos();
|
||||
rti::core::policy::EntityName entityName;
|
||||
entityName.name(QString(qAppName() +
|
||||
QStringLiteral(" - DP ") +
|
||||
QString::number(m_domainId)
|
||||
).toStdString());
|
||||
dpQos << entityName;
|
||||
m_domainParticipant.qos(dpQos);
|
||||
|
||||
// Installing listeners for the builtin topics requires several steps
|
||||
// First get the builtin subscriber.
|
||||
dds::sub::Subscriber builtin_subscriber = dds::sub::builtin_subscriber(m_domainParticipant);
|
||||
|
||||
// Get builtin subscriber's datareader for publishers.
|
||||
std::vector< dds::sub::DataReader<dds::topic::PublicationBuiltinTopicData> > publication_reader;
|
||||
dds::sub::find< dds::sub::DataReader<dds::topic::PublicationBuiltinTopicData> >
|
||||
(
|
||||
builtin_subscriber,
|
||||
dds::topic::publication_topic_name(),
|
||||
std::back_inserter(publication_reader)
|
||||
);
|
||||
|
||||
BuiltinPublicationListener *bipl = new BuiltinPublicationListener(this);
|
||||
|
||||
// Install our listener using ListenerBinder.
|
||||
m_publisherListener = rti::core::bind_and_manage_listener(publication_reader[0],
|
||||
bipl,
|
||||
dds::core::status::StatusMask::data_available()
|
||||
);
|
||||
|
||||
connect(bipl, &BuiltinPublicationListener::topicDescription,
|
||||
this, &TopicDiscoverer::onTopicDescription);
|
||||
/*------------------------------*/
|
||||
|
||||
// Get builtin subscriber's datareader for subscribers.
|
||||
std::vector< dds::sub::DataReader<dds::topic::SubscriptionBuiltinTopicData> > subscription_reader;
|
||||
dds::sub::find< dds::sub::DataReader<dds::topic::SubscriptionBuiltinTopicData> >
|
||||
(
|
||||
builtin_subscriber,
|
||||
dds::topic::subscription_topic_name(),
|
||||
std::back_inserter(subscription_reader)
|
||||
);
|
||||
|
||||
BuiltinSubscriberListener *bisl = new BuiltinSubscriberListener(this);
|
||||
|
||||
// Install our listener using ListenerBinder.
|
||||
m_subscriberListener = rti::core::bind_and_manage_listener(subscription_reader[0],
|
||||
bisl,
|
||||
dds::core::status::StatusMask::data_available()
|
||||
);
|
||||
|
||||
connect(bisl, &BuiltinSubscriberListener::topicDescription,
|
||||
this, &TopicDiscoverer::onTopicDescription);
|
||||
/*------------------------------*/
|
||||
|
||||
// Done! All the listeners are installed, so we can enable the
|
||||
// participant now.
|
||||
m_domainParticipant.enable();
|
||||
}
|
||||
|
||||
void TopicDiscoverer::onTopicDescription(const std::string &topicName,
|
||||
const std::string &typeName)
|
||||
{
|
||||
INFO_LOG(m_logger) << "Built-in Reader: found Topic: "
|
||||
<< " topicName: " << topicName
|
||||
<< " typeName: " << typeName
|
||||
;
|
||||
|
||||
BuiltinAnyListener* bal = qobject_cast<BuiltinAnyListener*>(sender());
|
||||
|
||||
if (!bal)
|
||||
return;
|
||||
|
||||
dds::core::xtypes::StructType type = bal->structType(typeName);
|
||||
|
||||
if (type.name() != "NULL")
|
||||
emit topicDescription(topicName, typeName, type);
|
||||
}
|
||||
Executable
+106
@@ -0,0 +1,106 @@
|
||||
#pragma once
|
||||
|
||||
#include <dds/dds.hpp>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtCore/QReadWriteLock>
|
||||
#include <DDS/QosProfile/DDS_DefaultQos.h>
|
||||
|
||||
#include <rti/core/ListenerBinder.hpp>
|
||||
|
||||
#ifndef TOPICDISCOVER_EXPORT
|
||||
# ifdef BUILD_STATIC_LIBRARIES
|
||||
# define TOPICDISCOVER_EXPORT
|
||||
# else
|
||||
# if defined(MAKE_TOPICDISCOVER_LIB)
|
||||
# define TOPICDISCOVER_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define TOPICDISCOVER_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace NGL {
|
||||
class INGLLogger;
|
||||
}
|
||||
|
||||
class BuiltinAnyListener
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
dds::core::xtypes::StructType structType(const std::string &typeName);
|
||||
|
||||
protected:
|
||||
template <typename S>
|
||||
void on_data_available(dds::sub::DataReader<S>& reader);
|
||||
|
||||
explicit BuiltinAnyListener(QObject *parent = nullptr);
|
||||
virtual ~BuiltinAnyListener() = default;
|
||||
|
||||
signals:
|
||||
void topicDescription(const std::string &topicName,
|
||||
const std::string &typeName);
|
||||
|
||||
protected:
|
||||
QMap<std::string, dds::core::xtypes::StructType> m_structTypes;
|
||||
QReadWriteLock m_safeTypeLock;
|
||||
NGL::INGLLogger &m_logger;
|
||||
};
|
||||
|
||||
class BuiltinPublicationListener
|
||||
: public BuiltinAnyListener
|
||||
, public dds::sub::NoOpDataReaderListener<dds::topic::PublicationBuiltinTopicData>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit BuiltinPublicationListener(QObject *parent = nullptr);
|
||||
virtual ~BuiltinPublicationListener() = default;
|
||||
void on_data_available(dds::sub::DataReader<dds::topic::PublicationBuiltinTopicData> &reader) override final;
|
||||
};
|
||||
|
||||
class BuiltinSubscriberListener
|
||||
: public BuiltinAnyListener
|
||||
, public dds::sub::NoOpDataReaderListener<dds::topic::SubscriptionBuiltinTopicData>
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit BuiltinSubscriberListener(QObject *parent = nullptr);
|
||||
virtual ~BuiltinSubscriberListener() = default;
|
||||
|
||||
void on_data_available(dds::sub::DataReader<dds::topic::SubscriptionBuiltinTopicData> &reader) override final;
|
||||
};
|
||||
|
||||
class TOPICDISCOVER_EXPORT TopicDiscoverer
|
||||
: public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TopicDiscoverer(int domainId, QObject *parent = nullptr);
|
||||
virtual ~TopicDiscoverer() = default;
|
||||
|
||||
void init(DDS::QosProfile::ConnectionType ct, const QUrl &tcpDiscoveryUrl);
|
||||
const dds::domain::DomainParticipant &getDomainParticipant() const { return m_domainParticipant; }
|
||||
|
||||
signals:
|
||||
void topicDescription(const std::string &topicName,
|
||||
const std::string &typeName,
|
||||
const dds::core::xtypes::StructType &type);
|
||||
|
||||
private slots:
|
||||
void onTopicDescription(const std::string &topicName,
|
||||
const std::string &typeName);
|
||||
|
||||
private:
|
||||
|
||||
int m_domainId;
|
||||
dds::domain::DomainParticipant m_domainParticipant;
|
||||
rti::core::ListenerBinder< dds::sub::DataReader<dds::topic::PublicationBuiltinTopicData> > m_publisherListener;
|
||||
rti::core::ListenerBinder< dds::sub::DataReader<dds::topic::SubscriptionBuiltinTopicData> > m_subscriberListener;
|
||||
NGL::INGLLogger &m_logger;
|
||||
|
||||
};
|
||||
Reference in new issue
Block a user