mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
ProtoBuffer, UDPListener ...
Protocol Buffer reimplemented to receive image data from third-party apps The status of the component "UDPListener" is now displayed correctly in WebUI Global signal names for WebUI added
This commit is contained in:
parent
777caafb24
commit
7ff9d7037b
5
.gitmodules
vendored
5
.gitmodules
vendored
@ -5,3 +5,8 @@
|
|||||||
[submodule "dependencies/external/flatbuffers"]
|
[submodule "dependencies/external/flatbuffers"]
|
||||||
path = dependencies/external/flatbuffers
|
path = dependencies/external/flatbuffers
|
||||||
url = https://github.com/google/flatbuffers
|
url = https://github.com/google/flatbuffers
|
||||||
|
branch = master
|
||||||
|
[submodule "dependencies/external/protobuf"]
|
||||||
|
path = dependencies/external/protobuf
|
||||||
|
url = https://github.com/hyperion-project/protobuf.git
|
||||||
|
branch = master
|
||||||
|
@ -24,6 +24,7 @@ SET ( DEFAULT_QT ON )
|
|||||||
SET ( DEFAULT_WS281XPWM OFF )
|
SET ( DEFAULT_WS281XPWM OFF )
|
||||||
SET ( DEFAULT_USE_SHARED_AVAHI_LIBS ON )
|
SET ( DEFAULT_USE_SHARED_AVAHI_LIBS ON )
|
||||||
SET ( DEFAULT_USE_SYSTEM_FLATBUFFERS_LIBS OFF )
|
SET ( DEFAULT_USE_SYSTEM_FLATBUFFERS_LIBS OFF )
|
||||||
|
SET ( DEFAULT_USE_SYSTEM_PROTO_LIBS OFF )
|
||||||
SET ( DEFAULT_TESTS OFF )
|
SET ( DEFAULT_TESTS OFF )
|
||||||
|
|
||||||
IF ( ${CMAKE_SYSTEM} MATCHES "Linux" )
|
IF ( ${CMAKE_SYSTEM} MATCHES "Linux" )
|
||||||
@ -164,6 +165,9 @@ message(STATUS "ENABLE_PROFILER = ${ENABLE_PROFILER}")
|
|||||||
SET ( FLATBUFFERS_INSTALL_BIN_DIR ${CMAKE_BINARY_DIR}/flatbuf )
|
SET ( FLATBUFFERS_INSTALL_BIN_DIR ${CMAKE_BINARY_DIR}/flatbuf )
|
||||||
SET ( FLATBUFFERS_INSTALL_LIB_DIR ${CMAKE_BINARY_DIR}/flatbuf )
|
SET ( FLATBUFFERS_INSTALL_LIB_DIR ${CMAKE_BINARY_DIR}/flatbuf )
|
||||||
|
|
||||||
|
SET ( PROTOBUF_INSTALL_BIN_DIR ${CMAKE_BINARY_DIR}/proto )
|
||||||
|
SET ( PROTOBUF_INSTALL_LIB_DIR ${CMAKE_BINARY_DIR}/proto )
|
||||||
|
|
||||||
# check all json files
|
# check all json files
|
||||||
FILE ( GLOB_RECURSE HYPERION_SCHEMAS RELATIVE ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/libsrc/*schema*.json )
|
FILE ( GLOB_RECURSE HYPERION_SCHEMAS RELATIVE ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/libsrc/*schema*.json )
|
||||||
SET( JSON_FILES
|
SET( JSON_FILES
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
"general_comp_UDPLISTENER" : "UDP Listener",
|
"general_comp_UDPLISTENER" : "UDP Listener",
|
||||||
"general_comp_BOBLIGHTSERVER" : "Boblight Server",
|
"general_comp_BOBLIGHTSERVER" : "Boblight Server",
|
||||||
"general_comp_FLATBUFSERVER" : "Flatbuffers Server",
|
"general_comp_FLATBUFSERVER" : "Flatbuffers Server",
|
||||||
|
"general_comp_PROTOSERVER" : "Protocol Buffers Server",
|
||||||
"general_comp_GRABBER" : "Plattform Aufnahme",
|
"general_comp_GRABBER" : "Plattform Aufnahme",
|
||||||
"general_comp_V4L" : "USB Aufnahme",
|
"general_comp_V4L" : "USB Aufnahme",
|
||||||
"general_comp_LEDDEVICE" : "LED Hardware",
|
"general_comp_LEDDEVICE" : "LED Hardware",
|
||||||
@ -48,7 +49,7 @@
|
|||||||
"dashboard_infobox_label_latesthyp" : "Aktuellste Hyperion Version:",
|
"dashboard_infobox_label_latesthyp" : "Aktuellste Hyperion Version:",
|
||||||
"dashboard_infobox_label_platform" : "Plattform:",
|
"dashboard_infobox_label_platform" : "Plattform:",
|
||||||
"dashboard_infobox_label_instance" : "Instanz:",
|
"dashboard_infobox_label_instance" : "Instanz:",
|
||||||
"dashboard_infobox_label_ports" : "Port flatbuf:",
|
"dashboard_infobox_label_ports" : "Ports (flat|proto):",
|
||||||
"dashboard_infobox_message_updatewarning" : "Eine aktuellere Version von Hyperion ist verfügbar! (V$1)",
|
"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_message_updatesuccess" : "Du nutzt die aktuellste Version von Hyperion.",
|
||||||
"dashboard_infobox_label_statush" : "Hyperion Status:",
|
"dashboard_infobox_label_statush" : "Hyperion Status:",
|
||||||
@ -169,6 +170,7 @@
|
|||||||
"conf_network_bobl_intro" : "Boblight Empfänger",
|
"conf_network_bobl_intro" : "Boblight Empfänger",
|
||||||
"conf_network_udpl_intro" : "UDP 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_fbs_intro" : "Google Flatbuffers Empfänger. Wird genutzt für schnellen Bildempfang.",
|
||||||
|
"conf_network_proto_intro" : "Der PROTO-Port dieser Hyperion-Instanz, wird genutzt für \"Bildstreams\" (HyperionScreenCap, Kodi Addon, ...)",
|
||||||
"conf_network_forw_intro" : "Leite alles an eine zweite Hyperion Instanz weiter, diese kann dann mit einer anderen LED Steuerung genutzt werden",
|
"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_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",
|
"conf_logging_btn_pbupload" : "Bericht für Supportanfrage hochladen",
|
||||||
@ -572,6 +574,9 @@
|
|||||||
"edt_conf_fbs_heading_title" : "Flatbuffers Server",
|
"edt_conf_fbs_heading_title" : "Flatbuffers Server",
|
||||||
"edt_conf_fbs_timeout_title" : "Zeitüberschreitung",
|
"edt_conf_fbs_timeout_title" : "Zeitüberschreitung",
|
||||||
"edt_conf_fbs_timeout_expl" : "Wenn für die angegebene Zeit keine Daten empfangen werden, wird die Komponente (vorübergehend) deaktiviert",
|
"edt_conf_fbs_timeout_expl" : "Wenn für die angegebene Zeit keine Daten empfangen werden, wird die Komponente (vorübergehend) deaktiviert",
|
||||||
|
"edt_conf_pbs_heading_title" : "Protocol Buffers Server",
|
||||||
|
"edt_conf_pbs_timeout_title" : "Zeitüberschreitung",
|
||||||
|
"edt_conf_pbs_timeout_expl" : "Wenn für die angegebene Zeit keine Daten empfangen werden, wird die Komponente (vorübergehend) deaktiviert",
|
||||||
"edt_conf_bobls_heading_title" : "Boblight Server",
|
"edt_conf_bobls_heading_title" : "Boblight Server",
|
||||||
"edt_conf_udpl_heading_title" : "UDP Listener",
|
"edt_conf_udpl_heading_title" : "UDP Listener",
|
||||||
"edt_conf_udpl_address_title" : "Adresse",
|
"edt_conf_udpl_address_title" : "Adresse",
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
"general_comp_UDPLISTENER" : "UDP Listener",
|
"general_comp_UDPLISTENER" : "UDP Listener",
|
||||||
"general_comp_BOBLIGHTSERVER" : "Boblight Server",
|
"general_comp_BOBLIGHTSERVER" : "Boblight Server",
|
||||||
"general_comp_FLATBUFSERVER" : "Flatbuffers Server",
|
"general_comp_FLATBUFSERVER" : "Flatbuffers Server",
|
||||||
|
"general_comp_PROTOSERVER" : "Protocol Buffers Server",
|
||||||
"general_comp_GRABBER" : "Platform Capture",
|
"general_comp_GRABBER" : "Platform Capture",
|
||||||
"general_comp_V4L" : "USB Capture",
|
"general_comp_V4L" : "USB Capture",
|
||||||
"general_comp_LEDDEVICE" : "LED device",
|
"general_comp_LEDDEVICE" : "LED device",
|
||||||
@ -48,7 +49,7 @@
|
|||||||
"dashboard_infobox_label_latesthyp" : "Latest Hyperion version:",
|
"dashboard_infobox_label_latesthyp" : "Latest Hyperion version:",
|
||||||
"dashboard_infobox_label_platform" : "Platform:",
|
"dashboard_infobox_label_platform" : "Platform:",
|
||||||
"dashboard_infobox_label_instance" : "Instance:",
|
"dashboard_infobox_label_instance" : "Instance:",
|
||||||
"dashboard_infobox_label_ports" : "Port flatbuf:",
|
"dashboard_infobox_label_ports" : "Ports (flat|proto):",
|
||||||
"dashboard_infobox_message_updatewarning" : "A newer version of Hyperion is available! ($1)",
|
"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_message_updatesuccess" : "You run the latest version of Hyperion.",
|
||||||
"dashboard_infobox_label_statush" : "Hyperion status:",
|
"dashboard_infobox_label_statush" : "Hyperion status:",
|
||||||
@ -169,6 +170,7 @@
|
|||||||
"conf_network_bobl_intro" : "Receiver for Boblight",
|
"conf_network_bobl_intro" : "Receiver for Boblight",
|
||||||
"conf_network_udpl_intro" : "Receiver for UDP",
|
"conf_network_udpl_intro" : "Receiver for UDP",
|
||||||
"conf_network_fbs_intro" : "Google Flatbuffers Receiver. Used for fast image transmission.",
|
"conf_network_fbs_intro" : "Google Flatbuffers Receiver. Used for fast image transmission.",
|
||||||
|
"conf_network_proto_intro" : "The PROTO-Port of this Hyperion instance, used for picture streams (HyperionScreenCap, Kodi Addon, ...)",
|
||||||
"conf_network_forw_intro" : "Forward all input to a second Hyperion instance which could be driven with another led controller",
|
"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_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",
|
"conf_logging_btn_pbupload" : "Upload report for support request",
|
||||||
@ -573,6 +575,9 @@
|
|||||||
"edt_conf_fbs_heading_title" : "Flatbuffers Server",
|
"edt_conf_fbs_heading_title" : "Flatbuffers Server",
|
||||||
"edt_conf_fbs_timeout_title" : "Timeout",
|
"edt_conf_fbs_timeout_title" : "Timeout",
|
||||||
"edt_conf_fbs_timeout_expl" : "If no data are received for the given period, the component will be (soft) disabled.",
|
"edt_conf_fbs_timeout_expl" : "If no data are received for the given period, the component will be (soft) disabled.",
|
||||||
|
"edt_conf_pbs_heading_title" : "Protocol Buffers Server",
|
||||||
|
"edt_conf_pbs_timeout_title" : "Timeout",
|
||||||
|
"edt_conf_pbs_timeout_expl" : "If no data are received for the given period, the component will be (soft) disabled.",
|
||||||
"edt_conf_bobls_heading_title" : "Boblight Server",
|
"edt_conf_bobls_heading_title" : "Boblight Server",
|
||||||
"edt_conf_udpl_heading_title" : "UDP Listener",
|
"edt_conf_udpl_heading_title" : "UDP Listener",
|
||||||
"edt_conf_udpl_address_title" : "Address",
|
"edt_conf_udpl_address_title" : "Address",
|
||||||
|
@ -77,7 +77,7 @@ $(document).ready( function() {
|
|||||||
$('#dash_leddevice').html(serverInfo.ledDevices.active);
|
$('#dash_leddevice').html(serverInfo.ledDevices.active);
|
||||||
$('#dash_currv').html(currentVersion);
|
$('#dash_currv').html(currentVersion);
|
||||||
$('#dash_instance').html(serverConfig.general.name);
|
$('#dash_instance').html(serverConfig.general.name);
|
||||||
$('#dash_ports').html(serverConfig.flatbufServer.port);
|
$('#dash_ports').html(serverConfig.flatbufServer.port+' | '+serverConfig.protoServer.port);
|
||||||
|
|
||||||
$.get( "https://raw.githubusercontent.com/hyperion-project/hyperion.ng/master/version.json", function( data ) {
|
$.get( "https://raw.githubusercontent.com/hyperion-project/hyperion.ng/master/version.json", function( data ) {
|
||||||
parsedUpdateJSON = JSON.parse(data);
|
parsedUpdateJSON = JSON.parse(data);
|
||||||
|
@ -21,6 +21,11 @@ $(document).ready( function() {
|
|||||||
$('#conf_cont_flatbuf').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_fbs_heading_title"), 'editor_container_fbserver', 'btn_submit_fbserver'));
|
$('#conf_cont_flatbuf').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_fbs_heading_title"), 'editor_container_fbserver', 'btn_submit_fbserver'));
|
||||||
$('#conf_cont_flatbuf').append(createHelpTable(schema.flatbufServer.properties, $.i18n("edt_conf_fbs_heading_title")));
|
$('#conf_cont_flatbuf').append(createHelpTable(schema.flatbufServer.properties, $.i18n("edt_conf_fbs_heading_title")));
|
||||||
|
|
||||||
|
//protoserver
|
||||||
|
$('#conf_cont').append(createRow('conf_cont_proto'))
|
||||||
|
$('#conf_cont_proto').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_pbs_heading_title"), 'editor_container_protoserver', 'btn_submit_protoserver'));
|
||||||
|
$('#conf_cont_proto').append(createHelpTable(schema.protoServer.properties, $.i18n("edt_conf_pbs_heading_title")));
|
||||||
|
|
||||||
//boblight
|
//boblight
|
||||||
$('#conf_cont').append(createRow('conf_cont_bobl'))
|
$('#conf_cont').append(createRow('conf_cont_bobl'))
|
||||||
$('#conf_cont_bobl').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_bobls_heading_title"), 'editor_container_boblightserver', 'btn_submit_boblightserver'));
|
$('#conf_cont_bobl').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_bobls_heading_title"), 'editor_container_boblightserver', 'btn_submit_boblightserver'));
|
||||||
@ -44,6 +49,7 @@ $(document).ready( function() {
|
|||||||
$('#conf_cont').addClass('row');
|
$('#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_js_heading_title"), 'editor_container_jsonserver', 'btn_submit_jsonserver'));
|
||||||
$('#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_fbs_heading_title"), 'editor_container_fbserver', 'btn_submit_fbserver'));
|
||||||
|
$('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_pbs_heading_title"), 'editor_container_protoserver', 'btn_submit_protoserver'));
|
||||||
$('#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_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'));
|
$('#conf_cont').append(createOptPanel('fa-sitemap', $.i18n("edt_conf_udpl_heading_title"), 'editor_container_udplistener', 'btn_submit_udplistener'));
|
||||||
if(storedAccess != 'default')
|
if(storedAccess != 'default')
|
||||||
@ -76,6 +82,19 @@ $(document).ready( function() {
|
|||||||
requestWriteConfig(conf_editor_fbs.getValue());
|
requestWriteConfig(conf_editor_fbs.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());
|
||||||
|
});
|
||||||
|
|
||||||
//boblight
|
//boblight
|
||||||
conf_editor_bobl = createJsonEditor('editor_container_boblightserver', {
|
conf_editor_bobl = createJsonEditor('editor_container_boblightserver', {
|
||||||
boblightServer : schema.boblightServer
|
boblightServer : schema.boblightServer
|
||||||
@ -123,6 +142,7 @@ $(document).ready( function() {
|
|||||||
{
|
{
|
||||||
createHint("intro", $.i18n('conf_network_json_intro'), "editor_container_jsonserver");
|
createHint("intro", $.i18n('conf_network_json_intro'), "editor_container_jsonserver");
|
||||||
createHint("intro", $.i18n('conf_network_fbs_intro'), "editor_container_fbserver");
|
createHint("intro", $.i18n('conf_network_fbs_intro'), "editor_container_fbserver");
|
||||||
|
createHint("intro", $.i18n('conf_network_proto_intro'), "editor_container_protoserver");
|
||||||
createHint("intro", $.i18n('conf_network_bobl_intro'), "editor_container_boblightserver");
|
createHint("intro", $.i18n('conf_network_bobl_intro'), "editor_container_boblightserver");
|
||||||
createHint("intro", $.i18n('conf_network_udpl_intro'), "editor_container_udplistener");
|
createHint("intro", $.i18n('conf_network_udpl_intro'), "editor_container_udplistener");
|
||||||
createHint("intro", $.i18n('conf_network_forw_intro'), "editor_container_forwarder");
|
createHint("intro", $.i18n('conf_network_forw_intro'), "editor_container_forwarder");
|
||||||
|
@ -156,9 +156,12 @@ $(document).ready(function() {
|
|||||||
case "FLATBUFSERVER":
|
case "FLATBUFSERVER":
|
||||||
owner = $.i18n('general_comp_FLATBUFSERVER');
|
owner = $.i18n('general_comp_FLATBUFSERVER');
|
||||||
break;
|
break;
|
||||||
|
case "PROTOSERVER":
|
||||||
|
owner = $.i18n('general_comp_PROTOSERVER');
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(duration && compId != "GRABBER" && compId != "PROTOSERVER")
|
if(duration && compId != "GRABBER" && compId != "FLATBUFSERVER" && compId != "PROTOSERVER")
|
||||||
owner += '<br/><span style="font-size:80%; color:grey;">'+$.i18n('remote_input_duration')+' '+duration.toFixed(0)+$.i18n('edt_append_s')+'</span>';
|
owner += '<br/><span style="font-size:80%; color:grey;">'+$.i18n('remote_input_duration')+' '+duration.toFixed(0)+$.i18n('edt_append_s')+'</span>';
|
||||||
|
|
||||||
var btn = '<button id="srcBtn'+i+'" type="button" '+btn_state+' class="btn btn-'+btn_type+' btn_input_selection" onclick="requestSetSource('+priority+');">'+btn_text+'</button>';
|
var btn = '<button id="srcBtn'+i+'" type="button" '+btn_state+' class="btn btn-'+btn_type+' btn_input_selection" onclick="requestSetSource('+priority+');">'+btn_text+'</button>';
|
||||||
|
@ -247,6 +247,15 @@
|
|||||||
"timeout" : 5
|
"timeout" : 5
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// The configuration of the Protobuffer server which enables the Protobuffer remote interface
|
||||||
|
/// * port : Port at which the protobuffer server is started
|
||||||
|
"protoServer" :
|
||||||
|
{
|
||||||
|
"enable" : true,
|
||||||
|
"port" : 19445,
|
||||||
|
"timeout" : 5
|
||||||
|
},
|
||||||
|
|
||||||
/// The configuration of the boblight server which enables the boblight remote interface
|
/// The configuration of the boblight server which enables the boblight remote interface
|
||||||
/// * enable : Enable or disable the boblight server (true/false)
|
/// * enable : Enable or disable the boblight server (true/false)
|
||||||
/// * port : Port at which the boblight server is started
|
/// * port : Port at which the boblight server is started
|
||||||
|
@ -140,6 +140,13 @@
|
|||||||
"timeout" : 5
|
"timeout" : 5
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"protoServer" :
|
||||||
|
{
|
||||||
|
"enable" : true,
|
||||||
|
"port" : 19445,
|
||||||
|
"timeout" : 5
|
||||||
|
},
|
||||||
|
|
||||||
"boblightServer" :
|
"boblightServer" :
|
||||||
{
|
{
|
||||||
"enable" : false,
|
"enable" : false,
|
||||||
|
112
dependencies/CMakeLists.txt
vendored
112
dependencies/CMakeLists.txt
vendored
@ -9,6 +9,10 @@ if(ENABLE_WS281XPWM)
|
|||||||
external/rpi_ws281x/rpihw.c)
|
external/rpi_ws281x/rpihw.c)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
# FLATBUFFER
|
||||||
|
#=============================================================================
|
||||||
|
|
||||||
set(USE_SYSTEM_FLATBUFFERS_LIBS ${DEFAULT_USE_SYSTEM_FLATBUFFERS_LIBS} CACHE BOOL "use flatbuffers library from system")
|
set(USE_SYSTEM_FLATBUFFERS_LIBS ${DEFAULT_USE_SYSTEM_FLATBUFFERS_LIBS} CACHE BOOL "use flatbuffers library from system")
|
||||||
|
|
||||||
if (USE_SYSTEM_FLATBUFFERS_LIBS)
|
if (USE_SYSTEM_FLATBUFFERS_LIBS)
|
||||||
@ -63,3 +67,111 @@ function(compile_flattbuffer_schema SRC_FBS OUTPUT_DIR)
|
|||||||
DEPENDS flatc)
|
DEPENDS flatc)
|
||||||
endif()
|
endif()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
#=============================================================================
|
||||||
|
# PROTOBUFFER
|
||||||
|
#=============================================================================
|
||||||
|
|
||||||
|
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 <philip@yhbt.com>
|
||||||
|
# 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()
|
||||||
|
1
dependencies/external/protobuf
vendored
Submodule
1
dependencies/external/protobuf
vendored
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit adce8a99fdab90f290d659b6b3bf2d09b721e24a
|
@ -41,13 +41,13 @@ private slots:
|
|||||||
/// @brief forward system image
|
/// @brief forward system image
|
||||||
/// @param image The image
|
/// @param image The image
|
||||||
///
|
///
|
||||||
void handleSystemImage(const Image<ColorRgb>& image);
|
void handleSystemImage(const QString& name, const Image<ColorRgb>& image);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief forward v4l image
|
/// @brief forward v4l image
|
||||||
/// @param image The image
|
/// @param image The image
|
||||||
///
|
///
|
||||||
void handleV4lImage(const Image<ColorRgb> & image);
|
void handleV4lImage(const QString& name, const Image<ColorRgb> & image);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Is called from _v4lInactiveTimer to set source after specific time to inactive
|
/// @brief Is called from _v4lInactiveTimer to set source after specific time to inactive
|
||||||
@ -66,10 +66,12 @@ private:
|
|||||||
/// Reflect state of System capture and prio
|
/// Reflect state of System capture and prio
|
||||||
bool _systemCaptEnabled;
|
bool _systemCaptEnabled;
|
||||||
quint8 _systemCaptPrio;
|
quint8 _systemCaptPrio;
|
||||||
|
QString _systemCaptName;
|
||||||
QTimer* _systemInactiveTimer;
|
QTimer* _systemInactiveTimer;
|
||||||
|
|
||||||
/// Reflect state of v4l capture and prio
|
/// Reflect state of v4l capture and prio
|
||||||
bool _v4lCaptEnabled;
|
bool _v4lCaptEnabled;
|
||||||
quint8 _v4lCaptPrio;
|
quint8 _v4lCaptPrio;
|
||||||
|
QString _v4lCaptName;
|
||||||
QTimer* _v4lInactiveTimer;
|
QTimer* _v4lInactiveTimer;
|
||||||
};
|
};
|
||||||
|
@ -54,7 +54,7 @@ public:
|
|||||||
int ret = grabber.grabFrame(_image);
|
int ret = grabber.grabFrame(_image);
|
||||||
if (ret >= 0)
|
if (ret >= 0)
|
||||||
{
|
{
|
||||||
emit systemImage(_image);
|
emit systemImage(_grabberName, _image);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -92,7 +92,7 @@ signals:
|
|||||||
///
|
///
|
||||||
/// @brief Emit the final processed image
|
/// @brief Emit the final processed image
|
||||||
///
|
///
|
||||||
void systemImage(const Image<ColorRgb>& image);
|
void systemImage(const QString& name, const Image<ColorRgb>& image);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -411,7 +411,7 @@ signals:
|
|||||||
void forwardJsonMessage(QJsonObject);
|
void forwardJsonMessage(QJsonObject);
|
||||||
|
|
||||||
/// Signal which is emitted, when a new proto image should be forwarded
|
/// Signal which is emitted, when a new proto image should be forwarded
|
||||||
void forwardProtoMessage(Image<ColorRgb>);
|
void forwardProtoMessage(const QString, const Image<ColorRgb>);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Is emitted from clients who request a videoMode change
|
/// @brief Is emitted from clients who request a videoMode change
|
||||||
|
@ -70,7 +70,7 @@ private slots:
|
|||||||
/// @brief Forward image to all proto slaves
|
/// @brief Forward image to all proto slaves
|
||||||
/// @param image The PROTO image to send
|
/// @param image The PROTO image to send
|
||||||
///
|
///
|
||||||
void forwardProtoMessage(const Image<ColorRgb> &image);
|
void forwardProtoMessage(const QString& name, const Image<ColorRgb> &image);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Forward message to a single json slave
|
/// @brief Forward message to a single json slave
|
||||||
|
67
include/protoserver/ProtoServer.h
Normal file
67
include/protoserver/ProtoServer.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// util
|
||||||
|
#include <utils/Logger.h>
|
||||||
|
#include <utils/settings.h>
|
||||||
|
|
||||||
|
// qt
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
|
class QTcpServer;
|
||||||
|
class ProtoClientConnection;
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief 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 various
|
||||||
|
/// third-party applications
|
||||||
|
///
|
||||||
|
class ProtoServer : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ProtoServer(const QJsonDocument& config, QObject* parent = nullptr);
|
||||||
|
~ProtoServer();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
///
|
||||||
|
/// @brief Handle settings update
|
||||||
|
/// @param type The type from enum
|
||||||
|
/// @param config The configuration
|
||||||
|
///
|
||||||
|
void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config);
|
||||||
|
|
||||||
|
void initServer();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
///
|
||||||
|
/// @brief Is called whenever a new socket wants to connect
|
||||||
|
///
|
||||||
|
void newConnection();
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief is called whenever a client disconnected
|
||||||
|
///
|
||||||
|
void clientDisconnected();
|
||||||
|
|
||||||
|
private:
|
||||||
|
///
|
||||||
|
/// @brief Start the server with current _port
|
||||||
|
///
|
||||||
|
void startServer();
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Stop server
|
||||||
|
///
|
||||||
|
void stopServer();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
QTcpServer* _server;
|
||||||
|
Logger* _log;
|
||||||
|
int _timeout;
|
||||||
|
quint16 _port;
|
||||||
|
const QJsonDocument _config;
|
||||||
|
|
||||||
|
QVector<ProtoClientConnection*> _openConnections;
|
||||||
|
};
|
@ -84,7 +84,6 @@ private slots:
|
|||||||
void processTheDatagram(const QByteArray * datagram, const QHostAddress * sender);
|
void processTheDatagram(const QByteArray * datagram, const QHostAddress * sender);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/// The UDP server object
|
/// The UDP server object
|
||||||
QUdpSocket * _server;
|
QUdpSocket * _server;
|
||||||
|
|
||||||
|
@ -22,7 +22,8 @@ enum Components
|
|||||||
COMP_IMAGE,
|
COMP_IMAGE,
|
||||||
COMP_EFFECT,
|
COMP_EFFECT,
|
||||||
COMP_LEDDEVICE,
|
COMP_LEDDEVICE,
|
||||||
COMP_FLATBUFSERVER
|
COMP_FLATBUFSERVER,
|
||||||
|
COMP_PROTOSERVER
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const char* componentToString(Components c)
|
inline const char* componentToString(Components c)
|
||||||
@ -41,7 +42,8 @@ inline const char* componentToString(Components c)
|
|||||||
case COMP_EFFECT: return "Effect";
|
case COMP_EFFECT: return "Effect";
|
||||||
case COMP_IMAGE: return "Image";
|
case COMP_IMAGE: return "Image";
|
||||||
case COMP_LEDDEVICE: return "LED device";
|
case COMP_LEDDEVICE: return "LED device";
|
||||||
case COMP_FLATBUFSERVER: return "Image Receiver";
|
case COMP_FLATBUFSERVER: return "Image Receiver";
|
||||||
|
case COMP_PROTOSERVER: return "Proto Server";
|
||||||
default: return "";
|
default: return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -63,6 +65,7 @@ inline const char* componentToIdString(Components c)
|
|||||||
case COMP_IMAGE: return "IMAGE";
|
case COMP_IMAGE: return "IMAGE";
|
||||||
case COMP_LEDDEVICE: return "LEDDEVICE";
|
case COMP_LEDDEVICE: return "LEDDEVICE";
|
||||||
case COMP_FLATBUFSERVER: return "FLATBUFSERVER";
|
case COMP_FLATBUFSERVER: return "FLATBUFSERVER";
|
||||||
|
case COMP_PROTOSERVER: return "PROTOSERVER";
|
||||||
default: return "";
|
default: return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,6 +86,7 @@ inline Components stringToComponent(QString component)
|
|||||||
if (component == "IMAGE") return COMP_IMAGE;
|
if (component == "IMAGE") return COMP_IMAGE;
|
||||||
if (component == "LEDDEVICE") return COMP_LEDDEVICE;
|
if (component == "LEDDEVICE") return COMP_LEDDEVICE;
|
||||||
if (component == "FLATBUFSERVER") return COMP_FLATBUFSERVER;
|
if (component == "FLATBUFSERVER") return COMP_FLATBUFSERVER;
|
||||||
|
if (component == "PROTOSERVER") return COMP_PROTOSERVER;
|
||||||
return COMP_INVALID;
|
return COMP_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,13 +29,15 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
///
|
///
|
||||||
/// @brief PIPE SystemCapture images from GrabberWrapper to Hyperion class
|
/// @brief PIPE SystemCapture images from GrabberWrapper to Hyperion class
|
||||||
|
/// @param name The name of the platform capture that is currently active
|
||||||
/// @param image The prepared image
|
/// @param image The prepared image
|
||||||
///
|
///
|
||||||
void setSystemImage(const Image<ColorRgb>& image);
|
void setSystemImage(const QString& name, const Image<ColorRgb>& image);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief PIPE v4lCapture images from v4lCapture over HyperionDaemon to Hyperion class
|
/// @brief PIPE v4lCapture images from v4lCapture over HyperionDaemon to Hyperion class
|
||||||
|
/// @param name The name of the v4l capture (path) that is currently active
|
||||||
/// @param image The prepared image
|
/// @param image The prepared image
|
||||||
///
|
///
|
||||||
void setV4lImage(const Image<ColorRgb> & image);
|
void setV4lImage(const QString& name, const Image<ColorRgb> & image);
|
||||||
};
|
};
|
||||||
|
@ -29,6 +29,7 @@ enum type {
|
|||||||
INSTCAPTURE,
|
INSTCAPTURE,
|
||||||
NETWORK,
|
NETWORK,
|
||||||
FLATBUFSERVER,
|
FLATBUFSERVER,
|
||||||
|
PROTOSERVER,
|
||||||
INVALID
|
INVALID
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -62,6 +63,7 @@ inline QString typeToString(const type& type)
|
|||||||
case INSTCAPTURE: return "instCapture";
|
case INSTCAPTURE: return "instCapture";
|
||||||
case NETWORK: return "network";
|
case NETWORK: return "network";
|
||||||
case FLATBUFSERVER: return "flatbufServer";
|
case FLATBUFSERVER: return "flatbufServer";
|
||||||
|
case PROTOSERVER: return "protoServer";
|
||||||
default: return "invalid";
|
default: return "invalid";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,7 +75,7 @@ inline QString typeToString(const type& type)
|
|||||||
///
|
///
|
||||||
inline type stringToType(const QString& type)
|
inline type stringToType(const QString& type)
|
||||||
{
|
{
|
||||||
if (type == "backgroundEffect") return BGEFFECT;
|
if (type == "backgroundEffect") return BGEFFECT;
|
||||||
else if (type == "foregroundEffect") return FGEFFECT;
|
else if (type == "foregroundEffect") return FGEFFECT;
|
||||||
else if (type == "blackborderdetector") return BLACKBORDER;
|
else if (type == "blackborderdetector") return BLACKBORDER;
|
||||||
else if (type == "boblightServer") return BOBLSERVER;
|
else if (type == "boblightServer") return BOBLSERVER;
|
||||||
@ -94,6 +96,7 @@ inline type stringToType(const QString& type)
|
|||||||
else if (type == "instCapture") return INSTCAPTURE;
|
else if (type == "instCapture") return INSTCAPTURE;
|
||||||
else if (type == "network") return NETWORK;
|
else if (type == "network") return NETWORK;
|
||||||
else if (type == "flatbufServer") return FLATBUFSERVER;
|
else if (type == "flatbufServer") return FLATBUFSERVER;
|
||||||
else return INVALID;
|
else if (type == "protoServer") return PROTOSERVER;
|
||||||
|
else return INVALID;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -8,6 +8,7 @@ add_subdirectory(commandline)
|
|||||||
add_subdirectory(blackborder)
|
add_subdirectory(blackborder)
|
||||||
add_subdirectory(jsonserver)
|
add_subdirectory(jsonserver)
|
||||||
add_subdirectory(flatbufserver)
|
add_subdirectory(flatbufserver)
|
||||||
|
add_subdirectory(protoserver)
|
||||||
add_subdirectory(bonjour)
|
add_subdirectory(bonjour)
|
||||||
add_subdirectory(ssdp)
|
add_subdirectory(ssdp)
|
||||||
add_subdirectory(boblightserver)
|
add_subdirectory(boblightserver)
|
||||||
|
@ -31,7 +31,7 @@ public:
|
|||||||
/// @param timeout The timeout when a client is automatically disconnected and the priority unregistered
|
/// @param timeout The timeout when a client is automatically disconnected and the priority unregistered
|
||||||
/// @param parent The parent
|
/// @param parent The parent
|
||||||
///
|
///
|
||||||
explicit FlatBufferClient(QTcpSocket* socket, const int &timeout, QObject *parent = nullptr);
|
explicit FlatBufferClient(QTcpSocket* socket, const int &timeout, QObject *parent = nullptr);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
///
|
///
|
||||||
@ -59,12 +59,12 @@ private slots:
|
|||||||
///
|
///
|
||||||
/// @brief Is called whenever the socket got new data to read
|
/// @brief Is called whenever the socket got new data to read
|
||||||
///
|
///
|
||||||
void readyRead();
|
void readyRead();
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Is called when the socket closed the connection, also requests thread exit
|
/// @brief Is called when the socket closed the connection, also requests thread exit
|
||||||
///
|
///
|
||||||
void disconnected();
|
void disconnected();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
///
|
///
|
||||||
|
@ -62,8 +62,6 @@ void FlatBufferServer::newConnection()
|
|||||||
FlatBufferClient *client = new FlatBufferClient(socket, _timeout, this);
|
FlatBufferClient *client = new FlatBufferClient(socket, _timeout, this);
|
||||||
// internal
|
// internal
|
||||||
connect(client, &FlatBufferClient::clientDisconnected, this, &FlatBufferServer::clientDisconnected);
|
connect(client, &FlatBufferClient::clientDisconnected, this, &FlatBufferServer::clientDisconnected);
|
||||||
// forward data
|
|
||||||
//connect(clientThread, &FlatBufferClient::);
|
|
||||||
_openConnections.append(client);
|
_openConnections.append(client);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ void V4L2Wrapper::setSignalDetectionOffset(double verticalMin, double horizontal
|
|||||||
|
|
||||||
void V4L2Wrapper::newFrame(const Image<ColorRgb> &image)
|
void V4L2Wrapper::newFrame(const Image<ColorRgb> &image)
|
||||||
{
|
{
|
||||||
emit systemImage(image);
|
emit systemImage(_grabberName, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
void V4L2Wrapper::readError(const char* err)
|
void V4L2Wrapper::readError(const char* err)
|
||||||
|
@ -13,8 +13,10 @@ CaptureCont::CaptureCont(Hyperion* hyperion)
|
|||||||
: QObject()
|
: QObject()
|
||||||
, _hyperion(hyperion)
|
, _hyperion(hyperion)
|
||||||
, _systemCaptEnabled(false)
|
, _systemCaptEnabled(false)
|
||||||
|
, _systemCaptName()
|
||||||
, _systemInactiveTimer(new QTimer(this))
|
, _systemInactiveTimer(new QTimer(this))
|
||||||
, _v4lCaptEnabled(false)
|
, _v4lCaptEnabled(false)
|
||||||
|
, _v4lCaptName()
|
||||||
, _v4lInactiveTimer(new QTimer(this))
|
, _v4lInactiveTimer(new QTimer(this))
|
||||||
{
|
{
|
||||||
// settings changes
|
// settings changes
|
||||||
@ -41,14 +43,24 @@ CaptureCont::~CaptureCont()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void CaptureCont::handleV4lImage(const Image<ColorRgb> & image)
|
void CaptureCont::handleV4lImage(const QString& name, const Image<ColorRgb> & image)
|
||||||
{
|
{
|
||||||
|
if(_v4lCaptName != name)
|
||||||
|
{
|
||||||
|
_hyperion->registerInput(_v4lCaptPrio, hyperion::COMP_V4L, "System", name);
|
||||||
|
_v4lCaptName = name;
|
||||||
|
}
|
||||||
_v4lInactiveTimer->start();
|
_v4lInactiveTimer->start();
|
||||||
_hyperion->setInputImage(_v4lCaptPrio, image);
|
_hyperion->setInputImage(_v4lCaptPrio, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CaptureCont::handleSystemImage(const Image<ColorRgb>& image)
|
void CaptureCont::handleSystemImage(const QString& name, const Image<ColorRgb>& image)
|
||||||
{
|
{
|
||||||
|
if(_systemCaptName != name)
|
||||||
|
{
|
||||||
|
_hyperion->registerInput(_systemCaptPrio, hyperion::COMP_GRABBER, "System", name);
|
||||||
|
_systemCaptName = name;
|
||||||
|
}
|
||||||
_systemInactiveTimer->start();
|
_systemInactiveTimer->start();
|
||||||
_hyperion->setInputImage(_systemCaptPrio, image);
|
_hyperion->setInputImage(_systemCaptPrio, image);
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ void MessageForwarder::forwardJsonMessage(const QJsonObject &message)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageForwarder::forwardProtoMessage(const Image<ColorRgb> &image)
|
void MessageForwarder::forwardProtoMessage(const QString& name, const Image<ColorRgb> &image)
|
||||||
{
|
{
|
||||||
if (_forwarder_enabled)
|
if (_forwarder_enabled)
|
||||||
{
|
{
|
||||||
|
@ -55,6 +55,10 @@
|
|||||||
{
|
{
|
||||||
"$ref": "schema-flatbufServer.json"
|
"$ref": "schema-flatbufServer.json"
|
||||||
},
|
},
|
||||||
|
"protoServer" :
|
||||||
|
{
|
||||||
|
"$ref": "schema-protoServer.json"
|
||||||
|
},
|
||||||
"boblightServer" :
|
"boblightServer" :
|
||||||
{
|
{
|
||||||
"$ref": "schema-boblightServer.json"
|
"$ref": "schema-boblightServer.json"
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
<file alias="schema-forwarder.json">schema/schema-forwarder.json</file>
|
<file alias="schema-forwarder.json">schema/schema-forwarder.json</file>
|
||||||
<file alias="schema-jsonServer.json">schema/schema-jsonServer.json</file>
|
<file alias="schema-jsonServer.json">schema/schema-jsonServer.json</file>
|
||||||
<file alias="schema-flatbufServer.json">schema/schema-flatbufServer.json</file>
|
<file alias="schema-flatbufServer.json">schema/schema-flatbufServer.json</file>
|
||||||
|
<file alias="schema-protoServer.json">schema/schema-protoServer.json</file>
|
||||||
<file alias="schema-boblightServer.json">schema/schema-boblightServer.json</file>
|
<file alias="schema-boblightServer.json">schema/schema-boblightServer.json</file>
|
||||||
<file alias="schema-udpListener.json">schema/schema-udpListener.json</file>
|
<file alias="schema-udpListener.json">schema/schema-udpListener.json</file>
|
||||||
<file alias="schema-webConfig.json">schema/schema-webConfig.json</file>
|
<file alias="schema-webConfig.json">schema/schema-webConfig.json</file>
|
||||||
|
36
libsrc/hyperion/schema/schema-protoServer.json
Normal file
36
libsrc/hyperion/schema/schema-protoServer.json
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
{
|
||||||
|
"type" : "object",
|
||||||
|
"required" : true,
|
||||||
|
"title" : "edt_conf_pbs_heading_title",
|
||||||
|
"properties" :
|
||||||
|
{
|
||||||
|
"enable" :
|
||||||
|
{
|
||||||
|
"type" : "boolean",
|
||||||
|
"required" : true,
|
||||||
|
"title" : "edt_conf_general_enable_title",
|
||||||
|
"default" : true,
|
||||||
|
"propertyOrder" : 1
|
||||||
|
},
|
||||||
|
"port" :
|
||||||
|
{
|
||||||
|
"type" : "integer",
|
||||||
|
"required" : true,
|
||||||
|
"title" : "edt_conf_general_port_title",
|
||||||
|
"minimum" : 1024,
|
||||||
|
"maximum" : 65535,
|
||||||
|
"default" : 19445
|
||||||
|
},
|
||||||
|
"timeout" :
|
||||||
|
{
|
||||||
|
"type" : "integer",
|
||||||
|
"required" : true,
|
||||||
|
"title" : "edt_conf_pbs_timeout_title",
|
||||||
|
"append" : "edt_append_s",
|
||||||
|
"minimum" : 1,
|
||||||
|
"default" : 5,
|
||||||
|
"propertyOrder" : 3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties" : false
|
||||||
|
}
|
44
libsrc/protoserver/CMakeLists.txt
Normal file
44
libsrc/protoserver/CMakeLists.txt
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
|
||||||
|
# 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_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 generated 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
|
||||||
|
)
|
238
libsrc/protoserver/ProtoClientConnection.cpp
Normal file
238
libsrc/protoserver/ProtoClientConnection.cpp
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
// project includes
|
||||||
|
#include "ProtoClientConnection.h"
|
||||||
|
|
||||||
|
// qt
|
||||||
|
#include <QTcpSocket>
|
||||||
|
#include <QHostAddress>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QRgb>
|
||||||
|
|
||||||
|
// Hyperion includes
|
||||||
|
#include <hyperion/Hyperion.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ProtoClientConnection::ProtoClientConnection(QTcpSocket* socket, const int &timeout, QObject *parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, _log(Logger::getInstance("PROTOSERVER"))
|
||||||
|
, _socket(socket)
|
||||||
|
, _clientAddress(socket->peerAddress().toString())
|
||||||
|
, _timeoutTimer(new QTimer(this))
|
||||||
|
, _timeout(timeout * 1000)
|
||||||
|
, _priority()
|
||||||
|
, _hyperion(Hyperion::getInstance())
|
||||||
|
{
|
||||||
|
// timer setup
|
||||||
|
_timeoutTimer->setSingleShot(true);
|
||||||
|
_timeoutTimer->setInterval(_timeout);
|
||||||
|
connect(_timeoutTimer, &QTimer::timeout, this, &ProtoClientConnection::forceClose);
|
||||||
|
|
||||||
|
// connect socket signals
|
||||||
|
connect(_socket, &QTcpSocket::readyRead, this, &ProtoClientConnection::readyRead);
|
||||||
|
connect(_socket, &QTcpSocket::disconnected, this, &ProtoClientConnection::disconnected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtoClientConnection::readyRead()
|
||||||
|
{
|
||||||
|
_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::forceClose()
|
||||||
|
{
|
||||||
|
_socket->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtoClientConnection::disconnected()
|
||||||
|
{
|
||||||
|
Debug(_log, "Socket Closed");
|
||||||
|
_socket->deleteLater();
|
||||||
|
_hyperion->clear(_priority);
|
||||||
|
emit clientDisconnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtoClientConnection::handleMessage(const proto::HyperionRequest & 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<ColorRgb> 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);
|
||||||
|
}
|
135
libsrc/protoserver/ProtoClientConnection.h
Normal file
135
libsrc/protoserver/ProtoClientConnection.h
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// util
|
||||||
|
#include <utils/Logger.h>
|
||||||
|
#include <utils/Image.h>
|
||||||
|
#include <utils/ColorRgb.h>
|
||||||
|
#include <utils/Components.h>
|
||||||
|
|
||||||
|
// protobuffer PROTO
|
||||||
|
#include "message.pb.h"
|
||||||
|
|
||||||
|
class QTcpSocket;
|
||||||
|
class QTimer;
|
||||||
|
class Hyperion;
|
||||||
|
|
||||||
|
namespace proto {
|
||||||
|
class HyperionRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The Connection object created by a ProtoServer when a new connection is established
|
||||||
|
///
|
||||||
|
class ProtoClientConnection : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
///
|
||||||
|
/// @brief Construct the client
|
||||||
|
/// @param socket The socket
|
||||||
|
/// @param timeout The timeout when a client is automatically disconnected and the priority unregistered
|
||||||
|
/// @param parent The parent
|
||||||
|
///
|
||||||
|
explicit ProtoClientConnection(QTcpSocket* socket, const int &timeout, QObject *parent);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
///
|
||||||
|
/// @brief Emits whenever the client disconnected
|
||||||
|
///
|
||||||
|
void clientDisconnected();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
///
|
||||||
|
/// @brief close the socket and call disconnected()
|
||||||
|
///
|
||||||
|
void forceClose();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
///
|
||||||
|
/// @brief Is called whenever the socket got new data to read
|
||||||
|
///
|
||||||
|
void readyRead();
|
||||||
|
|
||||||
|
///
|
||||||
|
/// @brief Is called when the socket closed the connection, also requests thread exit
|
||||||
|
///
|
||||||
|
void disconnected();
|
||||||
|
|
||||||
|
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:
|
||||||
|
Logger*_log;
|
||||||
|
|
||||||
|
/// The TCP-Socket that is connected tot the Proto-client
|
||||||
|
QTcpSocket* _socket;
|
||||||
|
|
||||||
|
/// address of client
|
||||||
|
const QString _clientAddress;
|
||||||
|
|
||||||
|
QTimer*_timeoutTimer;
|
||||||
|
int _timeout;
|
||||||
|
int _priority;
|
||||||
|
|
||||||
|
/// Link to Hyperion for writing led-values to a priority channel
|
||||||
|
Hyperion* _hyperion;
|
||||||
|
|
||||||
|
/// The buffer used for reading data from the socket
|
||||||
|
QByteArray _receiveBuffer;
|
||||||
|
};
|
104
libsrc/protoserver/ProtoServer.cpp
Normal file
104
libsrc/protoserver/ProtoServer.cpp
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
#include <protoserver/ProtoServer.h>
|
||||||
|
#include "ProtoClientConnection.h"
|
||||||
|
|
||||||
|
// qt
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QTcpServer>
|
||||||
|
#include <QTcpSocket>
|
||||||
|
|
||||||
|
ProtoServer::ProtoServer(const QJsonDocument& config, QObject* parent)
|
||||||
|
: QObject(parent)
|
||||||
|
, _server(new QTcpServer(this))
|
||||||
|
, _log(Logger::getInstance("PROTOSERVER"))
|
||||||
|
, _timeout(5000)
|
||||||
|
, _config(config)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ProtoServer::~ProtoServer()
|
||||||
|
{
|
||||||
|
stopServer();
|
||||||
|
delete _server;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtoServer::initServer()
|
||||||
|
{
|
||||||
|
connect(_server, &QTcpServer::newConnection, this, &ProtoServer::newConnection);
|
||||||
|
|
||||||
|
// apply config
|
||||||
|
handleSettingsUpdate(settings::PROTOSERVER, _config);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtoServer::handleSettingsUpdate(const settings::type& type, const QJsonDocument& config)
|
||||||
|
{
|
||||||
|
if(type == settings::PROTOSERVER)
|
||||||
|
{
|
||||||
|
const QJsonObject& obj = config.object();
|
||||||
|
|
||||||
|
quint16 port = obj["port"].toInt(19445);
|
||||||
|
|
||||||
|
// port check
|
||||||
|
if(_server->serverPort() != port)
|
||||||
|
{
|
||||||
|
stopServer();
|
||||||
|
_port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
// new timeout just for new connections
|
||||||
|
_timeout = obj["timeout"].toInt(5000);
|
||||||
|
// enable check
|
||||||
|
obj["enable"].toBool(true) ? startServer() : stopServer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtoServer::newConnection()
|
||||||
|
{
|
||||||
|
while(_server->hasPendingConnections())
|
||||||
|
{
|
||||||
|
if(QTcpSocket * socket = _server->nextPendingConnection())
|
||||||
|
{
|
||||||
|
Debug(_log, "New connection from %s", QSTRING_CSTR(socket->peerAddress().toString()));
|
||||||
|
ProtoClientConnection * client = new ProtoClientConnection(socket, _timeout, this);
|
||||||
|
// internal
|
||||||
|
connect(client, &ProtoClientConnection::clientDisconnected, this, &ProtoServer::clientDisconnected);
|
||||||
|
_openConnections.append(client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtoServer::clientDisconnected()
|
||||||
|
{
|
||||||
|
ProtoClientConnection* client = qobject_cast<ProtoClientConnection*>(sender());
|
||||||
|
client->deleteLater();
|
||||||
|
_openConnections.removeAll(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtoServer::startServer()
|
||||||
|
{
|
||||||
|
if(!_server->isListening())
|
||||||
|
{
|
||||||
|
if(!_server->listen(QHostAddress::Any, _port))
|
||||||
|
{
|
||||||
|
Error(_log,"Failed to bind port %d", _port);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Info(_log,"Started on port %d", _port);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtoServer::stopServer()
|
||||||
|
{
|
||||||
|
if(_server->isListening())
|
||||||
|
{
|
||||||
|
// close client connections
|
||||||
|
for(const auto& client : _openConnections)
|
||||||
|
{
|
||||||
|
client->forceClose();
|
||||||
|
}
|
||||||
|
_server->close();
|
||||||
|
Info(_log, "Stopped");
|
||||||
|
}
|
||||||
|
}
|
80
libsrc/protoserver/message.proto
Normal file
80
libsrc/protoserver/message.proto
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
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;
|
||||||
|
}
|
@ -5,6 +5,7 @@
|
|||||||
#include <bonjour/bonjourserviceregister.h>
|
#include <bonjour/bonjourserviceregister.h>
|
||||||
|
|
||||||
// hyperion includes
|
// hyperion includes
|
||||||
|
#include <hyperion/Hyperion.h>
|
||||||
#include "HyperionConfig.h"
|
#include "HyperionConfig.h"
|
||||||
|
|
||||||
// qt includes
|
// qt includes
|
||||||
@ -22,6 +23,9 @@ UDPListener::UDPListener(const QJsonDocument& config) :
|
|||||||
_isActive(false),
|
_isActive(false),
|
||||||
_listenPort(0)
|
_listenPort(0)
|
||||||
{
|
{
|
||||||
|
// listen for component change
|
||||||
|
connect(Hyperion::getInstance(), &Hyperion::componentStateChanged, this, &UDPListener::componentStateChanged);
|
||||||
|
|
||||||
// init
|
// init
|
||||||
handleSettingsUpdate(settings::UDPLISTENER, config);
|
handleSettingsUpdate(settings::UDPLISTENER, config);
|
||||||
}
|
}
|
||||||
@ -70,6 +74,8 @@ void UDPListener::start()
|
|||||||
_serviceRegister->registerService("_hyperiond-udp._udp", _listenPort);
|
_serviceRegister->registerService("_hyperiond-udp._udp", _listenPort);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Hyperion::getInstance()->getComponentRegister().componentStateChanged(COMP_UDPLISTENER, _isActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPListener::stop()
|
void UDPListener::stop()
|
||||||
@ -80,7 +86,7 @@ void UDPListener::stop()
|
|||||||
_server->close();
|
_server->close();
|
||||||
_isActive = false;
|
_isActive = false;
|
||||||
Info(_log, "Stopped");
|
Info(_log, "Stopped");
|
||||||
// emit clearGlobalPriority(_priority, hyperion::COMP_UDPLISTENER);
|
Hyperion::getInstance()->getComponentRegister().componentStateChanged(COMP_UDPLISTENER, _isActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPListener::componentStateChanged(const hyperion::Components component, bool enable)
|
void UDPListener::componentStateChanged(const hyperion::Components component, bool enable)
|
||||||
|
@ -17,6 +17,7 @@ target_link_libraries(hyperiond
|
|||||||
jsonserver
|
jsonserver
|
||||||
udplistener
|
udplistener
|
||||||
flatbufserver
|
flatbufserver
|
||||||
|
protoserver
|
||||||
webserver
|
webserver
|
||||||
bonjour
|
bonjour
|
||||||
ssdp
|
ssdp
|
||||||
|
@ -26,9 +26,12 @@
|
|||||||
#include <HyperionConfig.h> // Required to determine the cmake options
|
#include <HyperionConfig.h> // Required to determine the cmake options
|
||||||
#include "hyperiond.h"
|
#include "hyperiond.h"
|
||||||
|
|
||||||
// FlatBufferServer
|
// Flatbuffer Server
|
||||||
#include <flatbufserver/FlatBufferServer.h>
|
#include <flatbufserver/FlatBufferServer.h>
|
||||||
|
|
||||||
|
// Protobuffer Server
|
||||||
|
#include <protoserver/ProtoServer.h>
|
||||||
|
|
||||||
// bonjour browser
|
// bonjour browser
|
||||||
#include <bonjour/bonjourbrowserwrapper.h>
|
#include <bonjour/bonjourbrowserwrapper.h>
|
||||||
|
|
||||||
@ -145,6 +148,8 @@ void HyperionDaemon::freeObjects()
|
|||||||
delete _jsonServer;
|
delete _jsonServer;
|
||||||
_flatBufferServer->thread()->quit();
|
_flatBufferServer->thread()->quit();
|
||||||
_flatBufferServer->thread()->wait(1000);
|
_flatBufferServer->thread()->wait(1000);
|
||||||
|
_protoServer->thread()->quit();
|
||||||
|
_protoServer->thread()->wait(1000);
|
||||||
//ssdp before webserver
|
//ssdp before webserver
|
||||||
_ssdp->thread()->quit();
|
_ssdp->thread()->quit();
|
||||||
_ssdp->thread()->wait(1000);
|
_ssdp->thread()->wait(1000);
|
||||||
@ -166,17 +171,18 @@ void HyperionDaemon::freeObjects()
|
|||||||
|
|
||||||
_v4l2Grabbers.clear();
|
_v4l2Grabbers.clear();
|
||||||
_bonjourBrowserWrapper = nullptr;
|
_bonjourBrowserWrapper = nullptr;
|
||||||
_amlGrabber = nullptr;
|
_amlGrabber = nullptr;
|
||||||
_dispmanx = nullptr;
|
_dispmanx = nullptr;
|
||||||
_fbGrabber = nullptr;
|
_fbGrabber = nullptr;
|
||||||
_osxGrabber = nullptr;
|
_osxGrabber = nullptr;
|
||||||
_qtGrabber = nullptr;
|
_qtGrabber = nullptr;
|
||||||
_flatBufferServer = nullptr;
|
_flatBufferServer = nullptr;
|
||||||
_ssdp = nullptr;
|
_protoServer = nullptr;
|
||||||
_webserver = nullptr;
|
_ssdp = nullptr;
|
||||||
_jsonServer = nullptr;
|
_webserver = nullptr;
|
||||||
_udpListener = nullptr;
|
_jsonServer = nullptr;
|
||||||
_stats = nullptr;
|
_udpListener = nullptr;
|
||||||
|
_stats = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HyperionDaemon::startNetworkServices()
|
void HyperionDaemon::startNetworkServices()
|
||||||
@ -198,6 +204,16 @@ void HyperionDaemon::startNetworkServices()
|
|||||||
connect(this, &HyperionDaemon::settingsChanged, _flatBufferServer, &FlatBufferServer::handleSettingsUpdate);
|
connect(this, &HyperionDaemon::settingsChanged, _flatBufferServer, &FlatBufferServer::handleSettingsUpdate);
|
||||||
fbThread->start();
|
fbThread->start();
|
||||||
|
|
||||||
|
// Create Proto server in thread
|
||||||
|
_protoServer = new ProtoServer(getSetting(settings::PROTOSERVER));
|
||||||
|
QThread* pThread = new QThread(this);
|
||||||
|
_protoServer->moveToThread(pThread);
|
||||||
|
connect( pThread, &QThread::started, _protoServer, &ProtoServer::initServer );
|
||||||
|
connect( pThread, &QThread::finished, _protoServer, &QObject::deleteLater );
|
||||||
|
connect( pThread, &QThread::finished, pThread, &QObject::deleteLater );
|
||||||
|
connect(this, &HyperionDaemon::settingsChanged, _protoServer, &ProtoServer::handleSettingsUpdate);
|
||||||
|
pThread->start();
|
||||||
|
|
||||||
// Create UDP listener
|
// Create UDP listener
|
||||||
_udpListener = new UDPListener(getSetting(settings::UDPLISTENER));
|
_udpListener = new UDPListener(getSetting(settings::UDPLISTENER));
|
||||||
connect(this, &HyperionDaemon::settingsChanged, _udpListener, &UDPListener::handleSettingsUpdate);
|
connect(this, &HyperionDaemon::settingsChanged, _udpListener, &UDPListener::handleSettingsUpdate);
|
||||||
|
@ -63,6 +63,7 @@ class SettingsManager;
|
|||||||
class PythonInit;
|
class PythonInit;
|
||||||
class SSDPHandler;
|
class SSDPHandler;
|
||||||
class FlatBufferServer;
|
class FlatBufferServer;
|
||||||
|
class ProtoServer;
|
||||||
|
|
||||||
class HyperionDaemon : public QObject
|
class HyperionDaemon : public QObject
|
||||||
{
|
{
|
||||||
@ -130,33 +131,34 @@ private:
|
|||||||
void createGrabberX11(const QJsonObject & grabberConfig);
|
void createGrabberX11(const QJsonObject & grabberConfig);
|
||||||
void createGrabberQt(const QJsonObject & grabberConfig);
|
void createGrabberQt(const QJsonObject & grabberConfig);
|
||||||
|
|
||||||
Logger* _log;
|
Logger* _log;
|
||||||
BonjourBrowserWrapper* _bonjourBrowserWrapper;
|
BonjourBrowserWrapper* _bonjourBrowserWrapper;
|
||||||
PythonInit* _pyInit;
|
PythonInit* _pyInit;
|
||||||
WebServer* _webserver;
|
WebServer* _webserver;
|
||||||
JsonServer* _jsonServer;
|
JsonServer* _jsonServer;
|
||||||
UDPListener* _udpListener;
|
UDPListener* _udpListener;
|
||||||
std::vector<V4L2Wrapper*> _v4l2Grabbers;
|
std::vector<V4L2Wrapper*> _v4l2Grabbers;
|
||||||
DispmanxWrapper* _dispmanx;
|
DispmanxWrapper* _dispmanx;
|
||||||
X11Wrapper* _x11Grabber;
|
X11Wrapper* _x11Grabber;
|
||||||
AmlogicWrapper* _amlGrabber;
|
AmlogicWrapper* _amlGrabber;
|
||||||
FramebufferWrapper* _fbGrabber;
|
FramebufferWrapper* _fbGrabber;
|
||||||
OsxWrapper* _osxGrabber;
|
OsxWrapper* _osxGrabber;
|
||||||
QtWrapper* _qtGrabber;
|
QtWrapper* _qtGrabber;
|
||||||
Hyperion* _hyperion;
|
Hyperion* _hyperion;
|
||||||
Stats* _stats;
|
Stats* _stats;
|
||||||
SSDPHandler* _ssdp;
|
SSDPHandler* _ssdp;
|
||||||
FlatBufferServer* _flatBufferServer;
|
FlatBufferServer* _flatBufferServer;
|
||||||
|
ProtoServer* _protoServer;
|
||||||
|
|
||||||
unsigned _grabber_width;
|
unsigned _grabber_width;
|
||||||
unsigned _grabber_height;
|
unsigned _grabber_height;
|
||||||
unsigned _grabber_frequency;
|
unsigned _grabber_frequency;
|
||||||
unsigned _grabber_cropLeft;
|
unsigned _grabber_cropLeft;
|
||||||
unsigned _grabber_cropRight;
|
unsigned _grabber_cropRight;
|
||||||
unsigned _grabber_cropTop;
|
unsigned _grabber_cropTop;
|
||||||
unsigned _grabber_cropBottom;
|
unsigned _grabber_cropBottom;
|
||||||
int _grabber_ge2d_mode;
|
int _grabber_ge2d_mode;
|
||||||
QString _grabber_device;
|
QString _grabber_device;
|
||||||
|
|
||||||
QString _prevType;
|
QString _prevType;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user