diff --git a/.gitmodules b/.gitmodules index 68102e8d..e3d011f2 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "dependencies/external/protobuf"] - path = dependencies/external/protobuf - url = https://github.com/hyperion-project/protobuf.git [submodule "dependencies/external/rpi_ws281x"] path = dependencies/external/rpi_ws281x url = https://github.com/hyperion-project/rpi_ws281x.git diff --git a/CMakeLists.txt b/CMakeLists.txt index bdb31224..31b47ec6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,6 @@ SET ( DEFAULT_OSX OFF ) SET ( DEFAULT_X11 OFF ) SET ( DEFAULT_WS281XPWM OFF ) SET ( DEFAULT_USE_SHARED_AVAHI_LIBS ON ) -SET ( DEFAULT_USE_SYSTEM_PROTO_LIBS OFF ) SET ( DEFAULT_USE_SYSTEM_FLATBUFFERS_LIBS OFF ) SET ( DEFAULT_TESTS OFF ) @@ -161,9 +160,6 @@ option(ENABLE_PROFILER "enable profiler capabilities - not for release code" OFF message(STATUS "ENABLE_PROFILER = ${ENABLE_PROFILER}") -SET ( PROTOBUF_INSTALL_BIN_DIR ${CMAKE_BINARY_DIR}/proto ) -SET ( PROTOBUF_INSTALL_LIB_DIR ${CMAKE_BINARY_DIR}/proto ) - SET ( FLATBUFFERS_INSTALL_BIN_DIR ${CMAKE_BINARY_DIR}/flatbuf ) SET ( FLATBUFFERS_INSTALL_LIB_DIR ${CMAKE_BINARY_DIR}/flatbuf ) diff --git a/assets/webconfig/i18n/de.json b/assets/webconfig/i18n/de.json index 730dc199..35dbf291 100644 --- a/assets/webconfig/i18n/de.json +++ b/assets/webconfig/i18n/de.json @@ -47,7 +47,7 @@ "dashboard_infobox_label_latesthyp" : "Aktuellste Hyperion Version:", "dashboard_infobox_label_platform" : "Plattform:", "dashboard_infobox_label_instance" : "Instanz:", - "dashboard_infobox_label_ports" : "Ports (json|proto):", + "dashboard_infobox_label_ports" : "Port flatbuf:", "dashboard_infobox_message_updatewarning" : "Eine aktuellere Version von Hyperion ist verfügbar! (V$1)", "dashboard_infobox_message_updatesuccess" : "Du nutzt die aktuellste Version von Hyperion.", "dashboard_infobox_label_statush" : "Hyperion Status:", @@ -166,6 +166,7 @@ "conf_network_proto_intro" : "Der PROTO-Port dieser Hyperion-Instanz, wird genutzt für \"Bildstreams\" (HyperionScreenCap, Kodi Adddon, ...)", "conf_network_bobl_intro" : "Boblight Empfänger", "conf_network_udpl_intro" : "UDP Empfänger", + "conf_network_fbs_intro" : "Google Flatbuffers Empfänger. Wird genutzt für schnellen Bildempfang.", "conf_network_forw_intro" : "Leite alles an eine zweite Hyperion Instanz weiter, diese kann dann mit einer anderen LED Steuerung genutzt werden", "conf_logging_label_intro" : "Überprüfe die Meldungen im Prokotoll um zu erfahren was Hyperion gerade beschäftigt. Je nach eingestellter Protokoll-Stufe siehst du mehr oder weniger Informationen.", "conf_logging_btn_pbupload" : "Bericht für Supportanfrage hochladen", @@ -562,7 +563,7 @@ "edt_conf_fw_proto_expl" : "Ein Proto Ziel pro Zeile. Bestehend aus IP:PORT (Beispiel: 127.0.0.1:19447)", "edt_conf_fw_proto_itemtitle" : "Proto Ziel", "edt_conf_js_heading_title" : "JSON Server", - "edt_conf_ps_heading_title" : "PROTO Server", + "edt_conf_fbs_heading_title" : "Flatbuffers Server", "edt_conf_bobls_heading_title" : "Boblight Server", "edt_conf_udpl_heading_title" : "UDP Listener", "edt_conf_udpl_address_title" : "Adresse", diff --git a/assets/webconfig/i18n/en.json b/assets/webconfig/i18n/en.json index 51067818..0f49ee8a 100644 --- a/assets/webconfig/i18n/en.json +++ b/assets/webconfig/i18n/en.json @@ -47,7 +47,7 @@ "dashboard_infobox_label_latesthyp" : "Latest Hyperion version:", "dashboard_infobox_label_platform" : "Platform:", "dashboard_infobox_label_instance" : "Instance:", - "dashboard_infobox_label_ports" : "Ports (json|proto):", + "dashboard_infobox_label_ports" : "Port flatbuf:", "dashboard_infobox_message_updatewarning" : "A newer version of Hyperion is available! ($1)", "dashboard_infobox_message_updatesuccess" : "You run the latest version of Hyperion.", "dashboard_infobox_label_statush" : "Hyperion status:", @@ -166,6 +166,7 @@ "conf_network_proto_intro" : "The PROTO-Port of this Hyperion instance, used for picture streams (HyperionScreenCap, Kodi Adddon, ...)", "conf_network_bobl_intro" : "Receiver for Boblight", "conf_network_udpl_intro" : "Receiver for UDP", + "conf_network_fbs_intro" : "Google Flatbuffers Receiver. Used for fast image transmission.", "conf_network_forw_intro" : "Forward all input to a second Hyperion instance which could be driven with another led controller", "conf_logging_label_intro" : "Area to check log messages, depending on loglevel setting you see more or less information.", "conf_logging_btn_pbupload" : "Upload report for support request", @@ -563,7 +564,7 @@ "edt_conf_fw_proto_expl" : "One proto target per line. Contains IP:PORT (Example: 127.0.0.1:19447)", "edt_conf_fw_proto_itemtitle" : "Proto target", "edt_conf_js_heading_title" : "JSON Server", - "edt_conf_ps_heading_title" : "PROTO Server", + "edt_conf_fbs_heading_title" : "Flatbuffers Server", "edt_conf_bobls_heading_title" : "Boblight Server", "edt_conf_udpl_heading_title" : "UDP Listener", "edt_conf_udpl_address_title" : "Address", diff --git a/assets/webconfig/js/content_network.js b/assets/webconfig/js/content_network.js index eb276c08..7c747121 100644 --- a/assets/webconfig/js/content_network.js +++ b/assets/webconfig/js/content_network.js @@ -16,11 +16,6 @@ $(document).ready( function() { $('#conf_cont_json').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_js_heading_title"), 'editor_container_jsonserver', 'btn_submit_jsonserver')); $('#conf_cont_json').append(createHelpTable(schema.jsonServer.properties, $.i18n("edt_conf_js_heading_title"))); - //protoserver - $('#conf_cont').append(createRow('conf_cont_proto')) - $('#conf_cont_proto').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_ps_heading_title"), 'editor_container_protoserver', 'btn_submit_protoserver')); - $('#conf_cont_proto').append(createHelpTable(schema.protoServer.properties, $.i18n("edt_conf_ps_heading_title"))); - //flatbufserver $('#conf_cont').append(createRow('conf_cont_flatbuf')) $('#conf_cont_flatbuf').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_fbs_heading_title"), 'editor_container_fbserver', 'btn_submit_fbserver')); @@ -48,7 +43,6 @@ $(document).ready( function() { { $('#conf_cont').addClass('row'); $('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_js_heading_title"), 'editor_container_jsonserver', 'btn_submit_jsonserver')); - $('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_ps_heading_title"), 'editor_container_protoserver', 'btn_submit_protoserver')); $('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_fbs_heading_title"), 'editor_container_fbserver', 'btn_submit_fbserver')); $('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_bobls_heading_title"), 'editor_container_boblightserver', 'btn_submit_boblightserver')); $('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_udpl_heading_title"), 'editor_container_udplistener', 'btn_submit_udplistener')); @@ -69,19 +63,6 @@ $(document).ready( function() { requestWriteConfig(conf_editor_json.getValue()); }); - //protobuffer - conf_editor_proto = createJsonEditor('editor_container_protoserver', { - protoServer : schema.protoServer - }, true, true); - - conf_editor_proto.on('change',function() { - conf_editor_proto.validate().length ? $('#btn_submit_protoserver').attr('disabled', true) : $('#btn_submit_protoserver').attr('disabled', false); - }); - - $('#btn_submit_protoserver').off().on('click',function() { - requestWriteConfig(conf_editor_proto.getValue()); - }); - //flatbuffer conf_editor_fbs = createJsonEditor('editor_container_fbserver', { flatbufServer : schema.flatbufServer @@ -141,7 +122,6 @@ $(document).ready( function() { if(showOptHelp) { createHint("intro", $.i18n('conf_network_json_intro'), "editor_container_jsonserver"); - createHint("intro", $.i18n('conf_network_proto_intro'), "editor_container_protoserver"); createHint("intro", $.i18n('conf_network_fbs_intro'), "editor_container_fbserver"); createHint("intro", $.i18n('conf_network_bobl_intro'), "editor_container_boblightserver"); createHint("intro", $.i18n('conf_network_udpl_intro'), "editor_container_udplistener"); diff --git a/config/hyperion.config.json.commented b/config/hyperion.config.json.commented index c5313fca..9532d97c 100644 --- a/config/hyperion.config.json.commented +++ b/config/hyperion.config.json.commented @@ -231,13 +231,6 @@ "port" : 19444 }, - /// The configuration of the Protobuffer server which enables the Protobuffer remote interface - /// * port : Port at which the protobuffer server is started - "protoServer" : - { - "port" : 19445 - }, - /// The configuration of the Flatbuffer server which enables the Flatbuffer remote interface /// * port : Port at which the flatbuffer server is started "flatbufServer" : diff --git a/config/hyperion.config.json.default b/config/hyperion.config.json.default index 7ced8462..fa09304a 100644 --- a/config/hyperion.config.json.default +++ b/config/hyperion.config.json.default @@ -130,11 +130,6 @@ "port" : 19444 }, - "protoServer" : - { - "port" : 19445 - }, - "flatbufServer" : { "enable" : true, diff --git a/dependencies/CMakeLists.txt b/dependencies/CMakeLists.txt index 9d91a34e..4efc3fcd 100644 --- a/dependencies/CMakeLists.txt +++ b/dependencies/CMakeLists.txt @@ -50,107 +50,3 @@ function(compile_flattbuffer_schema SRC_FBS OUTPUT_DIR) "${SRC_FBS}" DEPENDS flatc) endfunction() - -set(USE_SYSTEM_PROTO_LIBS ${DEFAULT_USE_SYSTEM_PROTO_LIBS} CACHE BOOL "use protobuf library from system") - -if (USE_SYSTEM_PROTO_LIBS) - find_package(Protobuf REQUIRED) - include_directories(${PROTOBUF_INCLUDE_DIRS}) -else () - set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared protobuf library") - add_subdirectory(external/protobuf) - - if(CMAKE_CROSSCOMPILING) - # when crosscompiling import the protoc executable targets from a file generated by a native build - option(IMPORT_PROTOC "Protoc export file (protoc_export.cmake) from a native build" "IMPORT_PROTOC-FILE_NOT_FOUND") - include(${IMPORT_PROTOC}) - else() - # export the protoc compiler so it can be used when cross compiling - export(TARGETS protoc_compiler FILE "${CMAKE_BINARY_DIR}/protoc_export.cmake") - endif() - - # define the include for the protobuf library at the parent scope - set(PROTOBUF_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/external/protobuf/src") - set(PROTOBUF_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIRS} PARENT_SCOPE) - - # define the protoc executable at the parent scope - get_property(PROTOBUF_PROTOC_EXECUTABLE TARGET protoc_compiler PROPERTY LOCATION) - set(PROTOBUF_PROTOC_EXECUTABLE ${PROTOBUF_PROTOC_EXECUTABLE} PARENT_SCOPE) -endif() - -message(STATUS "Using protobuf compiler: " ${PROTOBUF_PROTOC_EXECUTABLE}) - -#============================================================================= -# Copyright 2009 Kitware, Inc. -# Copyright 2009-2011 Philip Lowman -# Copyright 2008 Esben Mose Hansen, Ange Optimization ApS -# -# Distributed under the OSI-approved BSD License (the "License"); -# see accompanying file Copyright.txt for details. -# -# This software is distributed WITHOUT ANY WARRANTY; without even the -# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -# See the License for more information. -#============================================================================= -# (To distribute this file outside of CMake, substitute the full -# License text for the above reference.) -function(PROTOBUF_GENERATE_CPP SRCS HDRS) - if(NOT ARGN) - message(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files") - return() - endif() - - if(PROTOBUF_GENERATE_CPP_APPEND_PATH) - # Create an include path for each file specified - foreach(FIL ${ARGN}) - get_filename_component(ABS_FIL ${FIL} ABSOLUTE) - get_filename_component(ABS_PATH ${ABS_FIL} PATH) - list(FIND _protobuf_include_path ${ABS_PATH} _contains_already) - if(${_contains_already} EQUAL -1) - list(APPEND _protobuf_include_path -I ${ABS_PATH}) - endif() - endforeach() - else() - set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR}) - endif() - - if(DEFINED PROTOBUF_IMPORT_DIRS) - foreach(DIR ${PROTOBUF_IMPORT_DIRS}) - get_filename_component(ABS_PATH ${DIR} ABSOLUTE) - list(FIND _protobuf_include_path ${ABS_PATH} _contains_already) - if(${_contains_already} EQUAL -1) - list(APPEND _protobuf_include_path -I ${ABS_PATH}) - endif() - endforeach() - endif() - - if(CMAKE_CROSSCOMPILING OR USE_SYSTEM_PROTO_LIBS) - set(PROTOC_DEPENDENCY ${PROTOBUF_PROTOC_EXECUTABLE}) - else() - set(PROTOC_DEPENDENCY protoc_compiler) - endif() - - set(${SRCS}) - set(${HDRS}) - foreach(FIL ${ARGN}) - get_filename_component(ABS_FIL ${FIL} ABSOLUTE) - get_filename_component(FIL_WE ${FIL} NAME_WE) - - list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc") - list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h") - - add_custom_command( - OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc" - "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h" - COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} - ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL} - DEPENDS ${ABS_FIL} ${PROTOC_DEPENDENCY} - COMMENT "Running C++ protocol buffer compiler on ${FIL}" - VERBATIM - ) - endforeach() - - set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE) - set(${SRCS} ${${SRCS}} PARENT_SCOPE) - set(${HDRS} ${${HDRS}} PARENT_SCOPE) -endfunction() diff --git a/dependencies/external/protobuf b/dependencies/external/protobuf deleted file mode 160000 index adce8a99..00000000 --- a/dependencies/external/protobuf +++ /dev/null @@ -1 +0,0 @@ -Subproject commit adce8a99fdab90f290d659b6b3bf2d09b721e24a diff --git a/include/protoserver/ProtoConnection.h b/include/protoserver/ProtoConnection.h deleted file mode 100644 index 7da5d742..00000000 --- a/include/protoserver/ProtoConnection.h +++ /dev/null @@ -1,127 +0,0 @@ -#pragma once - -// Qt includes -#include -#include -#include -#include -#include -#include - -// hyperion util -#include -#include -#include -#include - -#include - -/// -/// Connection class to setup an connection to the hyperion server and execute commands -/// -class ProtoConnection : public QObject -{ - - Q_OBJECT - -public: - /// - /// Constructor - /// - /// @param address The address of the Hyperion server (for example "192.168.0.32:19444) - /// - ProtoConnection(const QString & address); - - /// - /// Destructor - /// - ~ProtoConnection(); - - /// Do not read reply messages from Hyperion if set to true - void setSkipReply(bool skip); - - /// - /// Set all leds to the specified color - /// - /// @param color The color - /// @param priority The priority - /// @param duration The duration in milliseconds - /// - void setColor(const ColorRgb & color, int priority, int duration = 1); - - /// - /// Set the leds according to the given image (assume the image is stretched to the display size) - /// - /// @param image The image - /// @param priority The priority - /// @param duration The duration in milliseconds - /// - void setImage(const Image & image, int priority, int duration = -1); - - /// - /// Clear the given priority channel - /// - /// @param priority The priority - /// - void clear(int priority); - - /// - /// Clear all priority channels - /// - void clearAll(); - - /// - /// Send a command message and receive its reply - /// - /// @param message The message to send - /// - void sendMessage(const proto::HyperionRequest & message); - -private slots: - /// Try to connect to the Hyperion host - void connectToHost(); - - /// - /// Slot called when new data has arrived - /// - void readData(); - -signals: - - /// - /// emits when a new videoMode was requested from proto client - /// - void setVideoMode(const VideoMode videoMode); - -private: - - /// - /// Parse a reply message - /// - /// @param reply The received reply - /// - /// @return true if the reply indicates success - /// - bool parseReply(const proto::HyperionReply & reply); - -private: - /// The TCP-Socket with the connection to the server - QTcpSocket _socket; - - /// Host address - QString _host; - - /// Host port - uint16_t _port; - - /// Skip receiving reply messages from Hyperion if set - bool _skipReply; - - QTimer _timer; - QAbstractSocket::SocketState _prevSocketState; - - /// The buffer used for reading data from the socket - QByteArray _receiveBuffer; - - Logger * _log; -}; diff --git a/include/protoserver/ProtoConnectionWrapper.h b/include/protoserver/ProtoConnectionWrapper.h deleted file mode 100644 index 87646e52..00000000 --- a/include/protoserver/ProtoConnectionWrapper.h +++ /dev/null @@ -1,41 +0,0 @@ -// Qt includes -#include - -// hyperion includes -#include -#include -#include - -// hyperion proto includes -#include "protoserver/ProtoConnection.h" - -/// This class handles callbacks from the V4L2 and X11 grabber -class ProtoConnectionWrapper : public QObject -{ - Q_OBJECT - -public: - ProtoConnectionWrapper(const QString &address, int priority, int duration_ms, bool skipProtoReply); - virtual ~ProtoConnectionWrapper(); - -signals: - /// - /// Forwarding new videoMode - /// - void setVideoMode(const VideoMode videoMode); - -public slots: - /// Handle a single image - /// @param image The image to process - void receiveImage(const Image & image); - -private: - /// Priority for calls to Hyperion - const int _priority; - - /// Duration for color calls to Hyperion - const int _duration_ms; - - /// Hyperion proto connection object - ProtoConnection _connection; -}; diff --git a/include/protoserver/ProtoServer.h b/include/protoserver/ProtoServer.h deleted file mode 100644 index 9ad9afa0..00000000 --- a/include/protoserver/ProtoServer.h +++ /dev/null @@ -1,98 +0,0 @@ -#pragma once - -// system includes -#include - -// Qt includes -#include -#include -#include -#include - -// hyperion includes -#include -#include -#include -#include -#include - -// settings -#include - -// forward decl -class ProtoClientConnection; -class ProtoConnection; -class QTcpServer; -class Hyperion; -class BonjourServiceRegister; - -namespace proto { -class HyperionRequest; -} - -/// -/// This class creates a TCP server which accepts connections wich can then send -/// in Protocol Buffer encoded commands. This interface to Hyperion is used by -/// hyperion-remote to control the leds -/// -class ProtoServer : public QObject -{ - Q_OBJECT - -public: - /// - /// ProtoServer constructor - /// @param config the configuration - /// - ProtoServer(const QJsonDocument& config); - ~ProtoServer(); - - /// - /// @return the port number on which this TCP listens for incoming connections - /// - uint16_t getPort() const; - -public slots: - - /// - /// @brief Handle settings update from Hyperion Settingsmanager emit or this constructor - /// @param type settingyType from enum - /// @param config configuration object - /// - void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config); - -private slots: - /// - /// Slot which is called when a client tries to create a new connection - /// - void newConnection(); - - /// - /// Slot which is called when a client closes a connection - /// @param connection The Connection object which is being closed - /// - void closedConnection(ProtoClientConnection * connection); - -private: - /// Hyperion instance - Hyperion * _hyperion; - - /// The TCP server object - QTcpServer * _server; - - /// List with open connections - QSet _openConnections; - - /// Logger instance - Logger * _log; - - /// Service register - BonjourServiceRegister * _serviceRegister = nullptr; - - uint16_t _port = 0; - - /// Start server - void start(); - /// Stop server - void stop(); -}; diff --git a/libsrc/hyperion/schema/schema-protoServer.json b/libsrc/hyperion/schema/schema-protoServer.json deleted file mode 100644 index a344ba06..00000000 --- a/libsrc/hyperion/schema/schema-protoServer.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "type" : "object", - "required" : true, - "title" : "edt_conf_ps_heading_title", - "properties" : - { - "port" : - { - "type" : "integer", - "required" : true, - "title" : "edt_conf_general_port_title", - "minimum" : 1024, - "maximum" : 65535, - "default" : 19445 - } - }, - "additionalProperties" : false -} diff --git a/libsrc/protoserver/CMakeLists.txt b/libsrc/protoserver/CMakeLists.txt deleted file mode 100644 index f492d380..00000000 --- a/libsrc/protoserver/CMakeLists.txt +++ /dev/null @@ -1,48 +0,0 @@ - -# Define the current source locations -set(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/protoserver) -set(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/protoserver) - -include_directories( - ${CMAKE_CURRENT_BINARY_DIR} - ${PROTOBUF_INCLUDE_DIRS} -) - -set(ProtoServer_PROTOS ${CURRENT_SOURCE_DIR}/message.proto ) - -protobuf_generate_cpp(ProtoServer_PROTO_SRCS ProtoServer_PROTO_HDRS ${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(protoclient - hyperion - hyperion-utils - protobuf - Qt5::Gui -) - -target_link_libraries(protoserver - hyperion - hyperion-utils - protoclient - Qt5::Gui -) diff --git a/libsrc/protoserver/ProtoClientConnection.cpp b/libsrc/protoserver/ProtoClientConnection.cpp deleted file mode 100644 index f3c42c33..00000000 --- a/libsrc/protoserver/ProtoClientConnection.cpp +++ /dev/null @@ -1,255 +0,0 @@ -// system includes -#include -#include - -// stl includes -#include -#include -#include - -// Qt includes -#include -#include -#include -#include - -// hyperion util includes -#include "utils/ColorRgb.h" - -// Hyperion includes -#include - -// project includes -#include "ProtoClientConnection.h" - -ProtoClientConnection::ProtoClientConnection(QTcpSocket *socket) - : QObject() - , _socket(socket) - , _hyperion(Hyperion::getInstance()) - , _receiveBuffer() - , _priority(-1) - , _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())); -} - -ProtoClientConnection::~ProtoClientConnection() -{ - delete _socket; -} - -void ProtoClientConnection::readData() -{ - _receiveBuffer += _socket->readAll(); - - // check if we can read a message size - if (_receiveBuffer.size() <= 4) - { - return; - } - - // read the message size - uint32_t messageSize = - ((_receiveBuffer[0]<<24) & 0xFF000000) | - ((_receiveBuffer[1]<<16) & 0x00FF0000) | - ((_receiveBuffer[2]<< 8) & 0x0000FF00) | - ((_receiveBuffer[3] ) & 0x000000FF); - - // check if we can read a complete message - if ((uint32_t) _receiveBuffer.size() < messageSize + 4) - { - return; - } - - // read a message - proto::HyperionRequest message; - if (!message.ParseFromArray(_receiveBuffer.data() + 4, messageSize)) - { - sendErrorReply("Unable to parse message"); - } - - // handle the message - handleMessage(message); - - // remove message data from buffer - _receiveBuffer = _receiveBuffer.mid(messageSize + 4); -} - -void ProtoClientConnection::socketClosed() -{ - _hyperion->clear(_priority); - emit connectionClosed(this); -} - -void ProtoClientConnection::setVideoMode(const VideoMode videoMode) -{ - int video_Mode = (int)videoMode; - proto::HyperionReply vMode; - - // create proto message - vMode.set_type(proto::HyperionReply::VIDEO); - vMode.set_video(video_Mode); - - // send message - sendMessage(vMode); -} - -void ProtoClientConnection::handleMessage(const proto::HyperionRequest & message) -{ - // forward messages - emit newMessage(&message); - - switch (message.command()) - { - case proto::HyperionRequest::COLOR: - if (!message.HasExtension(proto::ColorRequest::colorRequest)) - { - sendErrorReply("Received COLOR command without ColorRequest"); - break; - } - handleColorCommand(message.GetExtension(proto::ColorRequest::colorRequest)); - break; - case proto::HyperionRequest::IMAGE: - if (!message.HasExtension(proto::ImageRequest::imageRequest)) - { - sendErrorReply("Received IMAGE command without ImageRequest"); - break; - } - handleImageCommand(message.GetExtension(proto::ImageRequest::imageRequest)); - break; - case proto::HyperionRequest::CLEAR: - if (!message.HasExtension(proto::ClearRequest::clearRequest)) - { - sendErrorReply("Received CLEAR command without ClearRequest"); - break; - } - handleClearCommand(message.GetExtension(proto::ClearRequest::clearRequest)); - break; - case proto::HyperionRequest::CLEARALL: - handleClearallCommand(); - break; - default: - handleNotImplemented(); - } -} - -void ProtoClientConnection::handleColorCommand(const proto::ColorRequest &message) -{ - // extract parameters - 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); - - // send reply - sendSuccessReply(); -} - -void ProtoClientConnection::handleImageCommand(const proto::ImageRequest &message) -{ - // extract parameters - 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) - { - sendErrorReply("Size of image data does not match with the width and height"); - return; - } - - // create ImageRgb - Image image(width, height); - memcpy(image.memptr(), imageData.c_str(), imageData.size()); - - _hyperion->setInputImage(_priority, image, duration); - - // send reply - sendSuccessReply(); -} - - -void ProtoClientConnection::handleClearCommand(const proto::ClearRequest &message) -{ - // extract parameters - int priority = message.priority(); - - // clear priority - //_hyperion->clear(priority); - // send reply - sendSuccessReply(); -} - -void ProtoClientConnection::handleClearallCommand() -{ - // clear priority - //_hyperion->clearall(); - - // send reply - sendSuccessReply(); -} - - -void ProtoClientConnection::handleNotImplemented() -{ - sendErrorReply("Command not implemented"); -} - -void ProtoClientConnection::sendMessage(const google::protobuf::Message &message) -{ - std::string serializedReply = message.SerializeAsString(); - uint32_t size = serializedReply.size(); - uint8_t sizeData[] = {uint8_t(size >> 24), uint8_t(size >> 16), uint8_t(size >> 8), uint8_t(size)}; - _socket->write((const char *) sizeData, sizeof(sizeData)); - _socket->write(serializedReply.data(), serializedReply.length()); - _socket->flush(); -} - -void ProtoClientConnection::sendSuccessReply() -{ - // create reply - proto::HyperionReply reply; - reply.set_type(proto::HyperionReply::REPLY); - reply.set_success(true); - - // send reply - sendMessage(reply); -} - -void ProtoClientConnection::sendErrorReply(const std::string &error) -{ - // create reply - proto::HyperionReply reply; - reply.set_type(proto::HyperionReply::REPLY); - reply.set_success(false); - reply.set_error(error); - - // send reply - sendMessage(reply); -} diff --git a/libsrc/protoserver/ProtoClientConnection.h b/libsrc/protoserver/ProtoClientConnection.h deleted file mode 100644 index 4f8c62ee..00000000 --- a/libsrc/protoserver/ProtoClientConnection.h +++ /dev/null @@ -1,138 +0,0 @@ -#pragma once - -// stl includes -#include - -// Qt includes -#include -#include -#include -#include - -//Utils includes -#include - -// proto includes -#include "message.pb.h" -#include "protoserver/ProtoConnection.h" - -class Hyperion; - -/// -/// The Connection object created by a ProtoServer when a new connection is establshed -/// -class ProtoClientConnection : public QObject -{ - Q_OBJECT - -public: - /// - /// Constructor - /// @param socket The Socket object for this connection - /// @param hyperion The Hyperion server - /// - ProtoClientConnection(QTcpSocket * socket); - - /// - /// Destructor - /// - ~ProtoClientConnection(); - -public slots: - /// - /// Send video mode message to connected client - /// - void setVideoMode(const VideoMode videoMode); - -signals: - /// - /// Signal which is emitted when the connection is being closed - /// @param connection This connection object - /// - void connectionClosed(ProtoClientConnection * connection); - void newMessage(const proto::HyperionRequest * message); - -private slots: - /// - /// Slot called when new data has arrived - /// - void readData(); - - /// - /// Slot called when this connection is being closed - /// - void socketClosed(); - -private: - /// - /// Handle an incoming Proto message - /// - /// @param message the incoming message as string - /// - void handleMessage(const proto::HyperionRequest &message); - - /// - /// Handle an incoming Proto Color message - /// - /// @param message the incoming message - /// - void handleColorCommand(const proto::ColorRequest & message); - - /// - /// Handle an incoming Proto Image message - /// - /// @param message the incoming message - /// - void handleImageCommand(const proto::ImageRequest & message); - - /// - /// Handle an incoming Proto Clear message - /// - /// @param message the incoming message - /// - void handleClearCommand(const proto::ClearRequest & message); - - /// - /// Handle an incoming Proto Clearall message - /// - void handleClearallCommand(); - - /// - /// Handle an incoming Proto message of unknown type - /// - void handleNotImplemented(); - - /// - /// Send a message to the connected client - /// - /// @param message The Proto message to send - /// - void sendMessage(const google::protobuf::Message &message); - - /// - /// Send a standard reply indicating success - /// - void sendSuccessReply(); - - /// - /// Send an error message back to the client - /// - /// @param error String describing the error - /// - void sendErrorReply(const std::string & error); - -private: - /// The TCP-Socket that is connected tot the Proto-client - QTcpSocket * _socket; - - /// Link to Hyperion for writing led-values to a priority channel - Hyperion * _hyperion; - - /// The buffer used for reading data from the socket - QByteArray _receiveBuffer; - - int _priority; - - /// address of client - QString _clientAddress; -}; diff --git a/libsrc/protoserver/ProtoConnection.cpp b/libsrc/protoserver/ProtoConnection.cpp deleted file mode 100644 index d723b0ae..00000000 --- a/libsrc/protoserver/ProtoConnection.cpp +++ /dev/null @@ -1,239 +0,0 @@ -// stl includes -#include - -// Qt includes -#include - -// protoserver includes -#include "protoserver/ProtoConnection.h" - -ProtoConnection::ProtoConnection(const QString & address) : - _socket(), - _skipReply(false), - _prevSocketState(QAbstractSocket::UnconnectedState), - _log(Logger::getInstance("PROTOCONNECTION")) - { - QStringList parts = address.split(":"); - if (parts.size() != 2) - { - throw std::runtime_error(QString("PROTOCONNECTION ERROR: Wrong address: Unable to parse address (%1)").arg(address).toStdString()); - } - _host = parts[0]; - - bool ok; - _port = parts[1].toUShort(&ok); - if (!ok) - { - throw std::runtime_error(QString("PROTOCONNECTION ERROR: Wrong port: Unable to parse the port number (%1)").arg(parts[1]).toStdString()); - } - - // try to connect to host - Info(_log, "Connecting to Hyperion: %s:%d", _host.toStdString().c_str(), _port); - connectToHost(); - - // start the connection timer - _timer.setInterval(5000); - _timer.setSingleShot(false); - - connect(&_timer,SIGNAL(timeout()), this, SLOT(connectToHost())); - connect(&_socket, SIGNAL(readyRead()), this, SLOT(readData())); - _timer.start(); -} - -ProtoConnection::~ProtoConnection() -{ - _timer.stop(); - _socket.close(); -} - -void ProtoConnection::readData() -{ - _receiveBuffer += _socket.readAll(); - - // check if we can read a message size - if (_receiveBuffer.size() <= 4) - { - return; - } - - // read the message size - uint32_t messageSize = - ((_receiveBuffer[0]<<24) & 0xFF000000) | - ((_receiveBuffer[1]<<16) & 0x00FF0000) | - ((_receiveBuffer[2]<< 8) & 0x0000FF00) | - ((_receiveBuffer[3] ) & 0x000000FF); - - // check if we can read a complete message - if ((uint32_t) _receiveBuffer.size() < messageSize + 4) - { - return; - } - - // read a message - proto::HyperionReply reply; - - if (!reply.ParseFromArray(_receiveBuffer.data() + 4, messageSize)) - { - Error(_log, "Unable to parse message"); - return; - } - - parseReply(reply); - - // remove message data from buffer - _receiveBuffer = _receiveBuffer.mid(messageSize + 4); -} - -void ProtoConnection::setSkipReply(bool skip) -{ - _skipReply = skip; -} - -void ProtoConnection::setColor(const ColorRgb & color, int priority, int duration) -{ - proto::HyperionRequest request; - request.set_command(proto::HyperionRequest::COLOR); - proto::ColorRequest * colorRequest = request.MutableExtension(proto::ColorRequest::colorRequest); - colorRequest->set_rgbcolor((color.red << 16) | (color.green << 8) | color.blue); - colorRequest->set_priority(priority); - colorRequest->set_duration(duration); - - // send command message - sendMessage(request); -} - -void ProtoConnection::setImage(const Image &image, int priority, int duration) -{ - proto::HyperionRequest request; - request.set_command(proto::HyperionRequest::IMAGE); - proto::ImageRequest * imageRequest = request.MutableExtension(proto::ImageRequest::imageRequest); - imageRequest->set_imagedata(image.memptr(), image.width() * image.height() * 3); - imageRequest->set_imagewidth(image.width()); - imageRequest->set_imageheight(image.height()); - imageRequest->set_priority(priority); - imageRequest->set_duration(duration); - - // send command message - sendMessage(request); -} - -void ProtoConnection::clear(int priority) -{ - proto::HyperionRequest request; - request.set_command(proto::HyperionRequest::CLEAR); - proto::ClearRequest * clearRequest = request.MutableExtension(proto::ClearRequest::clearRequest); - clearRequest->set_priority(priority); - - // send command message - sendMessage(request); -} - -void ProtoConnection::clearAll() -{ - proto::HyperionRequest request; - request.set_command(proto::HyperionRequest::CLEARALL); - - // send command message - sendMessage(request); -} - -void ProtoConnection::connectToHost() -{ - // try connection only when - if (_socket.state() == QAbstractSocket::UnconnectedState) - { - _socket.connectToHost(_host, _port); - //_socket.waitForConnected(1000); - } -} - -void ProtoConnection::sendMessage(const proto::HyperionRequest &message) -{ - // print out connection message only when state is changed - if (_socket.state() != _prevSocketState ) - { - switch (_socket.state() ) - { - case QAbstractSocket::UnconnectedState: - Info(_log, "No connection to Hyperion: %s:%d", _host.toStdString().c_str(), _port); - break; - - case QAbstractSocket::ConnectedState: - Info(_log, "Connected to Hyperion: %s:%d", _host.toStdString().c_str(), _port); - break; - - default: - Debug(_log, "Connecting to Hyperion: %s:%d", _host.toStdString().c_str(), _port); - break; - } - _prevSocketState = _socket.state(); - } - - - if (_socket.state() != QAbstractSocket::ConnectedState) - { - return; - } - - // We only get here if we are connected - - // serialize message (FastWriter already appends a newline) - std::string serializedMessage = message.SerializeAsString(); - - int length = serializedMessage.size(); - const uint8_t header[] = { - uint8_t((length >> 24) & 0xFF), - uint8_t((length >> 16) & 0xFF), - uint8_t((length >> 8) & 0xFF), - uint8_t((length ) & 0xFF)}; - - // write message - int count = 0; - count += _socket.write(reinterpret_cast(header), 4); - count += _socket.write(reinterpret_cast(serializedMessage.data()), length); - if (!_socket.waitForBytesWritten()) - { - Error(_log, "Error while writing data to host"); - return; - } -} - -bool ProtoConnection::parseReply(const proto::HyperionReply &reply) -{ - bool success = false; - - switch (reply.type()) - { - case proto::HyperionReply::REPLY: - { - if (!_skipReply) - { - if (!reply.success()) - { - if (reply.has_error()) - { - throw std::runtime_error("PROTOCONNECTION ERROR: " + reply.error()); - } - else - { - throw std::runtime_error("PROTOCONNECTION ERROR: No error info"); - } - } - else - { - success = true; - } - } - break; - } - case proto::HyperionReply::VIDEO: - { - int video = reply.has_video() ? reply.video() : 0; - VideoMode vMode = (VideoMode)video; - emit setVideoMode(vMode); - break; - } - } - - return success; -} diff --git a/libsrc/protoserver/ProtoConnectionWrapper.cpp b/libsrc/protoserver/ProtoConnectionWrapper.cpp deleted file mode 100644 index 160033e2..00000000 --- a/libsrc/protoserver/ProtoConnectionWrapper.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// protoserver includes -#include "protoserver/ProtoConnectionWrapper.h" - -ProtoConnectionWrapper::ProtoConnectionWrapper(const QString &address, - int priority, - int duration_ms, - bool skipProtoReply) - : _priority(priority) - , _duration_ms(duration_ms) - , _connection(address) -{ - _connection.setSkipReply(skipProtoReply); - connect(&_connection, SIGNAL(setVideoMode(VideoMode)), this, SIGNAL(setVideoMode(VideoMode))); -} - -ProtoConnectionWrapper::~ProtoConnectionWrapper() -{ -} - -void ProtoConnectionWrapper::receiveImage(const Image & image) -{ - _connection.setImage(image, _priority, _duration_ms); -} diff --git a/libsrc/protoserver/ProtoServer.cpp b/libsrc/protoserver/ProtoServer.cpp deleted file mode 100644 index 56e8ec1a..00000000 --- a/libsrc/protoserver/ProtoServer.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// system includes -#include - -// qt incl -#include -#include - -// project includes -#include -#include "protoserver/ProtoConnection.h" -#include "ProtoClientConnection.h" -#include -#include - -ProtoServer::ProtoServer(const QJsonDocument& config) - : QObject() - , _server(new QTcpServer(this)) - , _openConnections() - , _log(Logger::getInstance("PROTOSERVER")) -{ - Debug(_log,"Instance created"); - connect( _server, SIGNAL(newConnection()), this, SLOT(newConnection())); - handleSettingsUpdate(settings::PROTOSERVER, config); -} - -ProtoServer::~ProtoServer() -{ - foreach (ProtoClientConnection * connection, _openConnections) { - delete connection; - } -} - -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(this); - _serviceRegister->registerService("_hyperiond-proto._tcp", _port); - } - else if( _serviceRegister->getPort() != _port) - { - delete _serviceRegister; - _serviceRegister = new BonjourServiceRegister(this); - _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 _port; -} - -void ProtoServer::newConnection() -{ - while(_server->hasPendingConnections()) - { - 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*))); - } - } -} - -void ProtoServer::closedConnection(ProtoClientConnection *connection) -{ - Debug(_log, "Connection closed"); - _openConnections.remove(connection); - - // schedule to delete the connection object - connection->deleteLater(); -} diff --git a/libsrc/protoserver/message.proto b/libsrc/protoserver/message.proto deleted file mode 100644 index 9652453e..00000000 --- a/libsrc/protoserver/message.proto +++ /dev/null @@ -1,80 +0,0 @@ -package proto; - -message HyperionRequest { - enum Command { - COLOR = 1; - IMAGE = 2; - CLEAR = 3; - CLEARALL = 4; - } - - // command specification - required Command command = 1; - - // extensions to define all specific requests - extensions 10 to 100; -} - -message ColorRequest { - extend HyperionRequest { - optional ColorRequest colorRequest = 10; - } - - // priority to use when setting the color - required int32 priority = 1; - - // integer value containing the rgb color (0x00RRGGBB) - required int32 RgbColor = 2; - - // duration of the request (negative results in infinite) - optional int32 duration = 3; -} - -message ImageRequest { - extend HyperionRequest { - optional ImageRequest imageRequest = 11; - } - - // priority to use when setting the image - required int32 priority = 1; - - // width of the image - required int32 imagewidth = 2; - - // height of the image - required int32 imageheight = 3; - - // image data - required bytes imagedata = 4; - - // duration of the request (negative results in infinite) - optional int32 duration = 5; -} - -message ClearRequest { - extend HyperionRequest { - optional ClearRequest clearRequest = 12; - } - - // priority which need to be cleared - required int32 priority = 1; -} - -message HyperionReply { - enum Type { - REPLY = 1; - VIDEO = 2; - } - - // Identifies which field is filled in. - required Type type = 1; - - // flag indication success or failure - optional bool success = 2; - - // string indicating the reason for failure (if applicable) - optional string error = 3; - - // Proto Messages for video mode - optional int32 video = 4; -}