Udplistener start/stop during runtime (#56)

* start implementening runtime start/stop for udplistener

* add signal slots for start/stop/statusChanged for better connectivity with other qt stuff

* fix typo
This commit is contained in:
redPanther 2016-06-27 09:27:11 +02:00 committed by brindosch
parent de39ff8997
commit b9634e57d6
3 changed files with 88 additions and 41 deletions

View File

@ -6,6 +6,7 @@
// Qt includes // Qt includes
#include <QUdpSocket> #include <QUdpSocket>
#include <QSet> #include <QSet>
#include <QHostAddress>
// Hyperion includes // Hyperion includes
#include <hyperion/Hyperion.h> #include <hyperion/Hyperion.h>
@ -33,6 +34,25 @@ public:
/// @return the port number on which this UDP listens for incoming connections /// @return the port number on which this UDP listens for incoming connections
/// ///
uint16_t getPort() const; uint16_t getPort() const;
///
/// @return true if server is active (bind to a port)
///
bool active() { return _isActive; };
public slots:
///
/// bind server to network
///
void start();
///
/// close server
///
void stop();
signals:
void statusChanged(bool isActive);
private slots: private slots:
/// ///
@ -41,7 +61,6 @@ private slots:
void readPendingDatagrams(); void readPendingDatagrams();
void processTheDatagram(const QByteArray * _datagram); void processTheDatagram(const QByteArray * _datagram);
private: private:
/// Hyperion instance /// Hyperion instance
Hyperion * _hyperion; Hyperion * _hyperion;
@ -58,9 +77,17 @@ private:
/// hyperion priority /// hyperion priority
int _timeout; int _timeout;
/// The latest led color data /// The latest led color data
std::vector<ColorRgb> _ledColors; std::vector<ColorRgb> _ledColors;
/// Logger instance /// Logger instance
Logger * _log; Logger * _log;
/// state of connection
bool _isActive;
/// address to bind
QHostAddress _listenAddress;
quint16 _listenPort;
QAbstractSocket::BindFlag _bondage;
}; };

View File

@ -18,38 +18,14 @@ UDPListener::UDPListener(const int priority, const int timeout, const std::strin
_priority(priority), _priority(priority),
_timeout(timeout), _timeout(timeout),
_ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb::BLACK), _ledColors(Hyperion::getInstance()->getLedCount(), ColorRgb::BLACK),
_log(Logger::getInstance("UDPLISTENER")) _log(Logger::getInstance("UDPLISTENER")),
_isActive(false),
_bondage(shared ? QAbstractSocket::ShareAddress : QAbstractSocket::DefaultForPlatform)
{ {
_server = new QUdpSocket(this); _server = new QUdpSocket(this);
QHostAddress listenAddress = address.empty()
QAbstractSocket::BindFlag bondage = QAbstractSocket::DefaultForPlatform; ? QHostAddress::AnyIPv4
if (shared) { : QHostAddress( QString::fromStdString(address) );
bondage = QAbstractSocket::ShareAddress;
}
QHostAddress listenAddress = QHostAddress(QHostAddress::Any);
QHostAddress mcastGroup;
if (!address.empty()) {
listenAddress = QHostAddress( QString::fromStdString(address) );
}
if (listenAddress.isInSubnet(QHostAddress::parseSubnet("224.0.0.0/4"))) {
mcastGroup = listenAddress;
listenAddress = QHostAddress(QHostAddress::AnyIPv4);
}
if (!_server->bind(listenAddress, listenPort, bondage))
{
Warning(_log, "Could not bind to %s:%d parsed from %s", listenAddress.toString().toStdString().c_str(), listenPort, address.c_str());
} else {
Info(_log, "Started, listening on %s:%d", listenAddress.toString().toStdString().c_str(), listenPort);
if (!mcastGroup.isNull()) {
if (_server->joinMulticastGroup(mcastGroup)) {
Info(_log, "Multicast listening on %s",mcastGroup.toString().toStdString().c_str());
} else {
Warning(_log, "Multicast failed for %s", mcastGroup.toString().toStdString().c_str());
}
}
}
// Set trigger for incoming connections // Set trigger for incoming connections
connect(_server, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams())); connect(_server, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
@ -58,9 +34,50 @@ UDPListener::UDPListener(const int priority, const int timeout, const std::strin
UDPListener::~UDPListener() UDPListener::~UDPListener()
{ {
// clear the current channel // clear the current channel
stop();
delete _server;
_hyperion->clear(_priority); _hyperion->clear(_priority);
} }
void UDPListener::start()
{
if ( active() )
return;
QHostAddress mcastGroup;
if (_listenAddress.isInSubnet(QHostAddress::parseSubnet("224.0.0.0/4"))) {
mcastGroup = _listenAddress;
}
if (!_server->bind(_listenAddress, _listenPort, _bondage))
{
Warning(_log, "Could not bind to %s:%d", _listenAddress.toString().toStdString().c_str(), _listenPort);
}
else
{
Info(_log, "Started, listening on %s:%d", _listenAddress.toString().toStdString().c_str(), _listenPort);
if (!mcastGroup.isNull()) {
bool joinGroupOK = _server->joinMulticastGroup(_listenAddress);
InfoIf ( joinGroupOK, _log, "Multicast enabled");
WarningIf( ! joinGroupOK, _log, "Multicast failed");
}
_isActive = true;
emit statusChanged(_isActive);
}
}
void UDPListener::stop()
{
if ( ! active() )
return;
_server->close();
_isActive = false;
emit statusChanged(_isActive);
}
uint16_t UDPListener::getPort() const uint16_t UDPListener::getPort() const
{ {
return _server->localPort(); return _server->localPort();

View File

@ -245,16 +245,19 @@ void HyperionDaemon::startNetworkServices()
if (_config.isMember("udpListener")) if (_config.isMember("udpListener"))
{ {
const Json::Value & udpListenerConfig = _config["udpListener"]; const Json::Value & udpListenerConfig = _config["udpListener"];
_udpListener = new UDPListener(
udpListenerConfig.get("priority",700).asInt(),
udpListenerConfig.get("timeout",10000).asInt(),
udpListenerConfig.get("address", "").asString(),
udpListenerConfig.get("port", 2801).asUInt(),
udpListenerConfig.get("shared", false).asBool()
);
Info(_log, "UDP listener created on port %d", _udpListener->getPort());
if ( udpListenerConfig.get("enable", true).asBool() ) if ( udpListenerConfig.get("enable", true).asBool() )
{ {
_udpListener = new UDPListener( Info(_log, "UDP listener started" );
udpListenerConfig.get("priority",700).asInt(), _udpListener->start();
udpListenerConfig.get("timeout",10000).asInt(),
udpListenerConfig.get("address", "").asString(),
udpListenerConfig.get("port", 2801).asUInt(),
udpListenerConfig.get("shared", false).asBool()
);
Info(_log, "UDP listener created and started on port %d", _udpListener->getPort());
} }
} }