From b9634e57d6e606b144e61a90de4135dbe16d4b2c Mon Sep 17 00:00:00 2001 From: redPanther Date: Mon, 27 Jun 2016 09:27:11 +0200 Subject: [PATCH] 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 --- include/udplistener/UDPListener.h | 33 +++++++++++-- libsrc/udplistener/UDPListener.cpp | 77 ++++++++++++++++++------------ src/hyperiond/hyperiond.cpp | 19 ++++---- 3 files changed, 88 insertions(+), 41 deletions(-) diff --git a/include/udplistener/UDPListener.h b/include/udplistener/UDPListener.h index 3245b81e..457b603b 100644 --- a/include/udplistener/UDPListener.h +++ b/include/udplistener/UDPListener.h @@ -6,6 +6,7 @@ // Qt includes #include #include +#include // Hyperion includes #include @@ -33,6 +34,25 @@ public: /// @return the port number on which this UDP listens for incoming connections /// 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: /// @@ -41,7 +61,6 @@ private slots: void readPendingDatagrams(); void processTheDatagram(const QByteArray * _datagram); - private: /// Hyperion instance Hyperion * _hyperion; @@ -58,9 +77,17 @@ private: /// hyperion priority int _timeout; - /// The latest led color data - std::vector _ledColors; + /// The latest led color data + std::vector _ledColors; /// Logger instance Logger * _log; + + /// state of connection + bool _isActive; + + /// address to bind + QHostAddress _listenAddress; + quint16 _listenPort; + QAbstractSocket::BindFlag _bondage; }; diff --git a/libsrc/udplistener/UDPListener.cpp b/libsrc/udplistener/UDPListener.cpp index e613b9e8..70ed4c77 100644 --- a/libsrc/udplistener/UDPListener.cpp +++ b/libsrc/udplistener/UDPListener.cpp @@ -18,38 +18,14 @@ UDPListener::UDPListener(const int priority, const int timeout, const std::strin _priority(priority), _timeout(timeout), _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); - - QAbstractSocket::BindFlag bondage = QAbstractSocket::DefaultForPlatform; - if (shared) { - 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()); - } - } - } + QHostAddress listenAddress = address.empty() + ? QHostAddress::AnyIPv4 + : QHostAddress( QString::fromStdString(address) ); // Set trigger for incoming connections connect(_server, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams())); @@ -58,9 +34,50 @@ UDPListener::UDPListener(const int priority, const int timeout, const std::strin UDPListener::~UDPListener() { // clear the current channel + stop(); + delete _server; _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 { return _server->localPort(); diff --git a/src/hyperiond/hyperiond.cpp b/src/hyperiond/hyperiond.cpp index 04f57adb..cb2d8364 100644 --- a/src/hyperiond/hyperiond.cpp +++ b/src/hyperiond/hyperiond.cpp @@ -245,16 +245,19 @@ void HyperionDaemon::startNetworkServices() if (_config.isMember("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() ) { - _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 and started on port %d", _udpListener->getPort()); + Info(_log, "UDP listener started" ); + _udpListener->start(); } }