mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
Details coming soon.
This commit is contained in:
@@ -7,24 +7,42 @@ include_directories(
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
${PROTOBUF_INCLUDE_DIRS}
|
||||
)
|
||||
FILE ( GLOB ProtoServer_SOURCES "${CURRENT_HEADER_DIR}/*.h" "${CURRENT_SOURCE_DIR}/*.h" "${CURRENT_SOURCE_DIR}/*.cpp" )
|
||||
|
||||
set(ProtoServer_PROTOS ${CURRENT_SOURCE_DIR}/message.proto )
|
||||
|
||||
protobuf_generate_cpp(ProtoServer_PROTO_SRCS ProtoServer_PROTO_HDRS ${ProtoServer_PROTOS} )
|
||||
|
||||
add_library(protoserver
|
||||
${ProtoServer_SOURCES}
|
||||
${ProtoServer_PROTOS}
|
||||
### Split protoclient from protoserver as protoserver relates to HyperionDaemon and standalone capture binarys can't link to it
|
||||
|
||||
add_library(protoclient
|
||||
${CURRENT_HEADER_DIR}/ProtoConnection.h
|
||||
${CURRENT_SOURCE_DIR}/ProtoConnection.cpp
|
||||
${CURRENT_HEADER_DIR}/ProtoConnectionWrapper.h
|
||||
${CURRENT_SOURCE_DIR}/ProtoConnectionWrapper.cpp
|
||||
${CURRENT_SOURCE_DIR}/ProtoClientConnection.h
|
||||
${CURRENT_SOURCE_DIR}/ProtoClientConnection.cpp
|
||||
${ProtoServer_PROTO_SRCS}
|
||||
${ProtoServer_PROTO_HDRS}
|
||||
)
|
||||
|
||||
add_library(protoserver
|
||||
${CURRENT_HEADER_DIR}/ProtoServer.h
|
||||
${CURRENT_SOURCE_DIR}/ProtoServer.cpp
|
||||
)
|
||||
|
||||
# disable warnings for auto generatet proto files, we can't change the files ....
|
||||
SET_SOURCE_FILES_PROPERTIES ( ${ProtoServer_PROTO_SRCS} ${ProtoServer_PROTO_HDRS} ${ProtoServer_PROTOS} PROPERTIES COMPILE_FLAGS -w )
|
||||
|
||||
target_link_libraries(protoserver
|
||||
target_link_libraries(protoclient
|
||||
hyperion
|
||||
hyperion-utils
|
||||
protobuf
|
||||
Qt5::Gui
|
||||
)
|
||||
|
||||
target_link_libraries(protoserver
|
||||
hyperion
|
||||
hyperion-utils
|
||||
protoclient
|
||||
Qt5::Gui
|
||||
)
|
||||
|
@@ -14,8 +14,6 @@
|
||||
#include <QHostInfo>
|
||||
|
||||
// hyperion util includes
|
||||
#include "hyperion/ImageProcessorFactory.h"
|
||||
#include "hyperion/ImageProcessor.h"
|
||||
#include "utils/ColorRgb.h"
|
||||
|
||||
// project includes
|
||||
@@ -24,17 +22,14 @@
|
||||
ProtoClientConnection::ProtoClientConnection(QTcpSocket *socket)
|
||||
: QObject()
|
||||
, _socket(socket)
|
||||
, _imageProcessor(ImageProcessorFactory::getInstance().newImageProcessor())
|
||||
, _hyperion(Hyperion::getInstance())
|
||||
, _receiveBuffer()
|
||||
, _priority(-1)
|
||||
, _priorityChannelName("Proto-Server")
|
||||
, _clientAddress(QHostInfo::fromName(socket->peerAddress().toString()).hostName())
|
||||
{
|
||||
// connect internal signals and slots
|
||||
connect(_socket, SIGNAL(disconnected()), this, SLOT(socketClosed()));
|
||||
connect(_socket, SIGNAL(readyRead()), this, SLOT(readData()));
|
||||
connect(_hyperion, SIGNAL(imageToLedsMappingChanged(int)), _imageProcessor, SLOT(setLedMappingType(int)));
|
||||
}
|
||||
|
||||
ProtoClientConnection::~ProtoClientConnection()
|
||||
@@ -81,7 +76,7 @@ void ProtoClientConnection::readData()
|
||||
|
||||
void ProtoClientConnection::socketClosed()
|
||||
{
|
||||
_hyperion->unRegisterPriority(_priorityChannelName);
|
||||
_hyperion->clear(_priority);
|
||||
emit connectionClosed(this);
|
||||
}
|
||||
|
||||
@@ -103,7 +98,6 @@ void ProtoClientConnection::handleMessage(const proto::HyperionRequest & message
|
||||
// forward messages
|
||||
emit newMessage(&message);
|
||||
|
||||
int prevPriority = _priority;
|
||||
switch (message.command())
|
||||
{
|
||||
case proto::HyperionRequest::COLOR:
|
||||
@@ -136,24 +130,26 @@ void ProtoClientConnection::handleMessage(const proto::HyperionRequest & message
|
||||
default:
|
||||
handleNotImplemented();
|
||||
}
|
||||
|
||||
if (prevPriority != _priority)
|
||||
{
|
||||
_hyperion->registerPriority(_priorityChannelName, _priority);
|
||||
prevPriority = _priority;
|
||||
}
|
||||
}
|
||||
|
||||
void ProtoClientConnection::handleColorCommand(const proto::ColorRequest &message)
|
||||
{
|
||||
// extract parameters
|
||||
_priority = message.priority();
|
||||
int priority = message.priority();
|
||||
int duration = message.has_duration() ? message.duration() : -1;
|
||||
ColorRgb color;
|
||||
color.red = qRed(message.rgbcolor());
|
||||
color.green = qGreen(message.rgbcolor());
|
||||
color.blue = qBlue(message.rgbcolor());
|
||||
|
||||
// make sure the prio is registered before setColor()
|
||||
if(priority != _priority)
|
||||
{
|
||||
_hyperion->clear(_priority);
|
||||
_hyperion->registerInput(priority, hyperion::COMP_PROTOSERVER, "proto@"+_clientAddress);
|
||||
_priority = priority;
|
||||
}
|
||||
|
||||
// set output
|
||||
_hyperion->setColor(_priority, color, duration);
|
||||
|
||||
@@ -164,12 +160,20 @@ void ProtoClientConnection::handleColorCommand(const proto::ColorRequest &messag
|
||||
void ProtoClientConnection::handleImageCommand(const proto::ImageRequest &message)
|
||||
{
|
||||
// extract parameters
|
||||
_priority = message.priority();
|
||||
int priority = message.priority();
|
||||
int duration = message.has_duration() ? message.duration() : -1;
|
||||
int width = message.imagewidth();
|
||||
int height = message.imageheight();
|
||||
const std::string & imageData = message.imagedata();
|
||||
|
||||
// make sure the prio is registered before setInput()
|
||||
if(priority != _priority)
|
||||
{
|
||||
_hyperion->clear(_priority);
|
||||
_hyperion->registerInput(priority, hyperion::COMP_PROTOSERVER, "proto@"+_clientAddress);
|
||||
_priority = priority;
|
||||
}
|
||||
|
||||
// check consistency of the size of the received data
|
||||
if ((int) imageData.size() != width*height*3)
|
||||
{
|
||||
@@ -177,17 +181,11 @@ void ProtoClientConnection::handleImageCommand(const proto::ImageRequest &messag
|
||||
return;
|
||||
}
|
||||
|
||||
// set width and height of the image processor
|
||||
_imageProcessor->setSize(width, height);
|
||||
|
||||
// create ImageRgb
|
||||
Image<ColorRgb> image(width, height);
|
||||
memcpy(image.memptr(), imageData.c_str(), imageData.size());
|
||||
|
||||
// process the image
|
||||
std::vector<ColorRgb> ledColors = _imageProcessor->process(image);
|
||||
_hyperion->setColors(_priority, ledColors, duration, true, hyperion::COMP_PROTOSERVER , "proto@"+_clientAddress);
|
||||
_hyperion->setImage(_priority, image, duration);
|
||||
_hyperion->setInputImage(_priority, image, duration);
|
||||
|
||||
// send reply
|
||||
sendSuccessReply();
|
||||
@@ -197,11 +195,10 @@ void ProtoClientConnection::handleImageCommand(const proto::ImageRequest &messag
|
||||
void ProtoClientConnection::handleClearCommand(const proto::ClearRequest &message)
|
||||
{
|
||||
// extract parameters
|
||||
_priority = message.priority();
|
||||
int priority = message.priority();
|
||||
|
||||
// clear priority
|
||||
_hyperion->clear(_priority);
|
||||
_hyperion->unRegisterPriority(_priorityChannelName);
|
||||
_hyperion->clear(priority);
|
||||
// send reply
|
||||
sendSuccessReply();
|
||||
}
|
||||
|
@@ -19,8 +19,6 @@
|
||||
#include "message.pb.h"
|
||||
#include "protoserver/ProtoConnection.h"
|
||||
|
||||
class ImageProcessor;
|
||||
|
||||
///
|
||||
/// The Connection object created by a ProtoServer when a new connection is establshed
|
||||
///
|
||||
@@ -128,9 +126,6 @@ private:
|
||||
/// The TCP-Socket that is connected tot the Proto-client
|
||||
QTcpSocket * _socket;
|
||||
|
||||
/// The processor for translating images to led-values
|
||||
ImageProcessor * _imageProcessor;
|
||||
|
||||
/// Link to Hyperion for writing led-values to a priority channel
|
||||
Hyperion * _hyperion;
|
||||
|
||||
@@ -139,8 +134,6 @@ private:
|
||||
|
||||
int _priority;
|
||||
|
||||
QString _priorityChannelName;
|
||||
|
||||
/// address of client
|
||||
QString _clientAddress;
|
||||
};
|
||||
|
@@ -1,43 +1,44 @@
|
||||
// system includes
|
||||
#include <stdexcept>
|
||||
|
||||
// qt incl
|
||||
#include <QTcpServer>
|
||||
|
||||
// project includes
|
||||
#include <hyperion/Hyperion.h>
|
||||
#include <hyperion/MessageForwarder.h>
|
||||
#include <protoserver/ProtoServer.h>
|
||||
#include "protoserver/ProtoConnection.h"
|
||||
#include "ProtoClientConnection.h"
|
||||
#include <bonjour/bonjourserviceregister.h>
|
||||
#include <hyperion/ComponentRegister.h>
|
||||
|
||||
ProtoServer::ProtoServer(uint16_t port)
|
||||
ProtoServer::ProtoServer(const QJsonDocument& config)
|
||||
: QObject()
|
||||
, _hyperion(Hyperion::getInstance())
|
||||
, _server()
|
||||
, _server(new QTcpServer(this))
|
||||
, _openConnections()
|
||||
, _log(Logger::getInstance("PROTOSERVER"))
|
||||
, _forwarder_enabled(true)
|
||||
, _componentRegister( & _hyperion->getComponentRegister())
|
||||
{
|
||||
Debug(_log,"Instance created");
|
||||
connect( _server, SIGNAL(newConnection()), this, SLOT(newConnection()));
|
||||
handleSettingsUpdate(settings::PROTOSERVER, config);
|
||||
|
||||
MessageForwarder * forwarder = _hyperion->getForwarder();
|
||||
QStringList slaves = forwarder->getProtoSlaves();
|
||||
QStringList slaves = _hyperion->getForwarder()->getProtoSlaves();
|
||||
|
||||
for (int i = 0; i < slaves.size(); ++i) {
|
||||
if ( QString("127.0.0.1:%1").arg(port) == slaves.at(i) ) {
|
||||
throw std::runtime_error("PROTOSERVER ERROR: Loop between proto server and forwarder detected. Fix your config!");
|
||||
}
|
||||
|
||||
ProtoConnection* p = new ProtoConnection(slaves.at(i).toLocal8Bit().constData());
|
||||
for (const auto& entry : slaves)
|
||||
{
|
||||
ProtoConnection* p = new ProtoConnection(entry.toLocal8Bit().constData());
|
||||
p->setSkipReply(true);
|
||||
_proxy_connections << p;
|
||||
}
|
||||
|
||||
if (!_server.listen(QHostAddress::Any, port))
|
||||
{
|
||||
throw std::runtime_error("PROTOSERVER ERROR: Could not bind to port");
|
||||
}
|
||||
|
||||
// Set trigger for incoming connections
|
||||
connect(&_server, SIGNAL(newConnection()), this, SLOT(newConnection()));
|
||||
connect( _hyperion, SIGNAL(componentStateChanged(hyperion::Components,bool)), this, SLOT(componentStateChanged(hyperion::Components,bool)));
|
||||
// listen for component changes
|
||||
connect(_componentRegister, &ComponentRegister::updatedComponentState, this, &ProtoServer::componentStateChanged);
|
||||
|
||||
// get inital forwarder state
|
||||
componentStateChanged(hyperion::COMP_FORWARDER, _componentRegister->isComponentEnabled(hyperion::COMP_FORWARDER));
|
||||
}
|
||||
|
||||
ProtoServer::~ProtoServer()
|
||||
@@ -50,27 +51,70 @@ ProtoServer::~ProtoServer()
|
||||
delete _proxy_connections.takeFirst();
|
||||
}
|
||||
|
||||
void ProtoServer::start()
|
||||
{
|
||||
if(_server->isListening())
|
||||
return;
|
||||
|
||||
if (!_server->listen(QHostAddress::Any, _port))
|
||||
{
|
||||
Error(_log,"Could not bind to port '%d', please use an available port",_port);
|
||||
return;
|
||||
}
|
||||
Info(_log, "Started on port %d", _port);
|
||||
|
||||
if(_serviceRegister == nullptr)
|
||||
{
|
||||
_serviceRegister = new BonjourServiceRegister();
|
||||
_serviceRegister->registerService("_hyperiond-proto._tcp", _port);
|
||||
}
|
||||
}
|
||||
|
||||
void ProtoServer::stop()
|
||||
{
|
||||
if(!_server->isListening())
|
||||
return;
|
||||
|
||||
_server->close();
|
||||
Info(_log, "Stopped");
|
||||
}
|
||||
|
||||
void ProtoServer::handleSettingsUpdate(const settings::type& type, const QJsonDocument& config)
|
||||
{
|
||||
if(type == settings::PROTOSERVER)
|
||||
{
|
||||
QJsonObject obj = config.object();
|
||||
if(obj["port"].toInt() != _port)
|
||||
{
|
||||
_port = obj["port"].toInt();
|
||||
stop();
|
||||
start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t ProtoServer::getPort() const
|
||||
{
|
||||
return _server.serverPort();
|
||||
return _port;
|
||||
}
|
||||
|
||||
void ProtoServer::newConnection()
|
||||
{
|
||||
QTcpSocket * socket = _server.nextPendingConnection();
|
||||
|
||||
if (socket != nullptr)
|
||||
while(_server->hasPendingConnections())
|
||||
{
|
||||
Debug(_log, "New connection");
|
||||
ProtoClientConnection * connection = new ProtoClientConnection(socket);
|
||||
_openConnections.insert(connection);
|
||||
if(QTcpSocket * socket = _server->nextPendingConnection())
|
||||
{
|
||||
Debug(_log, "New connection");
|
||||
ProtoClientConnection * connection = new ProtoClientConnection(socket);
|
||||
_openConnections.insert(connection);
|
||||
|
||||
// register slot for cleaning up after the connection closed
|
||||
connect(connection, SIGNAL(connectionClosed(ProtoClientConnection*)), this, SLOT(closedConnection(ProtoClientConnection*)));
|
||||
connect(connection, SIGNAL(newMessage(const proto::HyperionRequest*)), this, SLOT(newMessage(const proto::HyperionRequest*)));
|
||||
// register slot for cleaning up after the connection closed
|
||||
connect(connection, SIGNAL(connectionClosed(ProtoClientConnection*)), this, SLOT(closedConnection(ProtoClientConnection*)));
|
||||
connect(connection, SIGNAL(newMessage(const proto::HyperionRequest*)), this, SLOT(newMessage(const proto::HyperionRequest*)));
|
||||
|
||||
// register forward signal for video mode
|
||||
connect(this, SIGNAL(videoMode(VideoMode)), connection, SLOT(setVideoMode(VideoMode)));
|
||||
// register forward signal for video mode
|
||||
connect(this, SIGNAL(videoMode(VideoMode)), connection, SLOT(setVideoMode(VideoMode)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,12 +137,7 @@ void ProtoServer::componentStateChanged(const hyperion::Components component, bo
|
||||
{
|
||||
if (component == hyperion::COMP_FORWARDER)
|
||||
{
|
||||
if (_forwarder_enabled != enable)
|
||||
{
|
||||
_forwarder_enabled = enable;
|
||||
Info(_log, "forwarder change state to %s", (_forwarder_enabled ? "enabled" : "disabled") );
|
||||
}
|
||||
_hyperion->getComponentRegister().componentStateChanged(component, _forwarder_enabled);
|
||||
_forwarder_enabled = enable;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user