Dev
This commit is contained in:
parent
0ae56e062c
commit
75f1a4d1c3
BIN
Lib/QtHTTPServer/Qt5HttpServer.dll
Normal file
BIN
Lib/QtHTTPServer/Qt5HttpServer.dll
Normal file
Binary file not shown.
BIN
Lib/QtHTTPServer/Qt5HttpServer.dll.debug
Normal file
BIN
Lib/QtHTTPServer/Qt5HttpServer.dll.debug
Normal file
Binary file not shown.
5
Lib/QtHTTPServer/Qt5HttpServer.prl
Normal file
5
Lib/QtHTTPServer/Qt5HttpServer.prl
Normal file
@ -0,0 +1,5 @@
|
||||
QMAKE_PRL_BUILD_DIR = D:/Main/Dev/qthttpserver/src/httpserver
|
||||
QMAKE_PRO_INPUT = httpserver.pro
|
||||
QMAKE_PRL_TARGET = libQt5HttpServer.a
|
||||
QMAKE_PRL_CONFIG = lex yacc depend_includepath testcase_targets import_plugins import_qpa_plugin windows prepare_docs qt_docs_targets qt_build_extra file_copies qmake_use qt warn_on release link_prl debug_and_release precompile_header shared shared release no_plugin_manifest win32 mingw gcc copy_dir_files sse2 aesni sse3 ssse3 sse4_1 sse4_2 compile_examples force_debug_info largefile precompile_header rdrnd shani x86SimdAlways prefix_build force_independent utf8_source create_prl link_prl no_private_qt_headers_warning QTDIR_build qt_example_installs exceptions_off testcase_exceptions release ReleaseBuild Release build_pass qml_debug release ReleaseBuild Release build_pass relative_qt_rpath git_build target_qt c++11 strict_c++ c++14 c++1z c99 c11 separate_debug_info qt_install_headers need_fwd_pri qt_install_module create_cmake skip_target_version_ext compiler_supports_fpmath create_pc release ReleaseBuild Release build_pass have_target dll exclusive_builds debug_info no_autoqmake thread moc resources
|
||||
QMAKE_PRL_VERSION = 5.12.0
|
||||
BIN
Lib/QtHTTPServer/Qt5SslServer.dll
Normal file
BIN
Lib/QtHTTPServer/Qt5SslServer.dll
Normal file
Binary file not shown.
BIN
Lib/QtHTTPServer/Qt5SslServer.dll.debug
Normal file
BIN
Lib/QtHTTPServer/Qt5SslServer.dll.debug
Normal file
Binary file not shown.
5
Lib/QtHTTPServer/Qt5SslServer.prl
Normal file
5
Lib/QtHTTPServer/Qt5SslServer.prl
Normal file
@ -0,0 +1,5 @@
|
||||
QMAKE_PRL_BUILD_DIR = D:/Main/Dev/qthttpserver/src/sslserver
|
||||
QMAKE_PRO_INPUT = sslserver.pro
|
||||
QMAKE_PRL_TARGET = libQt5SslServer.a
|
||||
QMAKE_PRL_CONFIG = lex yacc depend_includepath testcase_targets import_plugins import_qpa_plugin windows prepare_docs qt_docs_targets qt_build_extra file_copies qmake_use qt warn_on release link_prl debug_and_release shared shared release no_plugin_manifest win32 mingw gcc copy_dir_files sse2 aesni sse3 ssse3 sse4_1 sse4_2 compile_examples force_debug_info largefile rdrnd shani x86SimdAlways prefix_build force_independent utf8_source create_prl link_prl no_private_qt_headers_warning QTDIR_build qt_example_installs exceptions_off testcase_exceptions release ReleaseBuild Release build_pass qml_debug release ReleaseBuild Release build_pass relative_qt_rpath git_build target_qt c++11 strict_c++ c++14 c++1z c99 c11 separate_debug_info qt_install_headers need_fwd_pri qt_install_module create_cmake skip_target_version_ext compiler_supports_fpmath create_pc release ReleaseBuild Release build_pass have_target dll exclusive_builds debug_info no_autoqmake thread moc resources
|
||||
QMAKE_PRL_VERSION = 5.12.0
|
||||
223
Lib/QtHTTPServer/cmake/Qt5HttpServer/Qt5HttpServerConfig.cmake
Normal file
223
Lib/QtHTTPServer/cmake/Qt5HttpServer/Qt5HttpServerConfig.cmake
Normal file
@ -0,0 +1,223 @@
|
||||
|
||||
if (CMAKE_VERSION VERSION_LESS 3.1.0)
|
||||
message(FATAL_ERROR "Qt 5 HttpServer module requires at least CMake version 3.1.0")
|
||||
endif()
|
||||
|
||||
get_filename_component(_qt5HttpServer_install_prefix "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
|
||||
|
||||
# For backwards compatibility only. Use Qt5HttpServer_VERSION instead.
|
||||
set(Qt5HttpServer_VERSION_STRING 5.12.0)
|
||||
|
||||
set(Qt5HttpServer_LIBRARIES Qt5::HttpServer)
|
||||
|
||||
macro(_qt5_HttpServer_check_file_exists file)
|
||||
if(NOT EXISTS "${file}" )
|
||||
message(FATAL_ERROR "The imported target \"Qt5::HttpServer\" references the file
|
||||
\"${file}\"
|
||||
but this file does not exist. Possible reasons include:
|
||||
* The file was deleted, renamed, or moved to another location.
|
||||
* An install or uninstall procedure did not complete successfully.
|
||||
* The installation package was faulty and contained
|
||||
\"${CMAKE_CURRENT_LIST_FILE}\"
|
||||
but not all the files it references.
|
||||
")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(_populate_HttpServer_target_properties Configuration LIB_LOCATION IMPLIB_LOCATION
|
||||
IsDebugAndRelease)
|
||||
set_property(TARGET Qt5::HttpServer APPEND PROPERTY IMPORTED_CONFIGURATIONS ${Configuration})
|
||||
|
||||
set(imported_location "${_qt5HttpServer_install_prefix}/bin/${LIB_LOCATION}")
|
||||
_qt5_HttpServer_check_file_exists(${imported_location})
|
||||
set(_deps
|
||||
${_Qt5HttpServer_LIB_DEPENDENCIES}
|
||||
)
|
||||
set(_static_deps
|
||||
)
|
||||
|
||||
set_target_properties(Qt5::HttpServer PROPERTIES
|
||||
"IMPORTED_LOCATION_${Configuration}" ${imported_location}
|
||||
# For backward compatibility with CMake < 2.8.12
|
||||
"IMPORTED_LINK_INTERFACE_LIBRARIES_${Configuration}" "${_deps};${_static_deps}"
|
||||
)
|
||||
set_property(TARGET Qt5::HttpServer APPEND PROPERTY INTERFACE_LINK_LIBRARIES
|
||||
"${_deps}"
|
||||
)
|
||||
|
||||
|
||||
set(imported_implib "${_qt5HttpServer_install_prefix}/lib/${IMPLIB_LOCATION}")
|
||||
_qt5_HttpServer_check_file_exists(${imported_implib})
|
||||
if(NOT "${IMPLIB_LOCATION}" STREQUAL "")
|
||||
set_target_properties(Qt5::HttpServer PROPERTIES
|
||||
"IMPORTED_IMPLIB_${Configuration}" ${imported_implib}
|
||||
)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
if (NOT TARGET Qt5::HttpServer)
|
||||
|
||||
set(_Qt5HttpServer_OWN_INCLUDE_DIRS "${_qt5HttpServer_install_prefix}/include/" "${_qt5HttpServer_install_prefix}/include/QtHttpServer")
|
||||
set(Qt5HttpServer_PRIVATE_INCLUDE_DIRS
|
||||
"${_qt5HttpServer_install_prefix}/include/QtHttpServer/5.12.0"
|
||||
"${_qt5HttpServer_install_prefix}/include/QtHttpServer/5.12.0/QtHttpServer"
|
||||
)
|
||||
|
||||
foreach(_dir ${_Qt5HttpServer_OWN_INCLUDE_DIRS})
|
||||
_qt5_HttpServer_check_file_exists(${_dir})
|
||||
endforeach()
|
||||
|
||||
# Only check existence of private includes if the Private component is
|
||||
# specified.
|
||||
list(FIND Qt5HttpServer_FIND_COMPONENTS Private _check_private)
|
||||
if (NOT _check_private STREQUAL -1)
|
||||
foreach(_dir ${Qt5HttpServer_PRIVATE_INCLUDE_DIRS})
|
||||
_qt5_HttpServer_check_file_exists(${_dir})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
set(Qt5HttpServer_INCLUDE_DIRS ${_Qt5HttpServer_OWN_INCLUDE_DIRS})
|
||||
|
||||
set(Qt5HttpServer_DEFINITIONS -DQT_HTTPSERVER_LIB)
|
||||
set(Qt5HttpServer_COMPILE_DEFINITIONS QT_HTTPSERVER_LIB)
|
||||
set(_Qt5HttpServer_MODULE_DEPENDENCIES "SslServer;WebSockets;Network;Concurrent;Core")
|
||||
|
||||
|
||||
set(Qt5HttpServer_OWN_PRIVATE_INCLUDE_DIRS ${Qt5HttpServer_PRIVATE_INCLUDE_DIRS})
|
||||
|
||||
set(_Qt5HttpServer_FIND_DEPENDENCIES_REQUIRED)
|
||||
if (Qt5HttpServer_FIND_REQUIRED)
|
||||
set(_Qt5HttpServer_FIND_DEPENDENCIES_REQUIRED REQUIRED)
|
||||
endif()
|
||||
set(_Qt5HttpServer_FIND_DEPENDENCIES_QUIET)
|
||||
if (Qt5HttpServer_FIND_QUIETLY)
|
||||
set(_Qt5HttpServer_DEPENDENCIES_FIND_QUIET QUIET)
|
||||
endif()
|
||||
set(_Qt5HttpServer_FIND_VERSION_EXACT)
|
||||
if (Qt5HttpServer_FIND_VERSION_EXACT)
|
||||
set(_Qt5HttpServer_FIND_VERSION_EXACT EXACT)
|
||||
endif()
|
||||
|
||||
set(Qt5HttpServer_EXECUTABLE_COMPILE_FLAGS "")
|
||||
|
||||
foreach(_module_dep ${_Qt5HttpServer_MODULE_DEPENDENCIES})
|
||||
if (NOT Qt5${_module_dep}_FOUND)
|
||||
find_package(Qt5${_module_dep}
|
||||
5.12.0 ${_Qt5HttpServer_FIND_VERSION_EXACT}
|
||||
${_Qt5HttpServer_DEPENDENCIES_FIND_QUIET}
|
||||
${_Qt5HttpServer_FIND_DEPENDENCIES_REQUIRED}
|
||||
PATHS "${CMAKE_CURRENT_LIST_DIR}/.." NO_DEFAULT_PATH
|
||||
)
|
||||
endif()
|
||||
|
||||
if (NOT Qt5${_module_dep}_FOUND)
|
||||
set(Qt5HttpServer_FOUND False)
|
||||
return()
|
||||
endif()
|
||||
|
||||
list(APPEND Qt5HttpServer_INCLUDE_DIRS "${Qt5${_module_dep}_INCLUDE_DIRS}")
|
||||
list(APPEND Qt5HttpServer_PRIVATE_INCLUDE_DIRS "${Qt5${_module_dep}_PRIVATE_INCLUDE_DIRS}")
|
||||
list(APPEND Qt5HttpServer_DEFINITIONS ${Qt5${_module_dep}_DEFINITIONS})
|
||||
list(APPEND Qt5HttpServer_COMPILE_DEFINITIONS ${Qt5${_module_dep}_COMPILE_DEFINITIONS})
|
||||
list(APPEND Qt5HttpServer_EXECUTABLE_COMPILE_FLAGS ${Qt5${_module_dep}_EXECUTABLE_COMPILE_FLAGS})
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES Qt5HttpServer_INCLUDE_DIRS)
|
||||
list(REMOVE_DUPLICATES Qt5HttpServer_PRIVATE_INCLUDE_DIRS)
|
||||
list(REMOVE_DUPLICATES Qt5HttpServer_DEFINITIONS)
|
||||
list(REMOVE_DUPLICATES Qt5HttpServer_COMPILE_DEFINITIONS)
|
||||
list(REMOVE_DUPLICATES Qt5HttpServer_EXECUTABLE_COMPILE_FLAGS)
|
||||
|
||||
# It can happen that the same FooConfig.cmake file is included when calling find_package()
|
||||
# on some Qt component. An example of that is when using a Qt static build with auto inclusion
|
||||
# of plugins:
|
||||
#
|
||||
# Qt5WidgetsConfig.cmake -> Qt5GuiConfig.cmake -> Qt5Gui_QSvgIconPlugin.cmake ->
|
||||
# Qt5SvgConfig.cmake -> Qt5WidgetsConfig.cmake ->
|
||||
# finish processing of second Qt5WidgetsConfig.cmake ->
|
||||
# return to first Qt5WidgetsConfig.cmake ->
|
||||
# add_library cannot create imported target Qt5::Widgets.
|
||||
#
|
||||
# Make sure to return early in the original Config inclusion, because the target has already
|
||||
# been defined as part of the second inclusion.
|
||||
if(TARGET Qt5::HttpServer)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(_Qt5HttpServer_LIB_DEPENDENCIES "Qt5::SslServer;Qt5::WebSockets;Qt5::Network;Qt5::Concurrent;Qt5::Core")
|
||||
|
||||
|
||||
add_library(Qt5::HttpServer SHARED IMPORTED)
|
||||
|
||||
set_property(TARGET Qt5::HttpServer PROPERTY
|
||||
INTERFACE_INCLUDE_DIRECTORIES ${_Qt5HttpServer_OWN_INCLUDE_DIRS})
|
||||
set_property(TARGET Qt5::HttpServer PROPERTY
|
||||
INTERFACE_COMPILE_DEFINITIONS QT_HTTPSERVER_LIB)
|
||||
|
||||
set_property(TARGET Qt5::HttpServer PROPERTY INTERFACE_QT_ENABLED_FEATURES )
|
||||
set_property(TARGET Qt5::HttpServer PROPERTY INTERFACE_QT_DISABLED_FEATURES )
|
||||
|
||||
set_property(TARGET Qt5::HttpServer PROPERTY INTERFACE_QT_PLUGIN_TYPES "")
|
||||
|
||||
set(_Qt5HttpServer_PRIVATE_DIRS_EXIST TRUE)
|
||||
foreach (_Qt5HttpServer_PRIVATE_DIR ${Qt5HttpServer_OWN_PRIVATE_INCLUDE_DIRS})
|
||||
if (NOT EXISTS ${_Qt5HttpServer_PRIVATE_DIR})
|
||||
set(_Qt5HttpServer_PRIVATE_DIRS_EXIST FALSE)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if (_Qt5HttpServer_PRIVATE_DIRS_EXIST)
|
||||
add_library(Qt5::HttpServerPrivate INTERFACE IMPORTED)
|
||||
set_property(TARGET Qt5::HttpServerPrivate PROPERTY
|
||||
INTERFACE_INCLUDE_DIRECTORIES ${Qt5HttpServer_OWN_PRIVATE_INCLUDE_DIRS}
|
||||
)
|
||||
set(_Qt5HttpServer_PRIVATEDEPS)
|
||||
foreach(dep ${_Qt5HttpServer_LIB_DEPENDENCIES})
|
||||
if (TARGET ${dep}Private)
|
||||
list(APPEND _Qt5HttpServer_PRIVATEDEPS ${dep}Private)
|
||||
endif()
|
||||
endforeach()
|
||||
set_property(TARGET Qt5::HttpServerPrivate PROPERTY
|
||||
INTERFACE_LINK_LIBRARIES Qt5::HttpServer ${_Qt5HttpServer_PRIVATEDEPS}
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
_populate_HttpServer_target_properties(DEBUG "Qt5HttpServer.dll" "libQt5HttpServer.a" FALSE)
|
||||
|
||||
if (EXISTS
|
||||
"${_qt5HttpServer_install_prefix}/bin/Qt5HttpServer.dll"
|
||||
AND EXISTS
|
||||
"${_qt5HttpServer_install_prefix}/lib/libQt5HttpServer.a" )
|
||||
_populate_HttpServer_target_properties(RELEASE "Qt5HttpServer.dll" "libQt5HttpServer.a" FALSE)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
file(GLOB pluginTargets "${CMAKE_CURRENT_LIST_DIR}/Qt5HttpServer_*Plugin.cmake")
|
||||
|
||||
macro(_populate_HttpServer_plugin_properties Plugin Configuration PLUGIN_LOCATION
|
||||
IsDebugAndRelease)
|
||||
set_property(TARGET Qt5::${Plugin} APPEND PROPERTY IMPORTED_CONFIGURATIONS ${Configuration})
|
||||
|
||||
set(imported_location "${_qt5HttpServer_install_prefix}/plugins/${PLUGIN_LOCATION}")
|
||||
_qt5_HttpServer_check_file_exists(${imported_location})
|
||||
set_target_properties(Qt5::${Plugin} PROPERTIES
|
||||
"IMPORTED_LOCATION_${Configuration}" ${imported_location}
|
||||
)
|
||||
|
||||
endmacro()
|
||||
|
||||
if (pluginTargets)
|
||||
foreach(pluginTarget ${pluginTargets})
|
||||
include(${pluginTarget})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
_qt5_HttpServer_check_file_exists("${CMAKE_CURRENT_LIST_DIR}/Qt5HttpServerConfigVersion.cmake")
|
||||
|
||||
endif()
|
||||
@ -0,0 +1,11 @@
|
||||
|
||||
set(PACKAGE_VERSION 5.12.0)
|
||||
|
||||
if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
|
||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||
else()
|
||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||
if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
|
||||
set(PACKAGE_VERSION_EXACT TRUE)
|
||||
endif()
|
||||
endif()
|
||||
223
Lib/QtHTTPServer/cmake/Qt5SslServer/Qt5SslServerConfig.cmake
Normal file
223
Lib/QtHTTPServer/cmake/Qt5SslServer/Qt5SslServerConfig.cmake
Normal file
@ -0,0 +1,223 @@
|
||||
|
||||
if (CMAKE_VERSION VERSION_LESS 3.1.0)
|
||||
message(FATAL_ERROR "Qt 5 SslServer module requires at least CMake version 3.1.0")
|
||||
endif()
|
||||
|
||||
get_filename_component(_qt5SslServer_install_prefix "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
|
||||
|
||||
# For backwards compatibility only. Use Qt5SslServer_VERSION instead.
|
||||
set(Qt5SslServer_VERSION_STRING 5.12.0)
|
||||
|
||||
set(Qt5SslServer_LIBRARIES Qt5::SslServer)
|
||||
|
||||
macro(_qt5_SslServer_check_file_exists file)
|
||||
if(NOT EXISTS "${file}" )
|
||||
message(FATAL_ERROR "The imported target \"Qt5::SslServer\" references the file
|
||||
\"${file}\"
|
||||
but this file does not exist. Possible reasons include:
|
||||
* The file was deleted, renamed, or moved to another location.
|
||||
* An install or uninstall procedure did not complete successfully.
|
||||
* The installation package was faulty and contained
|
||||
\"${CMAKE_CURRENT_LIST_FILE}\"
|
||||
but not all the files it references.
|
||||
")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
||||
macro(_populate_SslServer_target_properties Configuration LIB_LOCATION IMPLIB_LOCATION
|
||||
IsDebugAndRelease)
|
||||
set_property(TARGET Qt5::SslServer APPEND PROPERTY IMPORTED_CONFIGURATIONS ${Configuration})
|
||||
|
||||
set(imported_location "${_qt5SslServer_install_prefix}/bin/${LIB_LOCATION}")
|
||||
_qt5_SslServer_check_file_exists(${imported_location})
|
||||
set(_deps
|
||||
${_Qt5SslServer_LIB_DEPENDENCIES}
|
||||
)
|
||||
set(_static_deps
|
||||
)
|
||||
|
||||
set_target_properties(Qt5::SslServer PROPERTIES
|
||||
"IMPORTED_LOCATION_${Configuration}" ${imported_location}
|
||||
# For backward compatibility with CMake < 2.8.12
|
||||
"IMPORTED_LINK_INTERFACE_LIBRARIES_${Configuration}" "${_deps};${_static_deps}"
|
||||
)
|
||||
set_property(TARGET Qt5::SslServer APPEND PROPERTY INTERFACE_LINK_LIBRARIES
|
||||
"${_deps}"
|
||||
)
|
||||
|
||||
|
||||
set(imported_implib "${_qt5SslServer_install_prefix}/lib/${IMPLIB_LOCATION}")
|
||||
_qt5_SslServer_check_file_exists(${imported_implib})
|
||||
if(NOT "${IMPLIB_LOCATION}" STREQUAL "")
|
||||
set_target_properties(Qt5::SslServer PROPERTIES
|
||||
"IMPORTED_IMPLIB_${Configuration}" ${imported_implib}
|
||||
)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
if (NOT TARGET Qt5::SslServer)
|
||||
|
||||
set(_Qt5SslServer_OWN_INCLUDE_DIRS "${_qt5SslServer_install_prefix}/include/" "${_qt5SslServer_install_prefix}/include/QtSslServer")
|
||||
set(Qt5SslServer_PRIVATE_INCLUDE_DIRS
|
||||
"${_qt5SslServer_install_prefix}/include/QtSslServer/5.12.0"
|
||||
"${_qt5SslServer_install_prefix}/include/QtSslServer/5.12.0/QtSslServer"
|
||||
)
|
||||
|
||||
foreach(_dir ${_Qt5SslServer_OWN_INCLUDE_DIRS})
|
||||
_qt5_SslServer_check_file_exists(${_dir})
|
||||
endforeach()
|
||||
|
||||
# Only check existence of private includes if the Private component is
|
||||
# specified.
|
||||
list(FIND Qt5SslServer_FIND_COMPONENTS Private _check_private)
|
||||
if (NOT _check_private STREQUAL -1)
|
||||
foreach(_dir ${Qt5SslServer_PRIVATE_INCLUDE_DIRS})
|
||||
_qt5_SslServer_check_file_exists(${_dir})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
set(Qt5SslServer_INCLUDE_DIRS ${_Qt5SslServer_OWN_INCLUDE_DIRS})
|
||||
|
||||
set(Qt5SslServer_DEFINITIONS -DQT_SSLSERVER_LIB)
|
||||
set(Qt5SslServer_COMPILE_DEFINITIONS QT_SSLSERVER_LIB)
|
||||
set(_Qt5SslServer_MODULE_DEPENDENCIES "Network;Core")
|
||||
|
||||
|
||||
set(Qt5SslServer_OWN_PRIVATE_INCLUDE_DIRS ${Qt5SslServer_PRIVATE_INCLUDE_DIRS})
|
||||
|
||||
set(_Qt5SslServer_FIND_DEPENDENCIES_REQUIRED)
|
||||
if (Qt5SslServer_FIND_REQUIRED)
|
||||
set(_Qt5SslServer_FIND_DEPENDENCIES_REQUIRED REQUIRED)
|
||||
endif()
|
||||
set(_Qt5SslServer_FIND_DEPENDENCIES_QUIET)
|
||||
if (Qt5SslServer_FIND_QUIETLY)
|
||||
set(_Qt5SslServer_DEPENDENCIES_FIND_QUIET QUIET)
|
||||
endif()
|
||||
set(_Qt5SslServer_FIND_VERSION_EXACT)
|
||||
if (Qt5SslServer_FIND_VERSION_EXACT)
|
||||
set(_Qt5SslServer_FIND_VERSION_EXACT EXACT)
|
||||
endif()
|
||||
|
||||
set(Qt5SslServer_EXECUTABLE_COMPILE_FLAGS "")
|
||||
|
||||
foreach(_module_dep ${_Qt5SslServer_MODULE_DEPENDENCIES})
|
||||
if (NOT Qt5${_module_dep}_FOUND)
|
||||
find_package(Qt5${_module_dep}
|
||||
5.12.0 ${_Qt5SslServer_FIND_VERSION_EXACT}
|
||||
${_Qt5SslServer_DEPENDENCIES_FIND_QUIET}
|
||||
${_Qt5SslServer_FIND_DEPENDENCIES_REQUIRED}
|
||||
PATHS "${CMAKE_CURRENT_LIST_DIR}/.." NO_DEFAULT_PATH
|
||||
)
|
||||
endif()
|
||||
|
||||
if (NOT Qt5${_module_dep}_FOUND)
|
||||
set(Qt5SslServer_FOUND False)
|
||||
return()
|
||||
endif()
|
||||
|
||||
list(APPEND Qt5SslServer_INCLUDE_DIRS "${Qt5${_module_dep}_INCLUDE_DIRS}")
|
||||
list(APPEND Qt5SslServer_PRIVATE_INCLUDE_DIRS "${Qt5${_module_dep}_PRIVATE_INCLUDE_DIRS}")
|
||||
list(APPEND Qt5SslServer_DEFINITIONS ${Qt5${_module_dep}_DEFINITIONS})
|
||||
list(APPEND Qt5SslServer_COMPILE_DEFINITIONS ${Qt5${_module_dep}_COMPILE_DEFINITIONS})
|
||||
list(APPEND Qt5SslServer_EXECUTABLE_COMPILE_FLAGS ${Qt5${_module_dep}_EXECUTABLE_COMPILE_FLAGS})
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES Qt5SslServer_INCLUDE_DIRS)
|
||||
list(REMOVE_DUPLICATES Qt5SslServer_PRIVATE_INCLUDE_DIRS)
|
||||
list(REMOVE_DUPLICATES Qt5SslServer_DEFINITIONS)
|
||||
list(REMOVE_DUPLICATES Qt5SslServer_COMPILE_DEFINITIONS)
|
||||
list(REMOVE_DUPLICATES Qt5SslServer_EXECUTABLE_COMPILE_FLAGS)
|
||||
|
||||
# It can happen that the same FooConfig.cmake file is included when calling find_package()
|
||||
# on some Qt component. An example of that is when using a Qt static build with auto inclusion
|
||||
# of plugins:
|
||||
#
|
||||
# Qt5WidgetsConfig.cmake -> Qt5GuiConfig.cmake -> Qt5Gui_QSvgIconPlugin.cmake ->
|
||||
# Qt5SvgConfig.cmake -> Qt5WidgetsConfig.cmake ->
|
||||
# finish processing of second Qt5WidgetsConfig.cmake ->
|
||||
# return to first Qt5WidgetsConfig.cmake ->
|
||||
# add_library cannot create imported target Qt5::Widgets.
|
||||
#
|
||||
# Make sure to return early in the original Config inclusion, because the target has already
|
||||
# been defined as part of the second inclusion.
|
||||
if(TARGET Qt5::SslServer)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(_Qt5SslServer_LIB_DEPENDENCIES "Qt5::Network;Qt5::Core")
|
||||
|
||||
|
||||
add_library(Qt5::SslServer SHARED IMPORTED)
|
||||
|
||||
set_property(TARGET Qt5::SslServer PROPERTY
|
||||
INTERFACE_INCLUDE_DIRECTORIES ${_Qt5SslServer_OWN_INCLUDE_DIRS})
|
||||
set_property(TARGET Qt5::SslServer PROPERTY
|
||||
INTERFACE_COMPILE_DEFINITIONS QT_SSLSERVER_LIB)
|
||||
|
||||
set_property(TARGET Qt5::SslServer PROPERTY INTERFACE_QT_ENABLED_FEATURES )
|
||||
set_property(TARGET Qt5::SslServer PROPERTY INTERFACE_QT_DISABLED_FEATURES )
|
||||
|
||||
set_property(TARGET Qt5::SslServer PROPERTY INTERFACE_QT_PLUGIN_TYPES "")
|
||||
|
||||
set(_Qt5SslServer_PRIVATE_DIRS_EXIST TRUE)
|
||||
foreach (_Qt5SslServer_PRIVATE_DIR ${Qt5SslServer_OWN_PRIVATE_INCLUDE_DIRS})
|
||||
if (NOT EXISTS ${_Qt5SslServer_PRIVATE_DIR})
|
||||
set(_Qt5SslServer_PRIVATE_DIRS_EXIST FALSE)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if (_Qt5SslServer_PRIVATE_DIRS_EXIST)
|
||||
add_library(Qt5::SslServerPrivate INTERFACE IMPORTED)
|
||||
set_property(TARGET Qt5::SslServerPrivate PROPERTY
|
||||
INTERFACE_INCLUDE_DIRECTORIES ${Qt5SslServer_OWN_PRIVATE_INCLUDE_DIRS}
|
||||
)
|
||||
set(_Qt5SslServer_PRIVATEDEPS)
|
||||
foreach(dep ${_Qt5SslServer_LIB_DEPENDENCIES})
|
||||
if (TARGET ${dep}Private)
|
||||
list(APPEND _Qt5SslServer_PRIVATEDEPS ${dep}Private)
|
||||
endif()
|
||||
endforeach()
|
||||
set_property(TARGET Qt5::SslServerPrivate PROPERTY
|
||||
INTERFACE_LINK_LIBRARIES Qt5::SslServer ${_Qt5SslServer_PRIVATEDEPS}
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
_populate_SslServer_target_properties(DEBUG "Qt5SslServer.dll" "libQt5SslServer.a" FALSE)
|
||||
|
||||
if (EXISTS
|
||||
"${_qt5SslServer_install_prefix}/bin/Qt5SslServer.dll"
|
||||
AND EXISTS
|
||||
"${_qt5SslServer_install_prefix}/lib/libQt5SslServer.a" )
|
||||
_populate_SslServer_target_properties(RELEASE "Qt5SslServer.dll" "libQt5SslServer.a" FALSE)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
file(GLOB pluginTargets "${CMAKE_CURRENT_LIST_DIR}/Qt5SslServer_*Plugin.cmake")
|
||||
|
||||
macro(_populate_SslServer_plugin_properties Plugin Configuration PLUGIN_LOCATION
|
||||
IsDebugAndRelease)
|
||||
set_property(TARGET Qt5::${Plugin} APPEND PROPERTY IMPORTED_CONFIGURATIONS ${Configuration})
|
||||
|
||||
set(imported_location "${_qt5SslServer_install_prefix}/plugins/${PLUGIN_LOCATION}")
|
||||
_qt5_SslServer_check_file_exists(${imported_location})
|
||||
set_target_properties(Qt5::${Plugin} PROPERTIES
|
||||
"IMPORTED_LOCATION_${Configuration}" ${imported_location}
|
||||
)
|
||||
|
||||
endmacro()
|
||||
|
||||
if (pluginTargets)
|
||||
foreach(pluginTarget ${pluginTargets})
|
||||
include(${pluginTarget})
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
_qt5_SslServer_check_file_exists("${CMAKE_CURRENT_LIST_DIR}/Qt5SslServerConfigVersion.cmake")
|
||||
|
||||
endif()
|
||||
@ -0,0 +1,11 @@
|
||||
|
||||
set(PACKAGE_VERSION 5.12.0)
|
||||
|
||||
if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
|
||||
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||
else()
|
||||
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||
if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
|
||||
set(PACKAGE_VERSION_EXACT TRUE)
|
||||
endif()
|
||||
endif()
|
||||
97
Lib/QtHTTPServer/include/QtHttpServer/qabstracthttpserver.h
Normal file
97
Lib/QtHTTPServer/include/QtHttpServer/qabstracthttpserver.h
Normal file
@ -0,0 +1,97 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QABSTRACTHTTPSERVER_H
|
||||
#define QABSTRACTHTTPSERVER_H
|
||||
|
||||
#include <QtCore/qobject.h>
|
||||
|
||||
#include <QtHttpServer/qthttpserverglobal.h>
|
||||
|
||||
#include <QtNetwork/qhostaddress.h>
|
||||
|
||||
#if QT_CONFIG(ssl)
|
||||
#include <QtSslServer/qsslserver.h>
|
||||
#include <QSslCertificate>
|
||||
#include <QSslKey>
|
||||
#endif
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHttpServerRequest;
|
||||
class QHttpServerResponder;
|
||||
class QTcpServer;
|
||||
class QTcpSocket;
|
||||
class QWebSocket;
|
||||
|
||||
class QAbstractHttpServerPrivate;
|
||||
class Q_HTTPSERVER_EXPORT QAbstractHttpServer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QAbstractHttpServer(QObject *parent = nullptr);
|
||||
|
||||
quint16 listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0);
|
||||
QVector<quint16> serverPorts();
|
||||
|
||||
void bind(QTcpServer *server = nullptr);
|
||||
QVector<QTcpServer *> servers() const;
|
||||
|
||||
#if QT_CONFIG(ssl)
|
||||
void sslSetup(const QSslCertificate &certificate, const QSslKey &privateKey,
|
||||
QSsl::SslProtocol protocol = QSsl::SecureProtocols);
|
||||
void sslSetup(const QSslConfiguration &sslConfiguration);
|
||||
#endif
|
||||
|
||||
Q_SIGNALS:
|
||||
void missingHandler(const QHttpServerRequest &request, QTcpSocket *socket);
|
||||
|
||||
#if defined(QT_WEBSOCKETS_LIB)
|
||||
void newWebSocketConnection();
|
||||
|
||||
public:
|
||||
bool hasPendingWebSocketConnections() const;
|
||||
QWebSocket *nextPendingWebSocketConnection();
|
||||
#endif // defined(QT_WEBSOCKETS_LIB)
|
||||
|
||||
protected:
|
||||
QAbstractHttpServer(QAbstractHttpServerPrivate &dd, QObject *parent = nullptr);
|
||||
|
||||
virtual bool handleRequest(const QHttpServerRequest &request, QTcpSocket *socket) = 0;
|
||||
static QHttpServerResponder makeResponder(const QHttpServerRequest &request,
|
||||
QTcpSocket *socket);
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE(QAbstractHttpServer)
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QABSTRACTHTTPSERVER_H
|
||||
@ -0,0 +1,82 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QABSTRACTHTTPSERVER_P_H
|
||||
#define QABSTRACTHTTPSERVER_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of QHttpServer. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
|
||||
#include <QtHttpServer/qabstracthttpserver.h>
|
||||
#include <QtHttpServer/qthttpserverglobal.h>
|
||||
|
||||
#include <private/qobject_p.h>
|
||||
|
||||
#if defined(QT_WEBSOCKETS_LIB)
|
||||
#include <QtWebSockets/qwebsocketserver.h>
|
||||
#endif // defined(QT_WEBSOCKETS_LIB)
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHttpServerRequest;
|
||||
|
||||
class Q_HTTPSERVER_EXPORT QAbstractHttpServerPrivate: public QObjectPrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QAbstractHttpServer)
|
||||
|
||||
public:
|
||||
QAbstractHttpServerPrivate();
|
||||
|
||||
#if defined(QT_WEBSOCKETS_LIB)
|
||||
QWebSocketServer websocketServer {
|
||||
QLatin1String("QtHttpServer"),
|
||||
QWebSocketServer::NonSecureMode
|
||||
};
|
||||
#endif // defined(QT_WEBSOCKETS_LIB)
|
||||
|
||||
void handleNewConnections();
|
||||
void handleReadyRead(QTcpSocket *socket,
|
||||
QHttpServerRequest *request);
|
||||
|
||||
#if QT_CONFIG(ssl)
|
||||
QSslConfiguration sslConfiguration;
|
||||
bool sslEnabled = false;
|
||||
#endif
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QABSTRACTHTTPSERVER_P_H
|
||||
222
Lib/QtHTTPServer/include/QtHttpServer/qhttpserver.h
Normal file
222
Lib/QtHTTPServer/include/QtHttpServer/qhttpserver.h
Normal file
@ -0,0 +1,222 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 Mikhail Svetkin <mikhail.svetkin@gmail.com>
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHTTPSERVER_H
|
||||
#define QHTTPSERVER_H
|
||||
|
||||
#include <QtHttpServer/qabstracthttpserver.h>
|
||||
#include <QtHttpServer/qhttpserverrouter.h>
|
||||
#include <QtHttpServer/qhttpserverrouterrule.h>
|
||||
#include <QtHttpServer/qhttpserverresponse.h>
|
||||
#include <QtHttpServer/qhttpserverrouterviewtraits.h>
|
||||
#include <QtHttpServer/qhttpserverviewtraits.h>
|
||||
|
||||
#include <tuple>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QTcpSocket;
|
||||
class QHttpServerRequest;
|
||||
|
||||
class QHttpServerPrivate;
|
||||
class Q_HTTPSERVER_EXPORT QHttpServer final : public QAbstractHttpServer
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_DECLARE_PRIVATE(QHttpServer)
|
||||
|
||||
template<int I, typename ... Ts>
|
||||
struct VariadicTypeAt { using Type = typename std::tuple_element<I, std::tuple<Ts...>>::type; };
|
||||
|
||||
template<typename ... Ts>
|
||||
struct VariadicTypeLast {
|
||||
using Type = typename VariadicTypeAt<sizeof ... (Ts) - 1, Ts...>::Type;
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
using ResponseType =
|
||||
typename std::conditional<
|
||||
std::is_base_of<QHttpServerResponse, T>::value,
|
||||
T,
|
||||
QHttpServerResponse
|
||||
>::type;
|
||||
|
||||
public:
|
||||
explicit QHttpServer(QObject *parent = nullptr);
|
||||
~QHttpServer();
|
||||
|
||||
QHttpServerRouter *router();
|
||||
|
||||
template<typename Rule = QHttpServerRouterRule, typename ... Args>
|
||||
bool route(Args && ... args)
|
||||
{
|
||||
using ViewHandler = typename VariadicTypeLast<Args...>::Type;
|
||||
using ViewTraits = QHttpServerRouterViewTraits<ViewHandler>;
|
||||
static_assert(ViewTraits::Arguments::StaticAssert,
|
||||
"ViewHandler arguments are in the wrong order or not supported");
|
||||
return routeHelper<Rule, ViewHandler, ViewTraits>(
|
||||
QtPrivate::makeIndexSequence<sizeof ... (Args) - 1>{},
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename ViewHandler>
|
||||
void afterRequest(ViewHandler &&viewHandler)
|
||||
{
|
||||
using ViewTraits = QHttpServerAfterRequestViewTraits<ViewHandler>;
|
||||
static_assert(ViewTraits::Arguments::StaticAssert,
|
||||
"ViewHandler arguments are in the wrong order or not supported");
|
||||
afterRequestHelper<ViewTraits, ViewHandler>(std::move(viewHandler));
|
||||
}
|
||||
|
||||
using AfterRequestHandler =
|
||||
std::function<QHttpServerResponse(QHttpServerResponse &&response,
|
||||
const QHttpServerRequest &request)>;
|
||||
private:
|
||||
template<typename ViewTraits, typename ViewHandler>
|
||||
typename std::enable_if<ViewTraits::Arguments::Last::IsRequest::Value &&
|
||||
ViewTraits::Arguments::Count == 2, void>::type
|
||||
afterRequestHelper(ViewHandler &&viewHandler) {
|
||||
auto handler = [viewHandler](QHttpServerResponse &&resp,
|
||||
const QHttpServerRequest &request) {
|
||||
return std::move(viewHandler(std::move(resp), request));
|
||||
};
|
||||
|
||||
afterRequestImpl(std::move(handler));
|
||||
}
|
||||
|
||||
template<typename ViewTraits, typename ViewHandler>
|
||||
typename std::enable_if<ViewTraits::Arguments::Last::IsResponse::Value &&
|
||||
ViewTraits::Arguments::Count == 1, void>::type
|
||||
afterRequestHelper(ViewHandler &&viewHandler) {
|
||||
auto handler = [viewHandler](QHttpServerResponse &&resp,
|
||||
const QHttpServerRequest &) {
|
||||
return std::move(viewHandler(std::move(resp)));
|
||||
};
|
||||
|
||||
afterRequestImpl(std::move(handler));
|
||||
}
|
||||
|
||||
template<typename ViewTraits, typename ViewHandler>
|
||||
typename std::enable_if<ViewTraits::Arguments::Last::IsResponse::Value &&
|
||||
ViewTraits::Arguments::Count == 2, void>::type
|
||||
afterRequestHelper(ViewHandler &&viewHandler) {
|
||||
auto handler = [viewHandler](QHttpServerResponse &&resp,
|
||||
const QHttpServerRequest &request) {
|
||||
return std::move(viewHandler(request, std::move(resp)));
|
||||
};
|
||||
|
||||
afterRequestImpl(std::move(handler));
|
||||
}
|
||||
|
||||
void afterRequestImpl(AfterRequestHandler &&afterRequestHandler);
|
||||
|
||||
private:
|
||||
template<typename Rule, typename ViewHandler, typename ViewTraits, int ... I, typename ... Args>
|
||||
bool routeHelper(QtPrivate::IndexesList<I...>, Args &&... args)
|
||||
{
|
||||
return routeImpl<Rule,
|
||||
ViewHandler,
|
||||
ViewTraits,
|
||||
typename VariadicTypeAt<I, Args...>::Type...>(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template<typename Rule, typename ViewHandler, typename ViewTraits, typename ... Args>
|
||||
bool routeImpl(Args &&...args, ViewHandler &&viewHandler)
|
||||
{
|
||||
auto routerHandler = [this, viewHandler] (
|
||||
const QRegularExpressionMatch &match,
|
||||
const QHttpServerRequest &request,
|
||||
QTcpSocket *socket) mutable {
|
||||
auto boundViewHandler = router()->bindCaptured<ViewHandler, ViewTraits>(
|
||||
std::move(viewHandler), match);
|
||||
responseImpl<ViewTraits>(boundViewHandler, request, socket);
|
||||
};
|
||||
|
||||
return router()->addRule<ViewHandler, ViewTraits>(
|
||||
new Rule(std::forward<Args>(args)..., std::move(routerHandler)));
|
||||
}
|
||||
|
||||
template<typename ViewTraits, typename T>
|
||||
typename std::enable_if<!ViewTraits::Arguments::Last::IsSpecial::Value, void>::type
|
||||
responseImpl(T &boundViewHandler,
|
||||
const QHttpServerRequest &request,
|
||||
QTcpSocket *socket)
|
||||
{
|
||||
ResponseType<typename ViewTraits::ReturnType> response(boundViewHandler());
|
||||
sendResponse(std::move(response), request, socket);
|
||||
}
|
||||
|
||||
template<typename ViewTraits, typename T>
|
||||
typename std::enable_if<ViewTraits::Arguments::Last::IsRequest::Value &&
|
||||
ViewTraits::Arguments::PlaceholdersCount == 1, void>::type
|
||||
responseImpl(T &boundViewHandler, const QHttpServerRequest &request, QTcpSocket *socket)
|
||||
{
|
||||
ResponseType<typename ViewTraits::ReturnType> response(boundViewHandler(request));
|
||||
sendResponse(std::move(response), request, socket);
|
||||
}
|
||||
|
||||
template<typename ViewTraits, typename T>
|
||||
typename std::enable_if<ViewTraits::Arguments::Last::IsRequest::Value &&
|
||||
ViewTraits::Arguments::PlaceholdersCount == 2, void>::type
|
||||
responseImpl(T &boundViewHandler, const QHttpServerRequest &request, QTcpSocket *socket)
|
||||
{
|
||||
boundViewHandler(makeResponder(request, socket), request);
|
||||
}
|
||||
|
||||
template<typename ViewTraits, typename T>
|
||||
typename std::enable_if<ViewTraits::Arguments::Last::IsResponder::Value &&
|
||||
ViewTraits::Arguments::PlaceholdersCount == 2, void>::type
|
||||
responseImpl(T &boundViewHandler,
|
||||
const QHttpServerRequest &request,
|
||||
QTcpSocket *socket)
|
||||
{
|
||||
boundViewHandler(request, makeResponder(request, socket));
|
||||
}
|
||||
|
||||
template<typename ViewTraits, typename T>
|
||||
typename std::enable_if<ViewTraits::Arguments::Last::IsResponder::Value &&
|
||||
ViewTraits::Arguments::PlaceholdersCount == 1, void>::type
|
||||
responseImpl(T &boundViewHandler,
|
||||
const QHttpServerRequest &request,
|
||||
QTcpSocket *socket)
|
||||
{
|
||||
boundViewHandler(makeResponder(request, socket));
|
||||
}
|
||||
|
||||
bool handleRequest(const QHttpServerRequest &request, QTcpSocket *socket) override final;
|
||||
|
||||
void sendResponse(QHttpServerResponse &&response,
|
||||
const QHttpServerRequest &request,
|
||||
QTcpSocket *socket);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHTTPSERVER_H
|
||||
69
Lib/QtHTTPServer/include/QtHttpServer/qhttpserver_p.h
Normal file
69
Lib/QtHTTPServer/include/QtHttpServer/qhttpserver_p.h
Normal file
@ -0,0 +1,69 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHTTPSERVER_P_H
|
||||
#define QHTTPSERVER_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of QHttpServer. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
|
||||
#include <private/qabstracthttpserver_p.h>
|
||||
|
||||
#include <QtHttpServer/qhttpserver.h>
|
||||
#include <QtHttpServer/qhttpserverresponse.h>
|
||||
#include <QtHttpServer/qhttpserverrequest.h>
|
||||
#include <QtHttpServer/qhttpserverrouter.h>
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#include <list>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHttpServerPrivate: public QAbstractHttpServerPrivate
|
||||
{
|
||||
Q_DECLARE_PUBLIC(QHttpServer)
|
||||
|
||||
public:
|
||||
QHttpServerPrivate() = default;
|
||||
|
||||
QHttpServerRouter router;
|
||||
std::list<QHttpServer::AfterRequestHandler> afterRequestHandlers;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHTTPSERVER_P_H
|
||||
@ -0,0 +1,162 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 Mikhail Svetkin <mikhail.svetkin@gmail.com>
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHTTPSERVERFUTURERESPONSE_H
|
||||
#define QHTTPSERVERFUTURERESPONSE_H
|
||||
|
||||
#include <QtHttpServer/qhttpserverresponse.h>
|
||||
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/qfuture.h>
|
||||
|
||||
#include <QtConcurrent>
|
||||
|
||||
#include <mutex>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
|
||||
template <>
|
||||
class QFutureInterface<QHttpServerResponse> : public QFutureInterfaceBase
|
||||
{
|
||||
public:
|
||||
QFutureInterface(State initialState = NoState)
|
||||
: QFutureInterfaceBase(initialState)
|
||||
{
|
||||
refT();
|
||||
}
|
||||
QFutureInterface(const QFutureInterface &other)
|
||||
: QFutureInterfaceBase(other)
|
||||
{
|
||||
refT();
|
||||
}
|
||||
~QFutureInterface()
|
||||
{
|
||||
if (!derefT())
|
||||
resultStoreBase().template clear<QHttpServerResponse>();
|
||||
}
|
||||
|
||||
static QFutureInterface canceledResult()
|
||||
{ return QFutureInterface(State(Started | Finished | Canceled)); }
|
||||
|
||||
QFutureInterface &operator=(const QFutureInterface &other)
|
||||
{
|
||||
other.refT();
|
||||
if (!derefT())
|
||||
resultStoreBase().template clear<QHttpServerResponse>();
|
||||
QFutureInterfaceBase::operator=(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline QFuture<QHttpServerResponse> future()
|
||||
{
|
||||
return QFuture<QHttpServerResponse>(this);
|
||||
}
|
||||
|
||||
void reportAndMoveResult(QHttpServerResponse &&result, int index = -1)
|
||||
{
|
||||
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
|
||||
std::lock_guard<QMutex> locker{*mutex()};
|
||||
#else
|
||||
std::lock_guard<QMutex> locker{mutex(0)};
|
||||
#endif
|
||||
if (queryState(Canceled) || queryState(Finished))
|
||||
return;
|
||||
|
||||
QtPrivate::ResultStoreBase &store = resultStoreBase();
|
||||
|
||||
const int oldResultCount = store.count();
|
||||
const int insertIndex = store.addResult(
|
||||
index, static_cast<void *>(new QHttpServerResponse(std::move_if_noexcept(result))));
|
||||
if (!store.filterMode() || oldResultCount < store.count()) // Let's make sure it's not in pending results.
|
||||
reportResultsReady(insertIndex, store.count());
|
||||
}
|
||||
|
||||
void reportFinished()
|
||||
{
|
||||
QFutureInterfaceBase::reportFinished();
|
||||
}
|
||||
|
||||
QHttpServerResponse takeResult();
|
||||
};
|
||||
|
||||
#endif // QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
|
||||
|
||||
namespace QtConcurrent {
|
||||
|
||||
template <>
|
||||
class RunFunctionTask<QHttpServerResponse> : public RunFunctionTaskBase<QHttpServerResponse>
|
||||
{
|
||||
public:
|
||||
void run() override
|
||||
{
|
||||
if (this->isCanceled()) {
|
||||
this->reportFinished();
|
||||
return;
|
||||
}
|
||||
#ifndef QT_NO_EXCEPTIONS
|
||||
try {
|
||||
#endif
|
||||
this->runFunctor();
|
||||
#ifndef QT_NO_EXCEPTIONS
|
||||
} catch (QException &e) {
|
||||
QFutureInterface<QHttpServerResponse>::reportException(e);
|
||||
} catch (...) {
|
||||
QFutureInterface<QHttpServerResponse>::reportException(QUnhandledException());
|
||||
}
|
||||
#endif
|
||||
this->reportAndMoveResult(std::move_if_noexcept(result));
|
||||
this->reportFinished();
|
||||
}
|
||||
|
||||
QHttpServerResponse result{QHttpServerResponse::StatusCode::NotFound};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class QHttpServerFutureResponsePrivate;
|
||||
class Q_HTTPSERVER_EXPORT QHttpServerFutureResponse : public QHttpServerResponse
|
||||
{
|
||||
Q_DECLARE_PRIVATE(QHttpServerFutureResponse)
|
||||
|
||||
public:
|
||||
using QHttpServerResponse::QHttpServerResponse;
|
||||
|
||||
QHttpServerFutureResponse(const QFuture<QHttpServerResponse> &futureResponse);
|
||||
|
||||
virtual void write(QHttpServerResponder &&responder) const override;
|
||||
|
||||
protected:
|
||||
QHttpServerFutureResponse(QHttpServerFutureResponsePrivate *d);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHTTPSERVERFUTURERESPONSE_H
|
||||
@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 Mikhail Svetkin <mikhail.svetkin@gmail.com>
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHTTPSERVERLITERALS_P_H
|
||||
#define QHTTPSERVERLITERALS_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of QHttpServer. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
|
||||
#include <QtHttpServer/qthttpserverglobal.h>
|
||||
|
||||
#include <QtCore/qbytearray.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Q_HTTPSERVER_EXPORT QHttpServerLiterals
|
||||
{
|
||||
|
||||
public:
|
||||
static QByteArray contentTypeHeader();
|
||||
static QByteArray contentTypeXEmpty();
|
||||
static QByteArray contentTypeTextHtml();
|
||||
static QByteArray contentTypeJson();
|
||||
static QByteArray contentLengthHeader();
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHTTPSERVERLITERALS_P_H
|
||||
108
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverrequest.h
Normal file
108
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverrequest.h
Normal file
@ -0,0 +1,108 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHTTPSERVERREQUEST_H
|
||||
#define QHTTPSERVERREQUEST_H
|
||||
|
||||
#include <QtHttpServer/qthttpserverglobal.h>
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qurl.h>
|
||||
#include <QtCore/qurlquery.h>
|
||||
#include <QtNetwork/qhostaddress.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QRegularExpression;
|
||||
class QString;
|
||||
class QTcpSocket;
|
||||
|
||||
class QHttpServerRequestPrivate;
|
||||
class Q_HTTPSERVER_EXPORT QHttpServerRequest
|
||||
{
|
||||
friend class QAbstractHttpServerPrivate;
|
||||
friend class QHttpServerResponse;
|
||||
|
||||
Q_GADGET
|
||||
|
||||
public:
|
||||
virtual ~QHttpServerRequest();
|
||||
|
||||
enum class Method
|
||||
{
|
||||
Unknown = 0x0000,
|
||||
Get = 0x0001,
|
||||
Put = 0x0002,
|
||||
Delete = 0x0004,
|
||||
Post = 0x0008,
|
||||
Head = 0x0010,
|
||||
Options = 0x0020,
|
||||
Patch = 0x0040,
|
||||
Connect = 0x0080,
|
||||
|
||||
All = Get | Put | Delete | Post | Head | Options | Patch | Connect,
|
||||
|
||||
// Include upper-case aliases for the sake of parsing from strings:
|
||||
GET = Get,
|
||||
PUT = Put,
|
||||
DELETE = Delete,
|
||||
POST = Post,
|
||||
HEAD = Head,
|
||||
OPTIONS = Options,
|
||||
PATCH = Patch,
|
||||
CONNECT = Connect
|
||||
};
|
||||
Q_ENUM(Method)
|
||||
Q_DECLARE_FLAGS(Methods, Method)
|
||||
Q_FLAG(Methods)
|
||||
|
||||
QByteArray value(const QByteArray &key) const;
|
||||
QUrl url() const;
|
||||
QUrlQuery query() const;
|
||||
Method method() const;
|
||||
QVariantMap headers() const;
|
||||
QByteArray body() const;
|
||||
QHostAddress remoteAddress() const;
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QHttpServerRequest)
|
||||
|
||||
#if !defined(QT_NO_DEBUG_STREAM)
|
||||
friend Q_HTTPSERVER_EXPORT QDebug operator<<(QDebug debug, const QHttpServerRequest &request);
|
||||
#endif
|
||||
|
||||
explicit QHttpServerRequest(const QHostAddress &remoteAddress);
|
||||
|
||||
QScopedPointer<QHttpServerRequestPrivate> d;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHTTPSERVERREQUEST_H
|
||||
113
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverrequest_p.h
Normal file
113
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverrequest_p.h
Normal file
@ -0,0 +1,113 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHTTPSERVERREQUEST_P_H
|
||||
#define QHTTPSERVERREQUEST_P_H
|
||||
|
||||
#include <QtHttpServer/qhttpserverrequest.h>
|
||||
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/qpair.h>
|
||||
#include <QtCore/qregularexpression.h>
|
||||
#include <QtCore/qshareddata.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qurl.h>
|
||||
#include <QtNetwork/qhostaddress.h>
|
||||
|
||||
#include "../3rdparty/http-parser/http_parser.h"
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of QHttpServer. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHttpServerRequestPrivate : public QSharedData
|
||||
{
|
||||
public:
|
||||
QHttpServerRequestPrivate(const QHostAddress &remoteAddress);
|
||||
|
||||
quint16 port = 0;
|
||||
enum class State {
|
||||
NotStarted,
|
||||
OnMessageBegin,
|
||||
OnUrl,
|
||||
OnStatus,
|
||||
OnHeaders,
|
||||
OnHeadersComplete,
|
||||
OnBody,
|
||||
OnMessageComplete,
|
||||
OnChunkHeader,
|
||||
OnChunkComplete
|
||||
} state = State::NotStarted;
|
||||
QByteArray body;
|
||||
|
||||
QUrl url;
|
||||
|
||||
http_parser httpParser;
|
||||
|
||||
QByteArray header(const QByteArray &key) const;
|
||||
bool parse(QIODevice *socket);
|
||||
|
||||
QByteArray lastHeader;
|
||||
QMap<uint, QPair<QByteArray, QByteArray>> headers;
|
||||
const uint headersSeed = uint(qGlobalQHashSeed());
|
||||
uint headerHash(const QByteArray &key) const;
|
||||
|
||||
void clear();
|
||||
QHostAddress remoteAddress;
|
||||
bool handling{false};
|
||||
|
||||
private:
|
||||
static http_parser_settings httpParserSettings;
|
||||
static bool parseUrl(const char *at, size_t length, bool connect, QUrl *url);
|
||||
|
||||
static QHttpServerRequestPrivate *instance(http_parser *httpParser);
|
||||
|
||||
static int onMessageBegin(http_parser *httpParser);
|
||||
static int onUrl(http_parser *httpParser, const char *at, size_t length);
|
||||
static int onStatus(http_parser *httpParser, const char *at, size_t length);
|
||||
static int onHeaderField(http_parser *httpParser, const char *at, size_t length);
|
||||
static int onHeaderValue(http_parser *httpParser, const char *at, size_t length);
|
||||
static int onHeadersComplete(http_parser *httpParser);
|
||||
static int onBody(http_parser *httpParser, const char *at, size_t length);
|
||||
static int onMessageComplete(http_parser *httpParser);
|
||||
static int onChunkHeader(http_parser *httpParser);
|
||||
static int onChunkComplete(http_parser *httpParser);
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHTTPSERVERREQUEST_P_H
|
||||
187
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverresponder.h
Normal file
187
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverresponder.h
Normal file
@ -0,0 +1,187 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHTTPSERVERRESPONDER_H
|
||||
#define QHTTPSERVERRESPONDER_H
|
||||
|
||||
#include <QtHttpServer/qthttpserverglobal.h>
|
||||
|
||||
#include <QtCore/qdebug.h>
|
||||
#include <QtCore/qpair.h>
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qscopedpointer.h>
|
||||
#include <QtCore/qmetatype.h>
|
||||
#include <QtCore/qmimetype.h>
|
||||
|
||||
#include <utility>
|
||||
#include <initializer_list>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QTcpSocket;
|
||||
class QHttpServerRequest;
|
||||
|
||||
class QHttpServerResponderPrivate;
|
||||
class Q_HTTPSERVER_EXPORT QHttpServerResponder final
|
||||
{
|
||||
Q_DECLARE_PRIVATE(QHttpServerResponder)
|
||||
|
||||
friend class QAbstractHttpServer;
|
||||
|
||||
public:
|
||||
enum class StatusCode {
|
||||
// 1xx: Informational
|
||||
Continue = 100,
|
||||
SwitchingProtocols,
|
||||
Processing,
|
||||
|
||||
// 2xx: Success
|
||||
Ok = 200,
|
||||
Created,
|
||||
Accepted,
|
||||
NonAuthoritativeInformation,
|
||||
NoContent,
|
||||
ResetContent,
|
||||
PartialContent,
|
||||
MultiStatus,
|
||||
AlreadyReported,
|
||||
IMUsed = 226,
|
||||
|
||||
// 3xx: Redirection
|
||||
MultipleChoices = 300,
|
||||
MovedPermanently,
|
||||
Found,
|
||||
SeeOther,
|
||||
NotModified,
|
||||
UseProxy,
|
||||
// 306: not used, was proposed as "Switch Proxy" but never standardized
|
||||
TemporaryRedirect = 307,
|
||||
PermanentRedirect,
|
||||
|
||||
// 4xx: Client Error
|
||||
BadRequest = 400,
|
||||
Unauthorized,
|
||||
PaymentRequired,
|
||||
Forbidden,
|
||||
NotFound,
|
||||
MethodNotAllowed,
|
||||
NotAcceptable,
|
||||
ProxyAuthenticationRequired,
|
||||
RequestTimeout,
|
||||
Conflict,
|
||||
Gone,
|
||||
LengthRequired,
|
||||
PreconditionFailed,
|
||||
PayloadTooLarge,
|
||||
UriTooLong,
|
||||
UnsupportedMediaType,
|
||||
RequestRangeNotSatisfiable,
|
||||
ExpectationFailed,
|
||||
ImATeapot,
|
||||
MisdirectedRequest = 421,
|
||||
UnprocessableEntity,
|
||||
Locked,
|
||||
FailedDependency,
|
||||
UpgradeRequired = 426,
|
||||
PreconditionRequired = 428,
|
||||
TooManyRequests,
|
||||
RequestHeaderFieldsTooLarge = 431,
|
||||
UnavailableForLegalReasons = 451,
|
||||
|
||||
// 5xx: Server Error
|
||||
InternalServerError = 500,
|
||||
NotImplemented,
|
||||
BadGateway,
|
||||
ServiceUnavailable,
|
||||
GatewayTimeout,
|
||||
HttpVersionNotSupported,
|
||||
VariantAlsoNegotiates,
|
||||
InsufficientStorage,
|
||||
LoopDetected,
|
||||
NotExtended = 510,
|
||||
NetworkAuthenticationRequired,
|
||||
NetworkConnectTimeoutError = 599,
|
||||
};
|
||||
|
||||
using HeaderList = std::initializer_list<std::pair<QByteArray, QByteArray>>;
|
||||
|
||||
QHttpServerResponder(QHttpServerResponder &&other);
|
||||
~QHttpServerResponder();
|
||||
|
||||
void write(QIODevice *data,
|
||||
HeaderList headers,
|
||||
StatusCode status = StatusCode::Ok);
|
||||
|
||||
void write(QIODevice *data,
|
||||
const QByteArray &mimeType,
|
||||
StatusCode status = StatusCode::Ok);
|
||||
|
||||
void write(const QJsonDocument &document,
|
||||
HeaderList headers,
|
||||
StatusCode status = StatusCode::Ok);
|
||||
|
||||
void write(const QJsonDocument &document,
|
||||
StatusCode status = StatusCode::Ok);
|
||||
|
||||
void write(const QByteArray &data,
|
||||
HeaderList headers,
|
||||
StatusCode status = StatusCode::Ok);
|
||||
|
||||
void write(const QByteArray &data,
|
||||
const QByteArray &mimeType,
|
||||
StatusCode status = StatusCode::Ok);
|
||||
|
||||
void write(HeaderList headers, StatusCode status = StatusCode::Ok);
|
||||
void write(StatusCode status = StatusCode::Ok);
|
||||
|
||||
|
||||
void writeStatusLine(StatusCode status = StatusCode::Ok,
|
||||
const QPair<quint8, quint8> &version = qMakePair(1u, 1u));
|
||||
|
||||
void writeHeader(const QByteArray &key, const QByteArray &value);
|
||||
void writeHeaders(HeaderList headers);
|
||||
|
||||
void writeBody(const char *body, qint64 size);
|
||||
void writeBody(const char *body);
|
||||
void writeBody(const QByteArray &body);
|
||||
|
||||
QTcpSocket *socket() const;
|
||||
|
||||
private:
|
||||
QHttpServerResponder(const QHttpServerRequest &request, QTcpSocket *socket);
|
||||
|
||||
QScopedPointer<QHttpServerResponderPrivate> d_ptr;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
Q_DECLARE_METATYPE(QHttpServerResponder::StatusCode)
|
||||
|
||||
#endif // QHTTPSERVERRESPONDER_H
|
||||
@ -0,0 +1,73 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHTTPSERVERRESPONDER_P_H
|
||||
#define QHTTPSERVERRESPONDER_P_H
|
||||
|
||||
#include <QtHttpServer/qthttpserverglobal.h>
|
||||
#include <QtHttpServer/qhttpserverrequest.h>
|
||||
#include <QtHttpServer/qhttpserverresponder.h>
|
||||
|
||||
#include <QtCore/qcoreapplication.h>
|
||||
#include <QtCore/qpair.h>
|
||||
#include <QtCore/qpointer.h>
|
||||
#include <QtCore/qsysinfo.h>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of QHttpServer. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHttpServerResponderPrivate
|
||||
{
|
||||
public:
|
||||
QHttpServerResponderPrivate(const QHttpServerRequest &request, QTcpSocket *const socket)
|
||||
: request(request), socket(socket) {}
|
||||
|
||||
const QHttpServerRequest &request;
|
||||
#if defined(QT_DEBUG)
|
||||
const QPointer<QTcpSocket> socket;
|
||||
#else
|
||||
QTcpSocket *const socket;
|
||||
#endif
|
||||
bool bodyStarted{false};
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHTTPSERVERRESPONDER_P_H
|
||||
129
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverresponse.h
Normal file
129
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverresponse.h
Normal file
@ -0,0 +1,129 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHTTPSERVERRESPONSE_H
|
||||
#define QHTTPSERVERRESPONSE_H
|
||||
|
||||
#include <QtHttpServer/qhttpserverresponder.h>
|
||||
|
||||
#include <QtCore/qscopedpointer.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QJsonObject;
|
||||
|
||||
class QHttpServerResponsePrivate;
|
||||
class Q_HTTPSERVER_EXPORT QHttpServerResponse
|
||||
{
|
||||
Q_DECLARE_PRIVATE(QHttpServerResponse)
|
||||
|
||||
public:
|
||||
using StatusCode = QHttpServerResponder::StatusCode;
|
||||
|
||||
QHttpServerResponse() = delete;
|
||||
QHttpServerResponse(const QHttpServerResponse &other) = delete;
|
||||
QHttpServerResponse& operator=(const QHttpServerResponse &other) = delete;
|
||||
|
||||
QHttpServerResponse(QHttpServerResponse &&other) noexcept;
|
||||
QHttpServerResponse& operator=(QHttpServerResponse &&other) noexcept;
|
||||
|
||||
QHttpServerResponse(const StatusCode statusCode);
|
||||
|
||||
QHttpServerResponse(const char *data);
|
||||
|
||||
QHttpServerResponse(const QString &data);
|
||||
|
||||
explicit QHttpServerResponse(const QByteArray &data);
|
||||
explicit QHttpServerResponse(QByteArray &&data);
|
||||
|
||||
QHttpServerResponse(const QJsonObject &data);
|
||||
QHttpServerResponse(const QJsonArray &data);
|
||||
|
||||
QHttpServerResponse(const QByteArray &mimeType,
|
||||
const QByteArray &data,
|
||||
const StatusCode status = StatusCode::Ok);
|
||||
QHttpServerResponse(QByteArray &&mimeType,
|
||||
const QByteArray &data,
|
||||
const StatusCode status = StatusCode::Ok);
|
||||
QHttpServerResponse(const QByteArray &mimeType,
|
||||
QByteArray &&data,
|
||||
const StatusCode status = StatusCode::Ok);
|
||||
QHttpServerResponse(QByteArray &&mimeType,
|
||||
QByteArray &&data,
|
||||
const StatusCode status = StatusCode::Ok);
|
||||
|
||||
virtual ~QHttpServerResponse();
|
||||
static QHttpServerResponse fromFile(const QString &fileName);
|
||||
|
||||
QByteArray data() const;
|
||||
|
||||
QByteArray mimeType() const;
|
||||
|
||||
StatusCode statusCode() const;
|
||||
|
||||
void addHeader(QByteArray &&name, QByteArray &&value);
|
||||
void addHeader(QByteArray &&name, const QByteArray &value);
|
||||
void addHeader(const QByteArray &name, QByteArray &&value);
|
||||
void addHeader(const QByteArray &name, const QByteArray &value);
|
||||
|
||||
void addHeaders(QHttpServerResponder::HeaderList headers);
|
||||
|
||||
template<typename Container>
|
||||
void addHeaders(const Container &headerList)
|
||||
{
|
||||
for (const auto &header : headerList)
|
||||
addHeader(header.first, header.second);
|
||||
}
|
||||
|
||||
void clearHeader(const QByteArray &name);
|
||||
void clearHeaders();
|
||||
|
||||
void setHeader(QByteArray &&name, QByteArray &&value);
|
||||
void setHeader(QByteArray &&name, const QByteArray &value);
|
||||
void setHeader(const QByteArray &name, QByteArray &&value);
|
||||
void setHeader(const QByteArray &name, const QByteArray &value);
|
||||
|
||||
void setHeaders(QHttpServerResponder::HeaderList headers);
|
||||
|
||||
bool hasHeader(const QByteArray &name) const;
|
||||
bool hasHeader(const QByteArray &name, const QByteArray &value) const;
|
||||
|
||||
QVector<QByteArray> headers(const QByteArray &name) const;
|
||||
|
||||
virtual void write(QHttpServerResponder &&responder) const;
|
||||
|
||||
protected:
|
||||
QHttpServerResponse(QHttpServerResponsePrivate *d);
|
||||
|
||||
QScopedPointer<QHttpServerResponsePrivate> d_ptr;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHTTPSERVERRESPONSE_H
|
||||
@ -0,0 +1,76 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHTTPSERVERRESPONSE_P_H
|
||||
#define QHTTPSERVERRESPONSE_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of QHttpServerResponse. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
|
||||
#include <private/qabstracthttpserver_p.h>
|
||||
|
||||
#include <QtHttpServer/qhttpserverresponse.h>
|
||||
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHttpServerResponsePrivate
|
||||
{
|
||||
struct HashHelper {
|
||||
std::size_t operator()(const QByteArray& key) const
|
||||
{
|
||||
return qHash(key.toLower());
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
explicit QHttpServerResponsePrivate() = default;
|
||||
virtual ~QHttpServerResponsePrivate() = default;
|
||||
|
||||
QHttpServerResponsePrivate(QByteArray &&d, const QHttpServerResponse::StatusCode sc);
|
||||
QHttpServerResponsePrivate(const QHttpServerResponse::StatusCode sc);
|
||||
|
||||
QByteArray data;
|
||||
QHttpServerResponse::StatusCode statusCode;
|
||||
std::unordered_multimap<QByteArray, QByteArray, HashHelper> headers;
|
||||
bool derived{false};
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHTTPSERVERRESPONSE_P_H
|
||||
161
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverrouter.h
Normal file
161
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverrouter.h
Normal file
@ -0,0 +1,161 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHTTPSERVERROUTER_H
|
||||
#define QHTTPSERVERROUTER_H
|
||||
|
||||
#include <QtHttpServer/qthttpserverglobal.h>
|
||||
#include <QtHttpServer/qhttpserverrouterviewtraits.h>
|
||||
|
||||
#include <QtCore/qscopedpointer.h>
|
||||
#include <QtCore/qmetatype.h>
|
||||
#include <QtCore/qregularexpression.h>
|
||||
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QtPrivate {
|
||||
template<int> struct QHttpServerRouterPlaceholder {};
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace std {
|
||||
|
||||
template<int N>
|
||||
struct is_placeholder<QT_PREPEND_NAMESPACE(QtPrivate::QHttpServerRouterPlaceholder<N>)> :
|
||||
integral_constant<int , N + 1>
|
||||
{};
|
||||
|
||||
}
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QTcpSocket;
|
||||
class QHttpServerRequest;
|
||||
class QHttpServerRouterRule;
|
||||
|
||||
class QHttpServerRouterPrivate;
|
||||
class Q_HTTPSERVER_EXPORT QHttpServerRouter
|
||||
{
|
||||
Q_DECLARE_PRIVATE(QHttpServerRouter)
|
||||
|
||||
public:
|
||||
QHttpServerRouter();
|
||||
~QHttpServerRouter();
|
||||
|
||||
template<typename Type>
|
||||
bool addConverter(const QLatin1String ®exp) {
|
||||
static_assert(QMetaTypeId2<Type>::Defined,
|
||||
"Type is not registered with Qt's meta-object system: "
|
||||
"please apply Q_DECLARE_METATYPE() to it");
|
||||
|
||||
if (!QMetaType::registerConverter<QString, Type>())
|
||||
return false;
|
||||
|
||||
addConverter(qMetaTypeId<Type>(), regexp);
|
||||
return true;
|
||||
}
|
||||
|
||||
void addConverter(const int type, const QLatin1String ®exp);
|
||||
void removeConverter(const int);
|
||||
void clearConverters();
|
||||
const QMap<int, QLatin1String> &converters() const;
|
||||
|
||||
static const QMap<int, QLatin1String> &defaultConverters();
|
||||
|
||||
template<typename ViewHandler, typename ViewTraits = QHttpServerRouterViewTraits<ViewHandler>>
|
||||
bool addRule(QHttpServerRouterRule *rule)
|
||||
{
|
||||
return addRuleHelper<ViewTraits>(
|
||||
rule,
|
||||
typename ViewTraits::Arguments::Indexes{});
|
||||
}
|
||||
|
||||
template<typename ViewHandler, typename ViewTraits = QHttpServerRouterViewTraits<ViewHandler>>
|
||||
typename ViewTraits::BindableType bindCaptured(ViewHandler &&handler,
|
||||
const QRegularExpressionMatch &match) const
|
||||
{
|
||||
return bindCapturedImpl<ViewHandler, ViewTraits>(
|
||||
std::forward<ViewHandler>(handler),
|
||||
match,
|
||||
typename ViewTraits::Arguments::CapturableIndexes{},
|
||||
typename ViewTraits::Arguments::PlaceholdersIndexes{});
|
||||
}
|
||||
|
||||
bool handleRequest(const QHttpServerRequest &request,
|
||||
QTcpSocket *socket) const;
|
||||
|
||||
private:
|
||||
template<typename ViewTraits, int ... Idx>
|
||||
bool addRuleHelper(QHttpServerRouterRule *rule,
|
||||
QtPrivate::IndexesList<Idx...>)
|
||||
{
|
||||
const std::initializer_list<int> types = {
|
||||
ViewTraits::Arguments::template metaTypeId<Idx>()...};
|
||||
return addRuleImpl(rule, types);
|
||||
}
|
||||
|
||||
bool addRuleImpl(QHttpServerRouterRule *rule,
|
||||
const std::initializer_list<int> &metaTypes);
|
||||
|
||||
template<typename ViewHandler, typename ViewTraits, int ... Cx, int ... Px>
|
||||
typename std::enable_if<ViewTraits::Arguments::CapturableCount != 0, typename ViewTraits::BindableType>::type
|
||||
bindCapturedImpl(ViewHandler &&handler,
|
||||
const QRegularExpressionMatch &match,
|
||||
QtPrivate::IndexesList<Cx...>,
|
||||
QtPrivate::IndexesList<Px...>) const
|
||||
{
|
||||
return std::bind(
|
||||
std::forward<ViewHandler>(handler),
|
||||
QVariant(match.captured(Cx + 1))
|
||||
.value<typename ViewTraits::Arguments::template Arg<Cx>::CleanType>()...,
|
||||
QtPrivate::QHttpServerRouterPlaceholder<Px>{}...);
|
||||
}
|
||||
|
||||
template<typename ViewHandler, typename ViewTraits, int ... Cx, int ... Px>
|
||||
typename std::enable_if<!ViewTraits::Arguments::CapturableCount, typename ViewTraits::BindableType>::type
|
||||
bindCapturedImpl(ViewHandler &&handler,
|
||||
const QRegularExpressionMatch &,
|
||||
QtPrivate::IndexesList<Cx...>,
|
||||
QtPrivate::IndexesList<Px...>) const
|
||||
{
|
||||
return std::bind(
|
||||
std::forward<ViewHandler>(handler),
|
||||
QtPrivate::QHttpServerRouterPlaceholder<Px>{}...);
|
||||
}
|
||||
|
||||
QScopedPointer<QHttpServerRouterPrivate> d_ptr;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHTTPSERVERROUTER_H
|
||||
65
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverrouter_p.h
Normal file
65
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverrouter_p.h
Normal file
@ -0,0 +1,65 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHTTPSERVERROUTER_P_H
|
||||
#define QHTTPSERVERROUTER_P_H
|
||||
|
||||
#include <QtHttpServer/qhttpserverrouter.h>
|
||||
#include <QtHttpServer/qhttpserverrouterrule.h>
|
||||
|
||||
#include <QtCore/qmap.h>
|
||||
#include <QtCore/qlist.h>
|
||||
#include <QtCore/qstring.h>
|
||||
|
||||
#include <memory>
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of QHttpServer. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHttpServerRouterPrivate
|
||||
{
|
||||
public:
|
||||
QHttpServerRouterPrivate();
|
||||
|
||||
QMap<int, QLatin1String> converters;
|
||||
std::list<std::unique_ptr<QHttpServerRouterRule>> rules;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHTTPSERVERROUTER_P_H
|
||||
@ -0,0 +1,90 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHTTPSERVERROUTERRULE_H
|
||||
#define QHTTPSERVERROUTERRULE_H
|
||||
|
||||
#include <QtHttpServer/qhttpserverrequest.h>
|
||||
|
||||
#include <QtCore/qmap.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QString;
|
||||
class QHttpServerRequest;
|
||||
class QTcpSocket;
|
||||
class QRegularExpressionMatch;
|
||||
class QHttpServerRouter;
|
||||
|
||||
class QHttpServerRouterRulePrivate;
|
||||
class Q_HTTPSERVER_EXPORT QHttpServerRouterRule
|
||||
{
|
||||
Q_DECLARE_PRIVATE(QHttpServerRouterRule)
|
||||
|
||||
public:
|
||||
using RouterHandler = std::function<void(const QRegularExpressionMatch &,
|
||||
const QHttpServerRequest &,
|
||||
QTcpSocket *)>;
|
||||
|
||||
explicit QHttpServerRouterRule(const QString &pathPattern, RouterHandler &&routerHandler);
|
||||
explicit QHttpServerRouterRule(const QString &pathPattern,
|
||||
const QHttpServerRequest::Methods methods,
|
||||
RouterHandler &&routerHandler);
|
||||
explicit QHttpServerRouterRule(const QString &pathPattern,
|
||||
const char * methods,
|
||||
RouterHandler &&routerHandler);
|
||||
|
||||
QHttpServerRouterRule(QHttpServerRouterRule &&other) = delete;
|
||||
QHttpServerRouterRule &operator=(QHttpServerRouterRule &&other) = delete;
|
||||
|
||||
virtual ~QHttpServerRouterRule();
|
||||
|
||||
protected:
|
||||
bool exec(const QHttpServerRequest &request, QTcpSocket *socket) const;
|
||||
|
||||
bool hasValidMethods() const;
|
||||
|
||||
bool createPathRegexp(const std::initializer_list<int> &metaTypes,
|
||||
const QMap<int, QLatin1String> &converters);
|
||||
|
||||
virtual bool matches(const QHttpServerRequest &request,
|
||||
QRegularExpressionMatch *match) const;
|
||||
|
||||
QHttpServerRouterRule(QHttpServerRouterRulePrivate *d);
|
||||
|
||||
private:
|
||||
Q_DISABLE_COPY(QHttpServerRouterRule)
|
||||
QScopedPointer<QHttpServerRouterRulePrivate> d_ptr;
|
||||
|
||||
friend class QHttpServerRouter;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHTTPSERVERROUTERRULE_H
|
||||
@ -0,0 +1,62 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHTTPSERVERROUTERRULE_P_H
|
||||
#define QHTTPSERVERROUTERRULE_P_H
|
||||
|
||||
#include <QtHttpServer/qhttpserverrouterrule.h>
|
||||
|
||||
#include <QtCore/qregularexpression.h>
|
||||
#include <QtCore/qstring.h>
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists for the convenience
|
||||
// of QHttpServer. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Q_HTTPSERVER_EXPORT QHttpServerRouterRulePrivate
|
||||
{
|
||||
public:
|
||||
QString pathPattern;
|
||||
QHttpServerRequest::Methods methods;
|
||||
QHttpServerRouterRule::RouterHandler routerHandler;
|
||||
|
||||
QRegularExpression pathRegexp;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHTTPSERVERROUTERRULE_P_H
|
||||
@ -0,0 +1,164 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 Mikhail Svetkin <mikhail.svetkin@gmail.com>
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHTTPSERVERROUTERVIEWTRAITS_H
|
||||
#define QHTTPSERVERROUTERVIEWTRAITS_H
|
||||
|
||||
#include <QtHttpServer/qhttpserverviewtraits_impl.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHttpServerRequest;
|
||||
class QHttpServerResponder;
|
||||
|
||||
namespace QtPrivate {
|
||||
|
||||
template<typename ViewHandler, bool DisableStaticAssert>
|
||||
struct RouterViewTraitsHelper : ViewTraits<ViewHandler, DisableStaticAssert> {
|
||||
using VTraits = ViewTraits<ViewHandler, DisableStaticAssert>;
|
||||
using FunctionTraits = typename VTraits::FTraits;
|
||||
|
||||
template<int I>
|
||||
struct ArgumentChecker : FunctionTraits::template Arg<I> {
|
||||
using IsRequest = typename VTraits::template Special<I, const QHttpServerRequest &>;
|
||||
static_assert(IsRequest::AssertCondition,
|
||||
"ViewHandler arguments error: "
|
||||
"QHttpServerRequest can only be passed as a const reference");
|
||||
|
||||
using IsResponder = typename VTraits::template Special<I, QHttpServerResponder &&>;
|
||||
static_assert(IsResponder::AssertCondition,
|
||||
"ViewHandler arguments error: "
|
||||
"QHttpServerResponder can only be passed as a universal reference");
|
||||
|
||||
using IsSpecial = CheckAny<IsRequest, IsResponder>;
|
||||
|
||||
struct IsSimple {
|
||||
static constexpr bool Value = !IsSpecial::Value &&
|
||||
I < FunctionTraits::ArgumentCount &&
|
||||
FunctionTraits::ArgumentIndexMax != -1;
|
||||
static constexpr bool Valid = FunctionTraits::template Arg<I>::Defined;
|
||||
|
||||
static constexpr bool StaticAssert =
|
||||
DisableStaticAssert || !Value || Valid;
|
||||
|
||||
|
||||
static_assert(StaticAssert,
|
||||
"ViewHandler arguments error: "
|
||||
"Type is not registered, please use the Q_DECLARE_METATYPE macro "
|
||||
"to make it known to Qt's meta-object system");
|
||||
};
|
||||
|
||||
using CheckOk = CheckAny<IsSimple, IsSpecial>;
|
||||
|
||||
static constexpr bool Valid = CheckOk::Valid;
|
||||
static constexpr bool StaticAssert = CheckOk::StaticAssert;
|
||||
};
|
||||
|
||||
|
||||
struct Arguments {
|
||||
template<int ... I>
|
||||
struct ArgumentsReturn {
|
||||
template<int Idx>
|
||||
using Arg = ArgumentChecker<Idx>;
|
||||
|
||||
template<int Idx>
|
||||
static constexpr int metaTypeId() noexcept
|
||||
{
|
||||
using Type = typename FunctionTraits::template Arg<Idx>::CleanType;
|
||||
|
||||
return qMetaTypeId<
|
||||
typename std::conditional<
|
||||
QMetaTypeId2<Type>::Defined,
|
||||
Type,
|
||||
void>::type>();
|
||||
}
|
||||
|
||||
static constexpr std::size_t Count = FunctionTraits::ArgumentCount;
|
||||
static constexpr std::size_t CapturableCount =
|
||||
StaticMath::Sum::eval(
|
||||
static_cast<std::size_t>(FunctionTraits::template Arg<I>::Defined)...);
|
||||
static constexpr std::size_t PlaceholdersCount = Count - CapturableCount;
|
||||
|
||||
static constexpr bool Valid = StaticMath::And::eval(Arg<I>::Valid...);
|
||||
static constexpr bool StaticAssert =
|
||||
StaticMath::And::eval(Arg<I>::StaticAssert...);
|
||||
|
||||
using Indexes = typename QtPrivate::IndexesList<I...>;
|
||||
|
||||
using CapturableIndexes =
|
||||
typename QtPrivate::Indexes<CapturableCount>::Value;
|
||||
|
||||
using PlaceholdersIndexes =
|
||||
typename QtPrivate::Indexes<PlaceholdersCount>::Value;
|
||||
|
||||
using Last = Arg<FunctionTraits::ArgumentIndexMax>;
|
||||
};
|
||||
|
||||
template<int ... I>
|
||||
static constexpr ArgumentsReturn<I...> eval(QtPrivate::IndexesList<I...>) noexcept
|
||||
{
|
||||
return ArgumentsReturn<I...>{};
|
||||
}
|
||||
};
|
||||
|
||||
template<int CaptureOffset>
|
||||
struct BindType {
|
||||
template<typename ... Args>
|
||||
struct FunctionWrapper {
|
||||
using Type = std::function<typename FunctionTraits::ReturnType (Args...)>;
|
||||
};
|
||||
|
||||
template<int Id>
|
||||
using OffsetArg = typename FunctionTraits::template Arg<CaptureOffset + Id>::Type;
|
||||
|
||||
template<int ... Idx>
|
||||
static constexpr typename FunctionWrapper<OffsetArg<Idx>...>::Type
|
||||
eval(QtPrivate::IndexesList<Idx...>) noexcept;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
} // namespace QtPrivate
|
||||
|
||||
template <typename ViewHandler, bool DisableStaticAssert = false>
|
||||
struct QHttpServerRouterViewTraits
|
||||
{
|
||||
using Helpers = typename QtPrivate::RouterViewTraitsHelper<ViewHandler, DisableStaticAssert>;
|
||||
using ReturnType = typename Helpers::FunctionTraits::ReturnType;
|
||||
using Arguments = decltype(Helpers::Arguments::eval(typename Helpers::ArgumentIndexes{}));
|
||||
using BindableType = decltype(
|
||||
Helpers::template BindType<Arguments::CapturableCount>::eval(
|
||||
typename Arguments::PlaceholdersIndexes{}));
|
||||
};
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHTTPSERVERROUTERVIEWTRAITS_H
|
||||
109
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverviewtraits.h
Normal file
109
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverviewtraits.h
Normal file
@ -0,0 +1,109 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 Mikhail Svetkin <mikhail.svetkin@gmail.com>
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHTTPSERVERVIEWTRAITS_H
|
||||
#define QHTTPSERVERVIEWTRAITS_H
|
||||
|
||||
#include <QtHttpServer/qhttpserverviewtraits_impl.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QHttpServerRequest;
|
||||
class QHttpServerResponse;
|
||||
|
||||
namespace QtPrivate {
|
||||
|
||||
template <typename ViewHandler, bool DisableStaticAssert>
|
||||
struct AfterRequestViewTraitsHelper : ViewTraits<ViewHandler, DisableStaticAssert> {
|
||||
using VTraits = ViewTraits<ViewHandler, DisableStaticAssert>;
|
||||
using FunctionTraits = typename VTraits::FTraits;
|
||||
|
||||
static_assert(DisableStaticAssert ||
|
||||
FunctionTraits::ArgumentCount == 2 ||
|
||||
FunctionTraits::ArgumentCount == 1,
|
||||
"ViewHandler arguments error: "
|
||||
"afterRequest can only accept QHttpServerResponse and QHttpServerRequest");
|
||||
|
||||
static_assert(DisableStaticAssert ||
|
||||
std::is_same<typename FunctionTraits::ReturnType,
|
||||
QHttpServerResponse>::value,
|
||||
"ViewHandler return type error: "
|
||||
"Return type can only be QHttpServerResponse");
|
||||
|
||||
template<int I>
|
||||
struct ArgumentChecker {
|
||||
using IsRequest = typename VTraits::template Special<I, const QHttpServerRequest &>;
|
||||
static_assert(IsRequest::AssertCondition,
|
||||
"ViewHandler arguments error: "
|
||||
"QHttpServerRequest can only be passed as a const reference");
|
||||
|
||||
using IsResponse = typename VTraits::template Special<I, QHttpServerResponse &&>;
|
||||
static_assert(IsResponse::AssertCondition,
|
||||
"ViewHandler arguments error: "
|
||||
"QHttpServerResponse can only be passed as a universal reference");
|
||||
|
||||
using IsSpecial = CheckAny<IsRequest, IsResponse>;
|
||||
|
||||
static constexpr bool Valid = IsSpecial::Valid;
|
||||
static constexpr bool StaticAssert = IsSpecial::StaticAssert;
|
||||
};
|
||||
|
||||
struct Arguments {
|
||||
template<int ... I>
|
||||
struct ArgumentsReturn {
|
||||
template<int Idx>
|
||||
using Arg = ArgumentChecker<Idx>;
|
||||
static constexpr bool Valid = QtPrivate::StaticMath::And::eval(Arg<I>::Valid...);
|
||||
static constexpr bool StaticAssert = QtPrivate::StaticMath::And::eval(
|
||||
Arg<I>::StaticAssert...);
|
||||
using Last = Arg<FunctionTraits::ArgumentIndexMax>;
|
||||
static constexpr std::size_t Count = FunctionTraits::ArgumentCount;
|
||||
};
|
||||
|
||||
template<int ... I>
|
||||
static constexpr ArgumentsReturn<I...> eval(QtPrivate::IndexesList<I...>) noexcept
|
||||
{
|
||||
return ArgumentsReturn<I...>{};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace QtPrivate
|
||||
|
||||
template <typename ViewHandler, bool DisableStaticAssert = false>
|
||||
struct QHttpServerAfterRequestViewTraits
|
||||
{
|
||||
using Helpers = typename QtPrivate::AfterRequestViewTraitsHelper<ViewHandler, DisableStaticAssert>;
|
||||
using Arguments = decltype(Helpers::Arguments::eval(typename Helpers::ArgumentIndexes{}));
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHTTPSERVERVIEWTRAITS_H
|
||||
@ -0,0 +1,194 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2020 Mikhail Svetkin <mikhail.svetkin@gmail.com>
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QHTTPSERVERVIEWTRAITS_IMPL_H
|
||||
#define QHTTPSERVERVIEWTRAITS_IMPL_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
#include <QtCore/qmetatype.h>
|
||||
#include <QtCore/qnamespace.h>
|
||||
#include <QtCore/qobjectdefs.h>
|
||||
|
||||
#include <functional>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QtPrivate {
|
||||
|
||||
template<typename T>
|
||||
struct RemoveCVRef
|
||||
{
|
||||
using Type = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
|
||||
};
|
||||
|
||||
|
||||
template<bool classMember, typename ReturnT, typename ... Args>
|
||||
struct FunctionTraitsHelper
|
||||
{
|
||||
static constexpr const int ArgumentCount = sizeof ... (Args);
|
||||
static constexpr const int ArgumentIndexMax = ArgumentCount - 1;
|
||||
static constexpr const bool IsClassMember = classMember;
|
||||
using ReturnType = ReturnT;
|
||||
|
||||
template <int I>
|
||||
struct Arg {
|
||||
using Type = typename std::tuple_element<I, std::tuple<Args...>>::type;
|
||||
|
||||
using CleanType = typename QtPrivate::RemoveCVRef<Type>::Type;
|
||||
|
||||
static constexpr bool Defined = QMetaTypeId2<CleanType>::Defined;
|
||||
};
|
||||
};
|
||||
|
||||
template<bool classMember, typename ReturnT>
|
||||
struct FunctionTraitsHelper<classMember, ReturnT>
|
||||
{
|
||||
static constexpr const int ArgumentCount = 0;
|
||||
static constexpr const int ArgumentIndexMax = -1;
|
||||
static constexpr const bool IsClassMember = classMember;
|
||||
using ReturnType = ReturnT;
|
||||
|
||||
template <int I>
|
||||
struct Arg {
|
||||
using Type = std::false_type;
|
||||
using CleanType = Type;
|
||||
static constexpr bool Defined = QMetaTypeId2<CleanType>::Defined;
|
||||
};
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct FunctionTraits;
|
||||
|
||||
template<typename T>
|
||||
struct FunctionTraits : public FunctionTraits<decltype(&T::operator())>{};
|
||||
|
||||
template<typename ReturnT, typename ... Args>
|
||||
struct FunctionTraits<ReturnT (*)(Args...)>
|
||||
: public FunctionTraitsHelper<false, ReturnT, Args...>
|
||||
{
|
||||
};
|
||||
|
||||
template<class ReturnT, class ClassT, class ...Args>
|
||||
struct FunctionTraits<ReturnT (ClassT::*)(Args...) const>
|
||||
: public FunctionTraitsHelper<true, ReturnT, Args...>
|
||||
{
|
||||
using classType = ClassT;
|
||||
};
|
||||
|
||||
struct StaticMath {
|
||||
template <template<typename> class Predicate, bool defaultValue>
|
||||
struct Loop {
|
||||
static constexpr bool eval() noexcept {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
template<typename T, typename ... N>
|
||||
static constexpr T eval(const T it, N ...n) noexcept {
|
||||
return Predicate<T>::eval(it, eval(n...));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct SumPredicate {
|
||||
static constexpr T eval(const T rs, const T ls) noexcept
|
||||
{
|
||||
return rs + ls;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct AndPredicate {
|
||||
static constexpr T eval(const T rs, const T ls) noexcept
|
||||
{
|
||||
return rs && ls;
|
||||
}
|
||||
};
|
||||
|
||||
using Sum = Loop<SumPredicate, false>;
|
||||
using And = Loop<AndPredicate, true>;
|
||||
using Or = Sum;
|
||||
};
|
||||
|
||||
template<typename ... T>
|
||||
struct CheckAny {
|
||||
static constexpr bool Value = StaticMath::Or::eval(T::Value...);
|
||||
static constexpr bool Valid = StaticMath::Or::eval(T::Valid...);
|
||||
static constexpr bool StaticAssert = StaticMath::Or::eval(T::StaticAssert...);
|
||||
};
|
||||
|
||||
template<typename ViewHandler, bool DisableStaticAssert>
|
||||
struct ViewTraits {
|
||||
using FTraits = FunctionTraits<ViewHandler>;
|
||||
using ArgumentIndexes = typename Indexes<FTraits::ArgumentCount>::Value;
|
||||
|
||||
template<int I, typename Special>
|
||||
struct SpecialHelper {
|
||||
using Arg = typename FTraits::template Arg<I>;
|
||||
using CleanSpecialT = typename RemoveCVRef<Special>::Type;
|
||||
|
||||
static constexpr bool TypeMatched = std::is_same<typename Arg::CleanType, CleanSpecialT>::value;
|
||||
static constexpr bool TypeCVRefMatched = std::is_same<typename Arg::Type, Special>::value;
|
||||
|
||||
static constexpr bool ValidPosition =
|
||||
(I == FTraits::ArgumentIndexMax ||
|
||||
I == FTraits::ArgumentIndexMax - 1);
|
||||
static constexpr bool ValidAll = TypeCVRefMatched && ValidPosition;
|
||||
|
||||
static constexpr bool AssertCondition =
|
||||
DisableStaticAssert || !TypeMatched || TypeCVRefMatched;
|
||||
|
||||
static constexpr bool AssertConditionOrder =
|
||||
DisableStaticAssert || !TypeMatched || ValidPosition;
|
||||
|
||||
static constexpr bool StaticAssert = AssertCondition && AssertConditionOrder;
|
||||
|
||||
static_assert(AssertConditionOrder,
|
||||
"ViewHandler arguments error: "
|
||||
"QHttpServerRequest or QHttpServerResponder"
|
||||
" can only be the last argument");
|
||||
};
|
||||
|
||||
template<int I, typename T>
|
||||
struct Special {
|
||||
using Helper = SpecialHelper<I, T>;
|
||||
static constexpr bool Value = Helper::TypeMatched;
|
||||
static constexpr bool Valid = Helper::ValidAll;
|
||||
static constexpr bool StaticAssert = Helper::StaticAssert;
|
||||
static constexpr bool AssertCondition = Helper::AssertCondition;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace QtPrivate
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QHTTPSERVERVIEWTRAITS_IMPL_H
|
||||
50
Lib/QtHTTPServer/include/QtHttpServer/qthttpserverglobal.h
Normal file
50
Lib/QtHTTPServer/include/QtHttpServer/qthttpserverglobal.h
Normal file
@ -0,0 +1,50 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QTHTTPSERVERGLOBAL_H
|
||||
#define QTHTTPSERVERGLOBAL_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#ifndef QT_STATIC
|
||||
# if defined(QT_BUILD_HTTPSERVER_LIB)
|
||||
# define Q_HTTPSERVER_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define Q_HTTPSERVER_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
#else
|
||||
# define Q_HTTPSERVER_EXPORT
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QTHTTPSERVERGLOBAL_H
|
||||
|
||||
65
Lib/QtHTTPServer/include/QtSslServer/qsslserver.h
Normal file
65
Lib/QtHTTPServer/include/QtSslServer/qsslserver.h
Normal file
@ -0,0 +1,65 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 Sylvain Garcia <garcia.6l20@gmail.com>.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QSSLSERVER_H
|
||||
#define QSSLSERVER_H
|
||||
|
||||
#include <QtSslServer/qtsslserverglobal.h>
|
||||
|
||||
#include <QtNetwork/qtcpserver.h>
|
||||
#include <QtNetwork/qsslconfiguration.h>
|
||||
|
||||
#include <QtCore/qscopedpointer.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSslServerPrivate;
|
||||
class Q_SSLSERVER_EXPORT QSslServer : public QTcpServer
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QSslServer(QObject *parent = nullptr);
|
||||
QSslServer(const QSslConfiguration &sslConfiguration, QObject *parent = nullptr);
|
||||
~QSslServer();
|
||||
|
||||
void setSslConfiguration(const QSslConfiguration &sslConfiguration);
|
||||
|
||||
Q_SIGNALS:
|
||||
void sslErrors(QSslSocket *socket, const QList<QSslError> &errors);
|
||||
|
||||
protected:
|
||||
void incomingConnection(qintptr handle) override final;
|
||||
|
||||
private:
|
||||
QScopedPointer<QSslServerPrivate> d;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QSSLSERVER_HPP
|
||||
45
Lib/QtHTTPServer/include/QtSslServer/qsslserver_p.h
Normal file
45
Lib/QtHTTPServer/include/QtSslServer/qsslserver_p.h
Normal file
@ -0,0 +1,45 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 Sylvain Garcia <garcia.6l20@gmail.com>.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QSSLSERVER_P_H
|
||||
#define QSSLSERVER_P_H
|
||||
|
||||
#include <QtSslServer/qsslserver.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class QSslServerPrivate
|
||||
{
|
||||
public:
|
||||
QSslConfiguration sslConfiguration;
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QSSLSERVER_P_H
|
||||
49
Lib/QtHTTPServer/include/QtSslServer/qtsslserverglobal.h
Normal file
49
Lib/QtHTTPServer/include/QtSslServer/qtsslserverglobal.h
Normal file
@ -0,0 +1,49 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2019 Sylvain Garcia <garcia.6l20@gmail.com>.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of the QtHttpServer module of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:GPL$
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 or (at your option) any later version
|
||||
** approved by the KDE Free Qt Foundation. The licenses are as published by
|
||||
** the Free Software Foundation and appearing in the file LICENSE.GPL3
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef QTSSLSERVERGLOBAL_H
|
||||
#define QTSSLSERVERGLOBAL_H
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#ifndef QT_STATIC
|
||||
# if defined(QT_BUILD_SSLSERVER_LIB)
|
||||
# define Q_SSLSERVER_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define Q_SSLSERVER_EXPORT Q_DECL_IMPORT
|
||||
# endif
|
||||
#else
|
||||
# define Q_SSLSERVER_EXPORT
|
||||
#endif
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QTSSLSERVERGLOBAL_H
|
||||
BIN
Lib/QtHTTPServer/libQt5HttpServer.a
Normal file
BIN
Lib/QtHTTPServer/libQt5HttpServer.a
Normal file
Binary file not shown.
BIN
Lib/QtHTTPServer/libQt5SslServer.a
Normal file
BIN
Lib/QtHTTPServer/libQt5SslServer.a
Normal file
Binary file not shown.
13
Lib/QtHTTPServer/pkgconfig/Qt5HttpServer.pc
Normal file
13
Lib/QtHTTPServer/pkgconfig/Qt5HttpServer.pc
Normal file
@ -0,0 +1,13 @@
|
||||
prefix=C:/Qt/Qt5.14.2/5.14.2/mingw73_64
|
||||
exec_prefix=${prefix}
|
||||
libdir=${prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
|
||||
Name: Qt5 HttpServer
|
||||
Description: Qt HttpServer module
|
||||
Version: 5.12.0
|
||||
Libs: -L${libdir} -lQt5HttpServer
|
||||
Cflags: -DQT_HTTPSERVER_LIB -I${includedir}/QtHttpServer -I${includedir}
|
||||
Requires: Qt5Network Qt5Core Qt5WebSockets Qt5SslServer Qt5Concurrent
|
||||
|
||||
13
Lib/QtHTTPServer/pkgconfig/Qt5SslServer.pc
Normal file
13
Lib/QtHTTPServer/pkgconfig/Qt5SslServer.pc
Normal file
@ -0,0 +1,13 @@
|
||||
prefix=C:/Qt/Qt5.14.2/5.14.2/mingw73_64
|
||||
exec_prefix=${prefix}
|
||||
libdir=${prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
|
||||
Name: Qt5 SslServer
|
||||
Description: Qt SslServer module
|
||||
Version: 5.12.0
|
||||
Libs: -L${libdir} -lQt5SslServer
|
||||
Cflags: -DQT_SSLSERVER_LIB -I${includedir}/QtSslServer -I${includedir}
|
||||
Requires: Qt5Network Qt5Core
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
#QT += Network
|
||||
#QT += gui declarative network
|
||||
QT += gui network serialport
|
||||
QT += gui network serialport mqtt
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
#CONFIG += console
|
||||
@ -41,7 +41,38 @@ HEADERS += \
|
||||
Sources/Chalet/ChaletNetworkMessage.h \
|
||||
Sources/HttpServer/HttpServer.h \
|
||||
Sources/BlynkCloudClient.h \
|
||||
Sources/Chalet/ChaletDataLogger.h
|
||||
Sources/Chalet/ChaletDataLogger.h \
|
||||
Sources/Chalet/ChaletUbidotsInterface.h \
|
||||
Sources/Chalet/ThingsBoardInterface.h \
|
||||
Lib/QtHTTPServer/include/QtHttpServer/qabstracthttpserver.h \
|
||||
Lib/QtHTTPServer/include/QtHttpServer/qabstracthttpserver_p.h \
|
||||
Lib/QtHTTPServer/include/QtHttpServer/qhttpserver.h \
|
||||
Lib/QtHTTPServer/include/QtHttpServer/qhttpserver_p.h \
|
||||
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverfutureresponse.h \
|
||||
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverliterals_p.h \
|
||||
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverrequest.h \
|
||||
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverrequest_p.h \
|
||||
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverresponder.h \
|
||||
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverresponder_p.h \
|
||||
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverresponse.h \
|
||||
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverresponse_p.h \
|
||||
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverrouter.h \
|
||||
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverrouter_p.h \
|
||||
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverrouterrule.h \
|
||||
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverrouterrule_p.h \
|
||||
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverrouterviewtraits.h \
|
||||
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverviewtraits.h \
|
||||
Lib/QtHTTPServer/include/QtHttpServer/qhttpserverviewtraits_impl.h \
|
||||
Lib/QtHTTPServer/include/QtHttpServer/qthttpserverglobal.h \
|
||||
Lib/QtHTTPServer/include/QtSslServer/qsslserver.h \
|
||||
Lib/QtHTTPServer/include/QtSslServer/qsslserver_p.h \
|
||||
Lib/QtHTTPServer/include/QtSslServer/qtsslserverglobal.h \
|
||||
Sources/ImageCropper/imagecropper.h \
|
||||
Sources/ImageCropper/imagecropper_e.h \
|
||||
Sources/ImageCropper/imagecropper_p.h \
|
||||
Sources/Modbus/ModbusBackend.h \
|
||||
Sources/Modbus/ModbusRepository.h \
|
||||
Sources/Chalet/ChaletModbusServer.h
|
||||
|
||||
SOURCES += \
|
||||
Sources/Chalet/ChaletData.cpp \
|
||||
@ -77,7 +108,13 @@ SOURCES += \
|
||||
Sources/Chalet/ChaletNetworkMessage.cpp \
|
||||
Sources/HttpServer/HttpServer.cpp \
|
||||
Sources/BlynkCloudClient.cpp \
|
||||
Sources/Chalet/ChaletDataLogger.cpp
|
||||
Sources/Chalet/ChaletDataLogger.cpp \
|
||||
Sources/Chalet/ChaletUbidotsInterface.cpp \
|
||||
Sources/Chalet/ThingsBoardInterface.cpp \
|
||||
Sources/ImageCropper/imagecropper.cpp \
|
||||
Sources/Modbus/ModbusBackend.cpp \
|
||||
Sources/Modbus/ModbusRepository.cpp \
|
||||
Sources/Chalet/ChaletModbusServer.cpp
|
||||
|
||||
DEFINES -= Q_OS_UNIX
|
||||
|
||||
@ -96,8 +133,7 @@ INCLUDEPATH += $$PWD/ \
|
||||
$$PWD/Sources/Chalet \
|
||||
$$PWD/Sources/HttpServer \
|
||||
$$PWD/blynk-library-master/src/ \
|
||||
$$PWD/Sources/Modbus \
|
||||
# $$PWD/Lib/QtHTTPServer/include/ \
|
||||
|
||||
FORMS +=
|
||||
|
||||
DISTFILES += \
|
||||
../../../../Dev/qthttpserver/mkspecs/modules/qt_lib_httpserver.pri
|
||||
LIBS += -L$$PWD/Lib/QtHTTPServer/ -lQt5HttpServer
|
||||
|
||||
@ -32,7 +32,7 @@ int C232NetworkCommIF::NewFrameReceived(int DeviceID, int DeviceAddress, int Mes
|
||||
// return 1;
|
||||
//}
|
||||
|
||||
int C232NetworkCommIF::SendNetworkMessage(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray Data)
|
||||
int C232NetworkCommIF::SendNetworkMessage(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray *Data)
|
||||
{
|
||||
Q_UNUSED(DeviceID)
|
||||
Q_UNUSED(DeviceAddress)
|
||||
|
||||
@ -15,7 +15,7 @@ public:
|
||||
int NewFrameReceived(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray Data);
|
||||
|
||||
//NetworkCommIF implementation
|
||||
virtual int SendNetworkMessage(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray Data);
|
||||
virtual int SendNetworkMessage(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray *Data);
|
||||
|
||||
private:
|
||||
CNetworkDevice *mDeviceHandle;
|
||||
|
||||
@ -28,7 +28,7 @@ int C485NetworkCommIF::RegisterNewDevice(CNetworkDevice *NewDevice)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int C485NetworkCommIF::SendNetworkMessage(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray Data)
|
||||
int C485NetworkCommIF::SendNetworkMessage(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray *Data)
|
||||
{
|
||||
Q_UNUSED(DeviceID)
|
||||
Q_UNUSED(DeviceAddress)
|
||||
|
||||
@ -16,7 +16,7 @@ public:
|
||||
virtual int NewFrameReceived(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray Data);
|
||||
|
||||
//NetworkCommIF implementation
|
||||
virtual int SendNetworkMessage(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray Data);
|
||||
virtual int SendNetworkMessage(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray *Data);
|
||||
|
||||
private:
|
||||
QList<CNetworkDevice *> mDevicesList;
|
||||
|
||||
@ -12,7 +12,7 @@ public:
|
||||
CNetworkDevice *mDevicePtr;
|
||||
CAbstractNetworkCommIF(){mDevicePtr = 0;}
|
||||
virtual ~CAbstractNetworkCommIF() {}
|
||||
virtual int SendNetworkMessage(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray Data) = 0;
|
||||
virtual int SendNetworkMessage(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray *Data) = 0;
|
||||
};
|
||||
|
||||
#endif // ABSTRACTNETWORKINTERFACE_H
|
||||
|
||||
@ -24,7 +24,7 @@ int CAvReceiverInterface::NewDeviceFrameReceived(int DeviceID, int DeviceAddress
|
||||
case AV_RECEIVER_INTERFACE_GENERAL_STATUS_REQUEST:
|
||||
{
|
||||
QByteArray data = mAvReceiverDevice->GetReceiverStatus().ToByteArray();
|
||||
mNetworkInterfacePtr->SendNetworkMessage(ID_AVRECEIVER_INTERFACE,mDeviceAddress,AV_RECEIVER_INTERFACE_GENERAL_STATUS_RESPONSE,data.size(),data);
|
||||
mNetworkInterfacePtr->SendNetworkMessage(ID_AVRECEIVER_INTERFACE,mDeviceAddress,AV_RECEIVER_INTERFACE_GENERAL_STATUS_RESPONSE,data.size(),&data);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@ CChaletMainStatus::CChaletMainStatus()
|
||||
mIsOnline = false;
|
||||
mHarakiriDone = false;
|
||||
mStatusToggleBit = 0;
|
||||
mLostRequestPercentage = 0;
|
||||
|
||||
}
|
||||
|
||||
@ -52,6 +53,10 @@ QByteArray CChaletMainStatus::ToByteArray()
|
||||
Strm << mBatterySOC;
|
||||
Strm << mIsOnline;
|
||||
Strm << mCurrentSensorStatus;
|
||||
Strm << mLostRequestPercentage;
|
||||
Strm << mThisStatusDateTime;
|
||||
Strm << mLastLoraStatus;
|
||||
Strm << mStatusToggleBit;
|
||||
|
||||
return Data;
|
||||
}
|
||||
|
||||
@ -30,6 +30,11 @@ public:
|
||||
bool mStatusToggleBit;
|
||||
|
||||
QDateTime mLastLoraStatus;
|
||||
QDateTime mThisStatusDateTime;
|
||||
|
||||
float mLostRequestPercentage;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -1,36 +1,231 @@
|
||||
#include "ChaletDataLogger.h"
|
||||
#include <QDateTime>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QDataStream>
|
||||
#include <QFileInfo>
|
||||
|
||||
|
||||
|
||||
CChaletDataLogger::CChaletDataLogger(QObject *parent) : QObject(parent)
|
||||
{
|
||||
mChaletLogFile = 0;
|
||||
OpenTodaysFile();
|
||||
mChaletNewLogFileTimer = new QTimer;
|
||||
connect(mChaletNewLogFileTimer,SIGNAL(timeout()),this,SLOT(NewLogFileTimerExpired()));
|
||||
mChaletNewLogFileTimer->setInterval(1000);
|
||||
mChaletNewLogFileTimer->setSingleShot(false);
|
||||
mChaletNewLogFileTimer->start();
|
||||
|
||||
}
|
||||
|
||||
int CChaletDataLogger::OpenTodaysFile()
|
||||
{
|
||||
mTodaysDate = QDateTime::currentDateTime().date();
|
||||
bool create = false;
|
||||
mChaletLogFile = new QFile(CHALET_LORA_DATA_LOG_FILENAME);
|
||||
if(QFile::exists(CHALET_LORA_DATA_LOG_FILENAME) == false)
|
||||
QString LogFileName(CHALET_LORA_DATA_LOG_DIR);
|
||||
LogFileName.append("ChaletLora-");
|
||||
LogFileName.append(mTodaysDate.toString("yyyy-MM-dd"));
|
||||
LogFileName.append(".csv");
|
||||
|
||||
if(mChaletLogFile != 0)
|
||||
{
|
||||
if(mChaletLogFile->isOpen())
|
||||
{
|
||||
mChaletLogFile->close();
|
||||
}
|
||||
mChaletLogFile->setFileName(LogFileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
mChaletLogFile = new QFile(LogFileName);
|
||||
}
|
||||
|
||||
//Check if today's file already exist, otherwise create it...
|
||||
if(QFile::exists(LogFileName) == false)
|
||||
create = true;
|
||||
|
||||
if(mChaletLogFile->open(QIODevice::ReadWrite|QIODevice::Append/*|QIODevice::Text*/) == false)
|
||||
if(mChaletLogFile->open(QIODevice::ReadWrite|QIODevice::Append|QIODevice::Unbuffered) == false)
|
||||
{
|
||||
delete mChaletLogFile;
|
||||
mChaletLogFile = 0;
|
||||
qDebug("Cannot open chalet LORA log file...");
|
||||
return;
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
if(create)
|
||||
{
|
||||
qDebug("Creating new chalet LORA log file...");
|
||||
QString Header("Date;Heure;Courant Batterie;Tension Batterie;Inverter;Wifi\n");
|
||||
int bytes = mChaletLogFile->write(qPrintable(Header));
|
||||
mChaletLogFile->write(qPrintable(Header));
|
||||
mChaletLogFile->flush();
|
||||
|
||||
}
|
||||
// mChaletLogFile->close();
|
||||
|
||||
qDebug("Chalet LORA log file created successfully");
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
QByteArray *CChaletDataLogger::GetChaletData(QDate StartDate)
|
||||
{
|
||||
|
||||
if(StartDate > QDate::currentDate())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
QFile *LogFile =0;
|
||||
|
||||
bool done = false;
|
||||
QByteArray WorkArray, *DataArray;
|
||||
DataArray = new QByteArray;
|
||||
int NbReadings = 0;
|
||||
DataArray->clear();
|
||||
|
||||
while(!done)
|
||||
{
|
||||
|
||||
if(StartDate > QDate::currentDate())
|
||||
{
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
// else if(StartDate == QDate::currentDate())
|
||||
// {
|
||||
// LogFile = mChaletLogFile;
|
||||
// }
|
||||
else
|
||||
{
|
||||
QString LogFileName(CHALET_LORA_DATA_LOG_DIR);
|
||||
LogFileName.append("ChaletLora-");
|
||||
LogFileName.append(StartDate.toString("yyyy-MM-dd"));
|
||||
LogFileName.append(".csv");
|
||||
|
||||
if(QFileInfo::exists(LogFileName))
|
||||
{
|
||||
LogFile = new QFile(LogFileName);
|
||||
if(LogFile->open(QIODevice::ReadOnly|QIODevice::Unbuffered) == false)
|
||||
{
|
||||
delete LogFile;
|
||||
LogFile = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogFile = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if(mChaletLogFile == 0)
|
||||
// {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
// if(mChaletLogFile->isOpen() == false)
|
||||
// {
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
if(LogFile != 0)
|
||||
{
|
||||
|
||||
LogFile->seek(0); //seek to the beginning of the log file
|
||||
WorkArray = LogFile->readLine(); //read and discard the header line.
|
||||
bool Finished = false;
|
||||
while(!Finished)
|
||||
{
|
||||
WorkArray.clear();
|
||||
WorkArray = LogFile->readLine();
|
||||
if(WorkArray.isEmpty())
|
||||
{
|
||||
Finished = true;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
QStringList LineData = QString(WorkArray).remove("\n").split(QChar(';'));
|
||||
if(LineData.size() == 6) //if we don't have 6 parameters, something went very wrong
|
||||
{ //"Date;Heure;Courant Batterie;Tension Batterie;Inverter;Wifi\n");
|
||||
|
||||
QString date = LineData.at(0);
|
||||
// QDate Date = QDate::fromString("yyyy-MM-dd",LineData.at(0));
|
||||
QDate Date = QDate::currentDate();
|
||||
Date = QDate::fromString(date,"yyyy-MM-dd");
|
||||
QString time = LineData.at(1);
|
||||
// QTime Time = QTime::fromString("hh:mm:ss",LineData.at(1));
|
||||
QTime Time = QTime::currentTime();
|
||||
Time= QTime::fromString(time,"hh:mm:ss");
|
||||
QDateTime DateTime(Date,Time);
|
||||
// qDebug("Date: %s",qPrintable(Date.toString("yyyy-MM-dd")));
|
||||
// qDebug("Time: %s",qPrintable(Time.toString("hh:mm:ss")));
|
||||
// qDebug("Date Time: %s",qPrintable(DateTime.toString("yyyy-MM-dd-hh:mm:ss")));
|
||||
|
||||
// time.setDate(QDate().fromString("yyyy-MM-dd",LineData.at(0)));
|
||||
// time.setTime(QTime().fromString("hh:mm:ss",LineData.at(1)));
|
||||
QString temp = LineData.at(2);
|
||||
bool OK;
|
||||
qint16 BattCurrent = temp.toInt(&OK);
|
||||
temp = LineData.at(3);
|
||||
float BattVoltage = temp.toFloat(&OK);
|
||||
temp = LineData.at(4);
|
||||
quint8 InverterStatus = 0;
|
||||
if(temp == "ON")
|
||||
{
|
||||
InverterStatus = 1;
|
||||
}
|
||||
temp = LineData.at(5);
|
||||
quint8 WiFiStatus = 0;
|
||||
if(temp == "ON")
|
||||
{
|
||||
WiFiStatus = 1;
|
||||
}
|
||||
CChaletMainStatus CurBlob;
|
||||
CurBlob.mThisStatusDateTime = DateTime;
|
||||
CurBlob.mBatteryCurrent = BattCurrent;
|
||||
CurBlob.mBatteryVoltage = BattVoltage;
|
||||
CurBlob.mInverterRelayStatus = InverterStatus;
|
||||
CurBlob.mWiFiModuleStatus = WiFiStatus;
|
||||
|
||||
DataArray->append(CurBlob.ToByteArray());
|
||||
NbReadings++;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug("Invalid nb. of parameters in today's data extraction");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(LogFile != mChaletLogFile && LogFile != 0)
|
||||
{
|
||||
LogFile->close();
|
||||
delete LogFile;
|
||||
}
|
||||
LogFile = 0;
|
||||
StartDate = StartDate.addDays(1);
|
||||
|
||||
}
|
||||
|
||||
QByteArray Readings;
|
||||
QDataStream strm(&Readings,QIODevice::WriteOnly);
|
||||
strm.device()->seek(0);
|
||||
strm << NbReadings;
|
||||
DataArray->prepend(Readings);
|
||||
|
||||
return DataArray; //Don't forget to delete!!!
|
||||
}
|
||||
|
||||
QByteArray *CChaletDataLogger::GetTodaysData()
|
||||
{
|
||||
return GetChaletData(QDate::currentDate());
|
||||
}
|
||||
|
||||
|
||||
CChaletDataLogger::~CChaletDataLogger()
|
||||
{
|
||||
if(mChaletLogFile)
|
||||
@ -38,6 +233,7 @@ CChaletDataLogger::~CChaletDataLogger()
|
||||
mChaletLogFile->close();
|
||||
delete mChaletLogFile;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool CChaletDataLogger::LogChaletLORAData(CChaletMainStatus *Data)
|
||||
@ -82,7 +278,21 @@ bool CChaletDataLogger::LogChaletLORAData(CChaletMainStatus *Data)
|
||||
mChaletLogFile->write(qPrintable(CSVData));
|
||||
mChaletLogFile->flush();
|
||||
|
||||
|
||||
|
||||
|
||||
// mChaletLogFile->close();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CChaletDataLogger::NewLogFileTimerExpired()
|
||||
{
|
||||
if(QDateTime::currentDateTime().date() > mTodaysDate) //If it's midnight...
|
||||
{
|
||||
qDebug("It's midnight... creating today's file...");
|
||||
OpenTodaysFile();
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,9 +4,11 @@
|
||||
#include <QObject>
|
||||
#include <QFile>
|
||||
#include "ChaletData.h"
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
//#define CHALET_LORA_DATA_LOG_FILENAME "./ChaletLogs/ChaletLora.csv"
|
||||
#define CHALET_LORA_DATA_LOG_FILENAME "D:/Main/Chalet/LoraLogs/ChaletLora.csv"
|
||||
#define CHALET_LORA_DATA_LOG_DIR "D:/Main/Chalet/LoraLogs/"
|
||||
|
||||
class CChaletMainStatus;
|
||||
|
||||
@ -18,13 +20,25 @@ public:
|
||||
~CChaletDataLogger();
|
||||
|
||||
bool LogChaletLORAData(CChaletMainStatus *Data);
|
||||
QByteArray *GetTodaysData();
|
||||
QByteArray *GetChaletData(QDate StartDate);
|
||||
|
||||
QFile *mChaletLogFile;
|
||||
QTimer *mChaletNewLogFileTimer;
|
||||
QDate mTodaysDate;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private:
|
||||
int OpenTodaysFile();
|
||||
|
||||
signals:
|
||||
|
||||
|
||||
public slots:
|
||||
void NewLogFileTimerExpired();
|
||||
};
|
||||
|
||||
#endif // CHALETDATALOGGER_H
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
#include "ChaletInterface.h"
|
||||
#include "ChaletDataLogger.h"
|
||||
|
||||
CChaletInterface::CChaletInterface(int Address, CAbstractNetworkCommIF *NetworkInterface, CChaletLoraDevice *DevicePtr):
|
||||
CNetworkDevice(ID_CHALET_INTERFACE,Address,NetworkInterface)
|
||||
{
|
||||
mChaletLoraDevice = DevicePtr;
|
||||
mChaletDataLogger = mChaletLoraDevice->GetDataLoggerHandle();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -24,7 +27,7 @@ int CChaletInterface::NewDeviceFrameReceived(int DeviceID, int DeviceAddress, in
|
||||
case CHALET_INTERFACE_GENERAL_STATUS_REQUEST:
|
||||
{
|
||||
QByteArray data = mChaletLoraDevice->GetChaletMainStatus().ToByteArray();
|
||||
mNetworkInterfacePtr->SendNetworkMessage(ID_CHALET_INTERFACE,mDeviceAddress,CHALET_INTERFACE_GENERAL_STATUS_RESPONSE,data.size(),data);
|
||||
mNetworkInterfacePtr->SendNetworkMessage(ID_CHALET_INTERFACE,mDeviceAddress,CHALET_INTERFACE_GENERAL_STATUS_RESPONSE,data.size(),&data);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -74,6 +77,25 @@ int CChaletInterface::NewDeviceFrameReceived(int DeviceID, int DeviceAddress, in
|
||||
mChaletLoraDevice->SendRebootCmd();
|
||||
break;
|
||||
}
|
||||
case CHALET_INTERFACE_GET_TODAYS_DATA_LOG_REQUEST:
|
||||
{
|
||||
QByteArray *data = mChaletDataLogger->GetTodaysData();
|
||||
mNetworkInterfacePtr->SendNetworkMessage(ID_CHALET_INTERFACE,mDeviceAddress,CHALET_INTERFACE_GET_TODAYS_DATA_LOG_RESPONSE,data->size(),data);
|
||||
delete data;
|
||||
break;
|
||||
}
|
||||
case CHALET_INTERFACE_GET_DATA_LOG_REQUEST:
|
||||
{
|
||||
QDate StartDate;
|
||||
QDataStream Strm(Data);
|
||||
Strm >> StartDate;
|
||||
QByteArray *data = mChaletDataLogger->GetChaletData(StartDate);
|
||||
mNetworkInterfacePtr->SendNetworkMessage(ID_CHALET_INTERFACE,mDeviceAddress,CHALET_INTERFACE_GET_DATA_LOG_RESPONSE,data->size(),data);
|
||||
delete data;
|
||||
break;
|
||||
}
|
||||
case CHALET_INTERFACE_GET_DATA_LOG_RESPONSE:
|
||||
case CHALET_INTERFACE_GET_TODAYS_DATA_LOG_RESPONSE:
|
||||
case CHALET_INTERFACE_GENERAL_STATUS_RESPONSE:
|
||||
case CHALET_INTERFACE_AC_POWER_STATE_STATUS_RESPONSE:
|
||||
case CHALET_INTERFACE_AC_POWER_SET_STATE_RESPONSE:
|
||||
@ -93,3 +115,8 @@ int CChaletInterface::NewDeviceFrameReceived(int DeviceID, int DeviceAddress, in
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
void CChaletInterface::SendChaletCommActivityBeacon()
|
||||
{
|
||||
mNetworkInterfacePtr->SendNetworkMessage(ID_CHALET_INTERFACE,mDeviceAddress,CHALET_INTERFACE_CHALET_ACTIVITY_RESPONSE,0,0);
|
||||
}
|
||||
|
||||
@ -2,8 +2,8 @@
|
||||
#define CCHALETINTERFACE_H
|
||||
|
||||
#include "NetworkDevice.h"
|
||||
#include "ChaletLoraDevice.h"
|
||||
|
||||
#include "ChaletLoraDevice.h"
|
||||
|
||||
class CChaletInterface: public QObject, public CNetworkDevice
|
||||
{
|
||||
@ -13,8 +13,10 @@ public:
|
||||
CChaletInterface(int Address, CAbstractNetworkCommIF *NetworkInterface, CChaletLoraDevice *DevicePtr);
|
||||
virtual int NewDeviceFrameReceived(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray Data);
|
||||
|
||||
void SendChaletCommActivityBeacon();
|
||||
private:
|
||||
CChaletLoraDevice *mChaletLoraDevice;
|
||||
CChaletDataLogger *mChaletDataLogger;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "ChaletLoraDevice.h"
|
||||
#include "GlobalDefine.h"
|
||||
#include "ChaletInterface.h"
|
||||
|
||||
|
||||
|
||||
@ -10,11 +11,16 @@ CChaletLoraDevice::CChaletLoraDevice(int Address, CAbstractNetworkCommIF *Networ
|
||||
mDeviceAddress = Address;
|
||||
mDeviceID = ID_CHALET_DEVICE;
|
||||
|
||||
|
||||
mChaletStatusTimer = new QTimer();
|
||||
mChaletStatusTimer->setInterval(1000);
|
||||
mChaletStatusTimer->setSingleShot(true);
|
||||
connect(mChaletStatusTimer,SIGNAL(timeout()),this,SLOT(CommTimerExpired()));
|
||||
|
||||
mJFUbidotsInterface = new CChaletJFUbidotsInterface("BBFF-tEq4lGAegEyP1H4EaYckNQ7ZHdZYzI");
|
||||
|
||||
mThingsBoardInterface.mChaletLoraDevice = this;
|
||||
|
||||
ResetCommStats();
|
||||
}
|
||||
|
||||
CChaletLoraDevice::~CChaletLoraDevice()
|
||||
@ -26,11 +32,16 @@ int CChaletLoraDevice::Start()
|
||||
{
|
||||
ScheduleChaletStatusRequest();
|
||||
mChaletStatusTimer->start(1000);
|
||||
mThingsBoardInterface.RegisterThingsboardRPC();
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int CChaletLoraDevice::NewDeviceFrameReceived(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray Data)
|
||||
{
|
||||
Q_UNUSED(DeviceID)
|
||||
Q_UNUSED(DeviceAddress)
|
||||
Q_UNUSED(DataSize)
|
||||
|
||||
switch(MessageID)
|
||||
{
|
||||
case CHALET_ACK:
|
||||
@ -69,20 +80,28 @@ int CChaletLoraDevice::NewDeviceFrameReceived(int DeviceID, int DeviceAddress, i
|
||||
mChaletMainStatus.mBatterySOC = temp2;
|
||||
|
||||
mChaletMainStatus.mStatusToggleBit = !mChaletMainStatus.mStatusToggleBit;
|
||||
mChaletMainStatus.mLastLoraStatus = QDateTime::currentDateTime();
|
||||
|
||||
CmdResponseReceived(CHALET_GENERAL_STATUS_REQUEST);
|
||||
qDebug("voltage: %f",mChaletMainStatus.mBatteryVoltage);
|
||||
qDebug("Current: %d",mChaletMainStatus.mBatteryCurrent);
|
||||
qDebug("SOC: %d",mChaletMainStatus.mBatterySOC);
|
||||
// qDebug("Current: %d",mChaletMainStatus.mBatteryCurrent);
|
||||
// qDebug("SOC: %d",mChaletMainStatus.mBatterySOC);
|
||||
qDebug("Inverter: %d",mChaletMainStatus.mInverterRelayStatus);
|
||||
|
||||
mChaletDataLogger.LogChaletLORAData(&mChaletMainStatus);
|
||||
|
||||
mJFUbidotsInterface->LogUbidotsChaletData(&mChaletMainStatus);
|
||||
|
||||
mBlynkInterface.UpdateChaletCurrent(mChaletMainStatus.mBatteryCurrent);
|
||||
mBlynkInterface.UpdateChaletVoltage(mChaletMainStatus.mBatteryVoltage);
|
||||
// mBlynkInterface.UpdateChaletWifiStatus((int)mChaletMainStatus.mInverterRelayStatus);
|
||||
mBlynkInterface.UpdateChaletInverterStatus((int)mChaletMainStatus.mInverterRelayStatus);
|
||||
mBlynkInterface.UpdateChaletStatusLed(((int)mChaletMainStatus.mStatusToggleBit)*255);
|
||||
|
||||
// mThingsBoardInterface.UpdateChaletVoltage(mChaletMainStatus.mBatteryVoltage);
|
||||
mThingsBoardInterface.UpdateChaletData(mChaletMainStatus.mInverterRelayStatus,mChaletMainStatus.mWiFiModuleStatus,mChaletMainStatus.mCurrentSensorStatus,mChaletMainStatus.mBatteryVoltage,mChaletMainStatus.mBatteryCurrent,mChaletMainStatus.mBatterySOC,mChaletMainStatus.mIsOnline);
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
case CHALET_AC_POWER_STATE_STATUS_RESPONSE:
|
||||
@ -185,6 +204,8 @@ void CChaletLoraDevice::CommTimerExpired()
|
||||
}
|
||||
}
|
||||
mPendingNetworkMsgList[0].ResendCounter++;
|
||||
mNbLostRequest++;
|
||||
ComputeCommStats();
|
||||
}
|
||||
|
||||
qDebug("Sending chalet request 0x%x",mPendingNetworkMsgList.at(0).mMessageID);
|
||||
@ -262,7 +283,9 @@ int CChaletLoraDevice::SendRebootCmd()
|
||||
|
||||
int CChaletLoraDevice::SendChaletCommand(int CmdID, int DataSize, QByteArray Data)
|
||||
{
|
||||
mNetworkInterfacePtr->SendNetworkMessage(ID_CHALET_DEVICE,mDeviceAddress,CmdID,DataSize,Data);
|
||||
mNetworkInterfacePtr->SendNetworkMessage(ID_CHALET_DEVICE,mDeviceAddress,CmdID,DataSize,&Data);
|
||||
mTotalNbRequest++;
|
||||
ComputeCommStats();
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
@ -351,3 +374,20 @@ int CChaletLoraDevice::ScheduleChaletCommand(int CmdID, QByteArray Data)
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int CChaletLoraDevice::ResetCommStats()
|
||||
{
|
||||
mLostRequestPercentage = 0.0;
|
||||
mTotalNbRequest = 0;
|
||||
mNbLostRequest = 0;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int CChaletLoraDevice::ComputeCommStats()
|
||||
{
|
||||
mLostRequestPercentage = ((float)mNbLostRequest/(float)mTotalNbRequest)*100;
|
||||
mChaletMainStatus.mLostRequestPercentage = mLostRequestPercentage;
|
||||
|
||||
// qDebug("Percent lost request: %f%%",mLostRequestPercentage);
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
@ -11,6 +11,9 @@
|
||||
#include <QList>
|
||||
#include "BlynkCloudClient.h"
|
||||
#include "ChaletDataLogger.h"
|
||||
#include "ChaletUbidotsInterface.h"
|
||||
#include "ThingsBoardInterface.h"
|
||||
|
||||
|
||||
#define LORA_MAGIC_WORD 0xBAADCAFE
|
||||
#define LORA_NORMAL_REQUEST_TIMEOUT 3000
|
||||
@ -37,22 +40,34 @@ public:
|
||||
|
||||
CChaletMainStatus GetChaletMainStatus() {return mChaletMainStatus;}
|
||||
CBlynkCloudClient mBlynkInterface;
|
||||
CThingsBoardInterface mThingsBoardInterface;
|
||||
|
||||
CChaletMainStatus mChaletMainStatus;
|
||||
QList<CChaletNetworkMessage> mPendingNetworkMsgList;
|
||||
CChaletDataLogger mChaletDataLogger;
|
||||
CChaletJFUbidotsInterface *mJFUbidotsInterface;
|
||||
|
||||
unsigned long long int mNbLostRequest, mTotalNbRequest;
|
||||
float mLostRequestPercentage;
|
||||
|
||||
CChaletDataLogger *GetDataLoggerHandle() {return &mChaletDataLogger;} //for Interface use...
|
||||
|
||||
|
||||
|
||||
int SendWiFiModuleSetState(bool State);
|
||||
int SendInverterPowerRelayState(bool State);
|
||||
int SendDOHarakiri();
|
||||
int SendRebootCmd();
|
||||
int SendChaletCommand(int CmdID,int DataSize, QByteArray Data);
|
||||
int ResetCommStats();
|
||||
int ComputeCommStats();
|
||||
|
||||
int CmdResponseReceived(int CmdID);
|
||||
int ScheduleChaletStatusRequest();
|
||||
int ScheduleChaletCommand(int CmdID, int DataSize, QByteArray Data);
|
||||
int ScheduleChaletCommand(int CmdID,QByteArray Data);
|
||||
|
||||
|
||||
public slots:
|
||||
void CommTimerExpired();
|
||||
|
||||
|
||||
7
Sources/Chalet/ChaletModbusServer.cpp
Normal file
7
Sources/Chalet/ChaletModbusServer.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
#include "ChaletModbusServer.h"
|
||||
|
||||
CChaletModbusServer::CChaletModbusServer(CModbusRepository *Repo, int ModbusPort, int DevID) :
|
||||
CModbusBackend(Repo)
|
||||
{
|
||||
|
||||
}
|
||||
25
Sources/Chalet/ChaletModbusServer.h
Normal file
25
Sources/Chalet/ChaletModbusServer.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef CHALETMODBUSSERVER_H
|
||||
#define CHALETMODBUSSERVER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <ModbusBackend.h>
|
||||
|
||||
class CChaletModbusServer : public CModbusBackend
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CChaletModbusServer(CModbusRepository *Repo, int ModbusPort, int DevID);
|
||||
virtual ~CChaletModbusServer();
|
||||
|
||||
int StartChaletModbusServer();
|
||||
int CloseChaletModbusServer();
|
||||
bool IsModbusConnected();
|
||||
|
||||
|
||||
|
||||
virtual void RegistersDatabaseUpdated(quint16 StartAddress, quint16 Length);
|
||||
virtual void ModbusRequestException(quint8 ExceptionCode, quint8 FctCode);
|
||||
};
|
||||
|
||||
#endif // CHALETMODUBSERVER_H
|
||||
89
Sources/Chalet/ChaletUbidotsInterface.cpp
Normal file
89
Sources/Chalet/ChaletUbidotsInterface.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
#include "ChaletUbidotsInterface.h"
|
||||
|
||||
CChaletUbidotsInterface::CChaletUbidotsInterface(QString UbidotsUsername, QObject *parent) : QObject(parent)
|
||||
{
|
||||
mUbidotsUsername = UbidotsUsername;
|
||||
// mUbidotsPascalChaletClient = new QMqttClient(this);
|
||||
// mUbidotsPascalChaletClient->setHostname("things.ubidots.com");
|
||||
// mUbidotsPascalChaletClient->setPort(1883);
|
||||
// mUbidotsPascalChaletClient->setUsername("BBFF-tEq4lGAegEyP1H4EaYckNQ7ZHdZYzI");
|
||||
// mUbidotsPascalChaletClient->setPassword("12");
|
||||
// mUbidotsPascalChaletClient->connectToHost();
|
||||
|
||||
mUbidotsChaletClient= new QMqttClient(this);
|
||||
mUbidotsChaletClient->setHostname(UBIDOTS_URL);
|
||||
mUbidotsChaletClient->setPort(UBIDOTS_PORT);
|
||||
mUbidotsChaletClient->setUsername(mUbidotsUsername);//"BBFF-tEq4lGAegEyP1H4EaYckNQ7ZHdZYzI");
|
||||
mUbidotsChaletClient->setPassword("12");
|
||||
|
||||
connect(mUbidotsChaletClient,SIGNAL(stateChanged(ClientState)),this,SLOT(UbidotsStateChanged(ClientState)));
|
||||
|
||||
mUbidotsChaletClient->connectToHost();
|
||||
}
|
||||
|
||||
CChaletUbidotsInterface::~CChaletUbidotsInterface()
|
||||
{
|
||||
mUbidotsChaletClient->disconnectFromHost();
|
||||
|
||||
delete mUbidotsChaletClient;
|
||||
}
|
||||
|
||||
int CChaletUbidotsInterface::LogUbidotsChaletData(CChaletMainStatus *Data)
|
||||
{
|
||||
Q_UNUSED(Data)
|
||||
|
||||
|
||||
qDebug("LogUbidotsChaletData() should only be called from derived class...");
|
||||
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
void CChaletUbidotsInterface::UbidotsStateChanged(QMqttClient::ClientState state)
|
||||
{
|
||||
qDebug("MQTT client %s is now in state %d",qPrintable(mInterfaceOwnerName),state);
|
||||
//MQTTStateChanged(state);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//////////////////////implementation
|
||||
CChaletJFUbidotsInterface::CChaletJFUbidotsInterface(QString Username) : CChaletUbidotsInterface(Username)
|
||||
{
|
||||
mInterfaceOwnerName = "J-F";
|
||||
//mUbidotsChaletClient->subscribe(QMqttTopicFilter("/v1.6/devices/ChaletDuino"))
|
||||
|
||||
//connect(mInverterBtnSubscritption,SIGNAL(messageReceived(QMqttMessage)),this,SLOT(InverterBtnSubscriptionMsgReceived(QMqttMessage)));
|
||||
|
||||
|
||||
qDebug("JF Ubidots interface created");
|
||||
}
|
||||
|
||||
int CChaletJFUbidotsInterface::LogUbidotsChaletData(CChaletMainStatus *Data)
|
||||
{
|
||||
QString MQTTMsg = QString("{\"BattVoltage\": %1}").arg(Data->mBatteryVoltage);
|
||||
mUbidotsChaletClient->publish(QMqttTopicName("/v1.6/devices/ChaletDuino"),MQTTMsg.toUtf8());
|
||||
MQTTMsg.clear();
|
||||
MQTTMsg = QString("{\"InverterSwitch\": %1}").arg(Data->mWiFiModuleStatus !=0);
|
||||
mUbidotsChaletClient->publish(QMqttTopicName("/v1.6/devices/ChaletDuino"),MQTTMsg.toUtf8(),0,true);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
void CChaletJFUbidotsInterface::InverterBtnSubscriptionMsgReceived(QMqttMessage msg)
|
||||
{
|
||||
qDebug("subscription msg. Topic name: %s",qPrintable(msg.topic().name()));
|
||||
}
|
||||
|
||||
void CChaletJFUbidotsInterface::WiFiBtnSubscriptionMsgReceived(QMqttMessage msg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CChaletJFUbidotsInterface::MQTTStateChanged(QMqttClient::ClientState)
|
||||
{
|
||||
|
||||
}
|
||||
48
Sources/Chalet/ChaletUbidotsInterface.h
Normal file
48
Sources/Chalet/ChaletUbidotsInterface.h
Normal file
@ -0,0 +1,48 @@
|
||||
#ifndef CHALETUBIDOTSINTERFACE_H
|
||||
#define CHALETUBIDOTSINTERFACE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QtMqtt/QtMqtt>
|
||||
#include <QMqttClient>
|
||||
#include "ChaletData.h"
|
||||
#include <QString>
|
||||
|
||||
#define UBIDOTS_URL "things.ubidots.com"
|
||||
#define UBIDOTS_PORT 1883
|
||||
|
||||
class CChaletUbidotsInterface : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CChaletUbidotsInterface(QString UbidotsUsername, QObject *parent = 0);
|
||||
~CChaletUbidotsInterface();
|
||||
virtual int LogUbidotsChaletData(CChaletMainStatus *Data);
|
||||
virtual void MQTTStateChanged(QMqttClient::ClientState)=0;
|
||||
|
||||
QMqttClient *mUbidotsChaletClient;
|
||||
QString mUbidotsUsername;
|
||||
QString mInterfaceOwnerName;
|
||||
|
||||
|
||||
|
||||
public slots:
|
||||
void UbidotsStateChanged(QMqttClient::ClientState);
|
||||
};
|
||||
|
||||
class CChaletJFUbidotsInterface: public CChaletUbidotsInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CChaletJFUbidotsInterface(QString Username);
|
||||
virtual int LogUbidotsChaletData(CChaletMainStatus *Data);
|
||||
void MQTTStateChanged(QMqttClient::ClientState);
|
||||
|
||||
QMqttSubscription *mInverterBtnSubscritption, *mWiFiBtnSubscription;
|
||||
|
||||
public slots:
|
||||
void InverterBtnSubscriptionMsgReceived(QMqttMessage);
|
||||
void WiFiBtnSubscriptionMsgReceived(QMqttMessage);
|
||||
|
||||
|
||||
};
|
||||
#endif // CHALETUBIDOTSINTERFACE_H
|
||||
285
Sources/Chalet/ThingsBoardInterface.cpp
Normal file
285
Sources/Chalet/ThingsBoardInterface.cpp
Normal file
@ -0,0 +1,285 @@
|
||||
#include "ThingsBoardInterface.h"
|
||||
#include <QNetworkReply>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include "ChaletLoraDevice.h"
|
||||
|
||||
|
||||
CThingsBoardInterface::CThingsBoardInterface()
|
||||
{
|
||||
mThingsBoardSocket = new QNetworkAccessManager;
|
||||
mThingsBoardRPCSocket = new QNetworkAccessManager;
|
||||
|
||||
|
||||
connect(mThingsBoardSocket,SIGNAL(finished(QNetworkReply*)),this,SLOT(ThingsBoardServerFinished(QNetworkReply*)));
|
||||
connect(mThingsBoardSocket,SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),this,SLOT(sslErrors(QNetworkReply*,QList<QSslError>)));
|
||||
|
||||
connect(mThingsBoardRPCSocket,SIGNAL(finished(QNetworkReply*)),this,SLOT(ThingsBoardRPCFinished(QNetworkReply*)));
|
||||
connect(mThingsBoardRPCSocket,SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)),this,SLOT(sslErrors(QNetworkReply*,QList<QSslError>)));
|
||||
}
|
||||
|
||||
CThingsBoardInterface::~CThingsBoardInterface()
|
||||
{
|
||||
mThingsBoardRPCReply->deleteLater();
|
||||
delete mThingsBoardRPCSocket;
|
||||
delete mThingsBoardSocket;
|
||||
|
||||
}
|
||||
|
||||
int CThingsBoardInterface::RegisterThingsboardRPC()
|
||||
{
|
||||
|
||||
QNetworkRequest Req;
|
||||
Req.setUrl(QUrl("http://192.168.50.100:8085/api/v1/aQIocLkJM2ECSqVT2VRx/rpc"));
|
||||
|
||||
mThingsBoardRPCReply = mThingsBoardRPCSocket->get(Req);
|
||||
// connect(mThingsBoardRPCReply,SIGNAL(readyRead()),this,SLOT(RPCData()));
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void CThingsBoardInterface::UpdateChaletVoltage(float Voltage)
|
||||
{
|
||||
// "{\"temperature\": 25}" http://localhost:8080/api/v1/$ACCESS_TOKEN/telemetry --header "Content-Type:application/json"
|
||||
//{"doubleKey":42.0}
|
||||
|
||||
QByteArray JsonByteArray = "{\"Bat_Voltage\":";
|
||||
JsonByteArray.append((QString("%1}").arg(Voltage)).toUtf8().data());
|
||||
|
||||
QNetworkRequest Req;
|
||||
Req.setHeader(QNetworkRequest::ContentTypeHeader,"application/json");
|
||||
Req.setUrl(QUrl("http://192.168.50.100:8085/api/v1/aQIocLkJM2ECSqVT2VRx/telemetry"));
|
||||
|
||||
mThingsBoardSocket->post(Req,JsonByteArray);
|
||||
|
||||
}
|
||||
|
||||
void CThingsBoardInterface::UpdateChaletData(quint8 mInverterRelayStatus, quint8 mWiFiModuleStatus, qint8 mCurrentSensorStatus, float mBatteryVoltage, qint16 mBatteryCurrent, qint16 mBatterySOC, qint8 LoraState)
|
||||
{
|
||||
//{"key1":"value1", "key2":"value2"}
|
||||
|
||||
QByteArray JsonByteArray = "{\"Bat_Voltage\":";
|
||||
JsonByteArray.append((QString("%1, ").arg(mBatteryVoltage)).toUtf8().data());
|
||||
|
||||
JsonByteArray.append("\"Bat_SOC\":");
|
||||
JsonByteArray.append((QString("%1, ").arg(mBatterySOC)).toUtf8().data());
|
||||
|
||||
JsonByteArray.append("\"WiFi_State\":");
|
||||
JsonByteArray.append((QString("%1, ").arg(mWiFiModuleStatus)).toUtf8().data());
|
||||
|
||||
JsonByteArray.append("\"CurrentSensor_State\":");
|
||||
JsonByteArray.append((QString("%1, ").arg(mCurrentSensorStatus)).toUtf8().data());
|
||||
|
||||
JsonByteArray.append("\"Bat_Current\":");
|
||||
JsonByteArray.append((QString("%1, ").arg(mBatteryCurrent)).toUtf8().data());
|
||||
|
||||
JsonByteArray.append("\"LoRa_State\":");
|
||||
JsonByteArray.append((QString("%1, ").arg(LoraState)).toUtf8().data());
|
||||
|
||||
JsonByteArray.append("\"Inverter_State\":");
|
||||
JsonByteArray.append((QString("%1}").arg(mInverterRelayStatus)).toUtf8().data());
|
||||
|
||||
QNetworkRequest Req;
|
||||
Req.setHeader(QNetworkRequest::ContentTypeHeader,"application/json");
|
||||
Req.setUrl(QUrl("http://192.168.50.100:8085/api/v1/aQIocLkJM2ECSqVT2VRx/telemetry"));
|
||||
|
||||
mThingsBoardSocket->post(Req,JsonByteArray);
|
||||
|
||||
// if(mThingsBoardRPCReply->isRunning() == true)
|
||||
// {
|
||||
// qDebug("RPC socket running...");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// qDebug("RPC socket not runnging");
|
||||
// }
|
||||
}
|
||||
|
||||
void CThingsBoardInterface::ThingsBoardServerFinished(QNetworkReply *NetworkReply)
|
||||
{
|
||||
if(NetworkReply->isFinished() == false)
|
||||
return;
|
||||
|
||||
if(NetworkReply->error() != QNetworkReply::NoError)
|
||||
{
|
||||
qDebug("Network error... %d", NetworkReply->error());
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
QByteArray Reply = NetworkReply->readAll();
|
||||
if(Reply.isEmpty())
|
||||
return;
|
||||
|
||||
NetworkReply->deleteLater();
|
||||
|
||||
QString ReplyString(Reply);
|
||||
qDebug("ThingsBoard Server Reply: %s",ReplyString.toUtf8().data());
|
||||
ReplyString.remove("[\"");
|
||||
ReplyString.remove("\"]");
|
||||
QJsonValue Result(ReplyString);
|
||||
// QJsonParseError error;
|
||||
// QJsonDocument JsonReply = QJsonDocument::fromJson(Reply,&error);
|
||||
// QJsonObject JsonObject = JsonReply.object();
|
||||
// QStringList Keys = JsonObject.keys();
|
||||
|
||||
// int toto = ReplyString.toInt();
|
||||
// qDebug("Switch = %d",toto);
|
||||
}
|
||||
|
||||
void CThingsBoardInterface::sslErrors(QNetworkReply *ServerReply, QList<QSslError> ErrorList)
|
||||
{
|
||||
|
||||
qDebug("Ssl errors...");
|
||||
ServerReply->ignoreSslErrors();
|
||||
}
|
||||
|
||||
|
||||
void CThingsBoardInterface::ThingsBoardRPCFinished(QNetworkReply *NetworkReply)
|
||||
{
|
||||
if(mThingsBoardRPCReply->error() != QNetworkReply::NoError)
|
||||
{
|
||||
qDebug("Network error (ThingsBoardRPC)... %d", mThingsBoardRPCReply->error());
|
||||
RegisterThingsboardRPC();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
QByteArray Reply = mThingsBoardRPCReply->readAll();
|
||||
if(Reply.isEmpty())
|
||||
{
|
||||
qDebug("Received an empty RPC reply in ThiungsBoard...");
|
||||
RegisterThingsboardRPC();
|
||||
return;
|
||||
}
|
||||
|
||||
mThingsBoardRPCReply->deleteLater();
|
||||
|
||||
QString ReplyString(Reply);
|
||||
qDebug("ThingsBoard RPC Reply: %s",ReplyString.toUtf8().data());
|
||||
QJsonDocument JSonReply = QJsonDocument::fromJson(Reply);
|
||||
|
||||
QJsonObject RPCCmd = JSonReply.object();
|
||||
|
||||
QJsonValue RequestedCmd = RPCCmd.value("method");
|
||||
{
|
||||
if(RequestedCmd.toString().contains("setChaletInverterState"))
|
||||
{
|
||||
//Fetch the required state.
|
||||
bool RequestedState = RPCCmd.value("params").toBool();
|
||||
if(RequestedState == true)
|
||||
{
|
||||
qDebug("Server Inverter TURN ON request received.");
|
||||
mChaletLoraDevice->SendInverterPowerRelayState(true);
|
||||
}
|
||||
if(RequestedState == false)
|
||||
{
|
||||
qDebug("Server Inverter TURN OFF request received.");
|
||||
mChaletLoraDevice->SendInverterPowerRelayState(false);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if(RequestedCmd.toString().contains("setWiFiState"))
|
||||
{
|
||||
//Fetch the required state.
|
||||
QString RequestedState = RPCCmd.value("params").toString();
|
||||
if(RequestedState == "true")
|
||||
{
|
||||
qDebug("Server WiFi TURN ON request received.");
|
||||
}
|
||||
if(RequestedState == "false")
|
||||
{
|
||||
qDebug("Server WiFi TURN OFF request received.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug("Received an unknown RPC call from ThingsBoard server");
|
||||
}
|
||||
}
|
||||
|
||||
//Re-register for next request..
|
||||
RegisterThingsboardRPC();
|
||||
}
|
||||
|
||||
void CThingsBoardInterface::RPCsslErrors(QNetworkReply *ServerReply, QList<QSslError> ErrorList)
|
||||
{
|
||||
|
||||
qDebug("Ssl errors...");
|
||||
ServerReply->ignoreSslErrors();
|
||||
}
|
||||
|
||||
void CThingsBoardInterface::RPCData()
|
||||
{
|
||||
// if(mThingsBoardRPCReply->isFinished() == false)
|
||||
// return;
|
||||
|
||||
// if(mThingsBoardRPCReply->error() != QNetworkReply::NoError)
|
||||
// {
|
||||
// qDebug("Network error (RPCData)... %d", mThingsBoardRPCReply->error());
|
||||
// RegisterThingsboardRPC();
|
||||
// return;
|
||||
// }
|
||||
|
||||
|
||||
// QByteArray Reply = mThingsBoardRPCReply->readAll();
|
||||
// if(Reply.isEmpty())
|
||||
// {
|
||||
// qDebug("Received an empty RPC reply in ThiungsBoard...");
|
||||
// RegisterThingsboardRPC();
|
||||
// return;
|
||||
// }
|
||||
|
||||
// mThingsBoardRPCReply->deleteLater();
|
||||
|
||||
// QString ReplyString(Reply);
|
||||
// qDebug("ThingsBoard RPC Reply: %s",ReplyString.toUtf8().data());
|
||||
// QJsonDocument JSonReply = QJsonDocument::fromJson(Reply);
|
||||
|
||||
// QJsonObject RPCCmd = JSonReply.object();
|
||||
|
||||
// QJsonValue RequestedCmd = RPCCmd.value("method");
|
||||
// {
|
||||
// if(RequestedCmd.toString().contains("setChaletInverterState"))
|
||||
// {
|
||||
// //Fetch the required state.
|
||||
// bool RequestedState = RPCCmd.value("params").toBool();
|
||||
// if(RequestedState == true)
|
||||
// {
|
||||
// qDebug("Server Inverter TURN ON request received.");
|
||||
// //mChaletLoraDevice->SendInverterPowerRelayState(true);
|
||||
// }
|
||||
// if(RequestedState == false)
|
||||
// {
|
||||
// qDebug("Server Inverter TURN OFF request received.");
|
||||
// // mChaletLoraDevice->SendInverterPowerRelayState(false);
|
||||
// }
|
||||
|
||||
|
||||
// }
|
||||
// else if(RequestedCmd.toString().contains("setWiFiState"))
|
||||
// {
|
||||
// //Fetch the required state.
|
||||
// QString RequestedState = RPCCmd.value("params").toString();
|
||||
// if(RequestedState == "true")
|
||||
// {
|
||||
// qDebug("Server WiFi TURN ON request received.");
|
||||
// }
|
||||
// if(RequestedState == "false")
|
||||
// {
|
||||
// qDebug("Server WiFi TURN OFF request received.");
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// qDebug("Received an unknown RPC call from ThingsBoard server");
|
||||
// }
|
||||
// }
|
||||
|
||||
// //Re-register for next request..
|
||||
// RegisterThingsboardRPC();
|
||||
|
||||
|
||||
}
|
||||
36
Sources/Chalet/ThingsBoardInterface.h
Normal file
36
Sources/Chalet/ThingsBoardInterface.h
Normal file
@ -0,0 +1,36 @@
|
||||
#ifndef THINGSBOARDINTERFACE_H
|
||||
#define THINGSBOARDINTERFACE_H
|
||||
|
||||
class CChaletLoraDevice;
|
||||
|
||||
#include <QObject>
|
||||
#include <QNetworkAccessManager>
|
||||
|
||||
class CThingsBoardInterface : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CThingsBoardInterface();
|
||||
~CThingsBoardInterface();
|
||||
|
||||
CChaletLoraDevice *mChaletLoraDevice;
|
||||
|
||||
int RegisterThingsboardRPC();
|
||||
void UpdateChaletVoltage(float Voltage);
|
||||
void UpdateChaletData(quint8 mInverterRelayStatus, quint8 mWiFiModuleStatus, qint8 mCurrentSensorStatus, float mBatteryVoltage, qint16 mBatteryCurrent, qint16 mBatterySOC, qint8 LoraState);
|
||||
|
||||
private:
|
||||
QNetworkAccessManager *mThingsBoardSocket, *mThingsBoardRPCSocket;
|
||||
QNetworkReply *mThingsBoardRPCReply;
|
||||
|
||||
public slots:
|
||||
void ThingsBoardServerFinished(QNetworkReply*);
|
||||
void sslErrors(QNetworkReply*,QList<QSslError>);
|
||||
|
||||
void ThingsBoardRPCFinished(QNetworkReply*);
|
||||
void RPCsslErrors(QNetworkReply*,QList<QSslError>);
|
||||
|
||||
void RPCData();
|
||||
};
|
||||
|
||||
#endif // THINGSBOARDINTERFACE_H
|
||||
@ -17,7 +17,7 @@ CEthernetNetworkCommIF::~CEthernetNetworkCommIF()
|
||||
}
|
||||
|
||||
|
||||
int CEthernetNetworkCommIF::SendNetworkMessage(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray Data)
|
||||
int CEthernetNetworkCommIF::SendNetworkMessage(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray *Data)
|
||||
{
|
||||
// Q_UNUSED(DeviceID)
|
||||
// Q_UNUSED(DeviceAddress)
|
||||
@ -25,7 +25,15 @@ int CEthernetNetworkCommIF::SendNetworkMessage(int DeviceID, int DeviceAddress,
|
||||
// Q_UNUSED(DataSize)
|
||||
// Q_UNUSED(Data)
|
||||
|
||||
QByteArray Packet = GetTxPacket(MessageID,0,Data.data(),DataSize,DeviceAddress,DeviceID);
|
||||
QByteArray Packet;
|
||||
if(Data != 0)
|
||||
{
|
||||
Packet = GetTxPacket(MessageID,0,Data->data(),DataSize,DeviceAddress,DeviceID);
|
||||
}
|
||||
else
|
||||
{
|
||||
Packet = GetTxPacket(MessageID,0,0,0,DeviceAddress,DeviceID);
|
||||
}
|
||||
mTCPSocket->write(Packet);
|
||||
|
||||
return RET_OK;
|
||||
|
||||
@ -21,7 +21,7 @@ public:
|
||||
QTcpSocket* mTCPSocket;
|
||||
|
||||
//CNetworkCommIF implementation
|
||||
virtual int SendNetworkMessage(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray Data);
|
||||
virtual int SendNetworkMessage(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray *Data);
|
||||
|
||||
//CNetworkProtocol implementation
|
||||
virtual int NewFrameReceived(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray Data);
|
||||
|
||||
@ -1,5 +1,25 @@
|
||||
#include "HttpServer.h"
|
||||
|
||||
|
||||
CHttpServer::CHttpServer()
|
||||
{
|
||||
mHttpServer = new QHttpServer;
|
||||
mHttpServer->route("/", []()
|
||||
{
|
||||
qDebug("Test");
|
||||
|
||||
return "Ja Mon CB!!!!";
|
||||
});
|
||||
|
||||
|
||||
const auto port = mHttpServer->listen(QHostAddress::Any,8080);
|
||||
|
||||
qDebug("Server Opened");
|
||||
|
||||
|
||||
}
|
||||
|
||||
CHttpServer::~CHttpServer()
|
||||
{
|
||||
delete mHttpServer;
|
||||
}
|
||||
|
||||
@ -1,11 +1,16 @@
|
||||
#ifndef HTTPSERVER_H
|
||||
#define HTTPSERVER_H
|
||||
|
||||
#include <QtHttpServer/QHttpServer>
|
||||
|
||||
class CHttpServer
|
||||
{
|
||||
public:
|
||||
|
||||
QHttpServer *mHttpServer;
|
||||
|
||||
CHttpServer();
|
||||
~CHttpServer();
|
||||
};
|
||||
|
||||
#endif // HTTPSERVER_H
|
||||
#endif // HTTPSERVER_H
|
||||
|
||||
@ -104,9 +104,9 @@ int CLoraNetworkCommIF::NewFrameReceived(int DeviceID, int DeviceAddress, int Me
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int CLoraNetworkCommIF::SendNetworkMessage(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray Data)
|
||||
int CLoraNetworkCommIF::SendNetworkMessage(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray *Data)
|
||||
{
|
||||
QByteArray Packet = GetTxPacket(MessageID,0,Data.data(),DataSize,DeviceAddress,DeviceID);
|
||||
QByteArray Packet = GetTxPacket(MessageID,0,Data->data(),DataSize,DeviceAddress,DeviceID);
|
||||
SendLoraFrame(6,4,Packet);
|
||||
// SendLoraFrame(4,4,Packet);
|
||||
return RET_OK;
|
||||
|
||||
@ -31,7 +31,7 @@ public:
|
||||
int NewFrameReceived(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray Data);
|
||||
|
||||
//NetworkCommIF implementation
|
||||
virtual int SendNetworkMessage(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray Data);
|
||||
virtual int SendNetworkMessage(int DeviceID, int DeviceAddress, int MessageID, int DataSize, QByteArray *Data);
|
||||
|
||||
private:
|
||||
QByteArray GetLoraFrame(unsigned short DestAddress,unsigned char DestChannel,QByteArray Payload);
|
||||
|
||||
@ -92,6 +92,7 @@ void CMasterCtrl::Start()
|
||||
mAVReceiverDevice->Start();
|
||||
|
||||
mChaletLoraNetworkCommInterface->SetLoraSerialPortSettings("COM3",QSerialPort::Baud9600);
|
||||
// mChaletLoraNetworkCommInterface->SetLoraSerialPortSettings("COM5",QSerialPort::Baud9600);
|
||||
mChaletLoraDevice->Start();
|
||||
|
||||
|
||||
|
||||
756
Sources/Modbus/ModbusBackend.cpp
Normal file
756
Sources/Modbus/ModbusBackend.cpp
Normal file
@ -0,0 +1,756 @@
|
||||
/*******************************************************************************
|
||||
* *
|
||||
* Société de Transports de Montréal. *
|
||||
* 2012 - 2013 *
|
||||
* *
|
||||
* Projet Zones Tests *
|
||||
* *
|
||||
* *
|
||||
* *
|
||||
*******************************************************************************/
|
||||
/*
|
||||
Description:
|
||||
Classe qui implémente le protocole Modbus.
|
||||
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Revision:
|
||||
### YYYMMDD JFM
|
||||
Verision d'origine.
|
||||
|
||||
### YYYYMMDD Description du besoin ou du bug
|
||||
Description du changement.
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
|
||||
|
||||
#include "ModbusBackend.h"
|
||||
#include "QBuffer"
|
||||
#include <QDataStream>
|
||||
//#include "EngLog.h"
|
||||
//#include "ZTLog.h"
|
||||
|
||||
CModbusBackend::CModbusBackend(CModbusRepository *Repo)
|
||||
{
|
||||
mModbusTCPSocketHandle = 0;
|
||||
mDataLinkValid = false;
|
||||
mModbusRepo = Repo;
|
||||
mModbusMode = MODBUS_INVALID_MODE;
|
||||
mTransactionIDCounter = 0;
|
||||
mDeviceID = 9;//0xFF;
|
||||
|
||||
mModbusMaxRetry = MODBUS_RETRY_MAX_COUNT;
|
||||
mModbusRequestTimeout = MODBUS_RETRY_DELAY;
|
||||
}
|
||||
|
||||
CModbusBackend::~CModbusBackend()
|
||||
{
|
||||
for(int i= 0; i < mRequestsList.size(); i++)
|
||||
{
|
||||
delete mRequestsList[i];
|
||||
}
|
||||
mRequestsList.clear();
|
||||
}
|
||||
|
||||
void CModbusBackend::ModbusDataReady()
|
||||
{
|
||||
|
||||
CModbusTransaction Transaction;
|
||||
QByteArray InData = mModbusTCPSocketHandle->readAll();
|
||||
|
||||
QBuffer FileBuffer(&InData);
|
||||
FileBuffer.open(QIODevice::ReadOnly);
|
||||
FileBuffer.seek(0);
|
||||
QDataStream *TransactionDataStrm = new QDataStream(&FileBuffer);
|
||||
*TransactionDataStrm >> Transaction.mHeader;
|
||||
*TransactionDataStrm >> Transaction.mPDU.mFunctionCode;
|
||||
Transaction.mPDU.mData = InData.right(Transaction.mHeader.mMessageLength - 2); //-2 to remove Device ID and Function Code.
|
||||
//
|
||||
|
||||
// qDebug("---------------------------------------");
|
||||
// qDebug("modbus data received %s",InData.toHex().data());
|
||||
// qDebug("Transaction ID 0x%X",Transaction.mHeader.mTransactionID);
|
||||
// qDebug("Message Length %d",Transaction.mHeader.mMessageLength);
|
||||
// qDebug("Protocol ID 0x%X",Transaction.mHeader.mProtocolID);
|
||||
// qDebug("Unit ID 0x%X",Transaction.mHeader.mUnitID);
|
||||
// qDebug("Function Code 0x%X",Transaction.mPDU.mFunctionCode);
|
||||
// qDebug("Data %s",Transaction.mPDU.mData.toHex().data());
|
||||
// qDebug("---------------------------------------");
|
||||
|
||||
if(mModbusMode == MODBUS_MASTER_MODE)
|
||||
{
|
||||
AnalyzeModbusResponse(Transaction); //Le maître recoit des réponses
|
||||
}
|
||||
else if( mModbusMode == MODBUS_SLAVE_MODE)
|
||||
{
|
||||
AnalyzeModbusRequest(Transaction); //L'esclave recoit des requêtes
|
||||
}
|
||||
else
|
||||
{
|
||||
// CEngLog::instance()->AddLogString("Erreur Modbus: <Illegal modbus backend mode...>"); //Erreur de logique interne. Ne doit pas survenir normalement
|
||||
}
|
||||
|
||||
delete TransactionDataStrm;
|
||||
}
|
||||
|
||||
void CModbusBackend::ModbusLinkDisconnected()
|
||||
{
|
||||
// qDebug("Modbus link disconnected");
|
||||
mDataLinkValid = false;
|
||||
mModbusTCPSocketHandle->flush();
|
||||
}
|
||||
|
||||
|
||||
//In client mode. This is the request from the master.
|
||||
int CModbusBackend::AnalyzeModbusRequest(CModbusTransaction Transaction)
|
||||
{
|
||||
if(Transaction.mHeader.mProtocolID != 0)
|
||||
{
|
||||
//Invalid protocol... what can we do?
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(Transaction.mPDU.mFunctionCode)
|
||||
{
|
||||
case MODBUS_FCT_READ_HOLDING_REGISTERS:
|
||||
{
|
||||
bool ok = true;
|
||||
unsigned short StartAdress = 0;
|
||||
StartAdress = Transaction.mPDU.mData[0]&0xFF;
|
||||
StartAdress <<= 8;
|
||||
StartAdress += Transaction.mPDU.mData[1]&0xFF;
|
||||
unsigned short NbRegisters = 0;
|
||||
NbRegisters = Transaction.mPDU.mData[2]&0xFF;
|
||||
NbRegisters <<= 8;
|
||||
NbRegisters += Transaction.mPDU.mData[3]&0xFF;
|
||||
|
||||
//Validate nb of registers
|
||||
if(NbRegisters < 1 || NbRegisters > MODBUS_MAX_NB_REGISTERS)
|
||||
{
|
||||
SendErrorResponse(Transaction,MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE);
|
||||
ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,MODBUS_FCT_READ_HOLDING_REGISTERS); //Fonction à être implémentée par le parent
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Validate data range
|
||||
if(!mModbusRepo->IsHRValid(StartAdress,NbRegisters))
|
||||
{
|
||||
qDebug("Reg invalid");
|
||||
//Send negative response
|
||||
SendErrorResponse(Transaction,MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS);
|
||||
ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,MODBUS_FCT_READ_HOLDING_REGISTERS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
QByteArray data = mModbusRepo->GetHRData(StartAdress,NbRegisters,&ok);
|
||||
|
||||
// qDebug("Slave Rx Read Holding Registers. Address: %d, Nb Reg: %d",StartAdress, NbRegisters);
|
||||
// qDebug("Data: %s",data.toHex().data());
|
||||
|
||||
//The response to a HR reading needs the byte count before the data.
|
||||
quint8 ByteCount = data.size();
|
||||
data.prepend(ByteCount);
|
||||
SendModbusResponse(Transaction, data);
|
||||
|
||||
//All OK
|
||||
|
||||
break;
|
||||
}
|
||||
case MODBUS_WRITE_SINGLE_REGISTER:
|
||||
{
|
||||
unsigned short StartAdress = 0;
|
||||
|
||||
StartAdress = Transaction.mPDU.mData[0]&0xFF;
|
||||
StartAdress <<= 8;
|
||||
StartAdress += Transaction.mPDU.mData[1]&0xFF;
|
||||
|
||||
//Validate data range
|
||||
if(!mModbusRepo->IsHRValid(StartAdress,1))
|
||||
{
|
||||
qDebug("Reg invalid");
|
||||
//Send negative response
|
||||
SendErrorResponse(Transaction,MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS);
|
||||
ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,MODBUS_WRITE_SINGLE_REGISTER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Extract data.
|
||||
QByteArray data = Transaction.mPDU.mData.right(2);
|
||||
|
||||
//Write register data
|
||||
mModbusRepo->WriteHRData(StartAdress,1,data);
|
||||
// if(StartAdress == 2000)
|
||||
// {
|
||||
// qDebug("debug... 2000");
|
||||
// }
|
||||
|
||||
// qDebug("Slave Rx Write Single Register. Address: %d, Value: 0x%s",StartAdress, data.toHex().data());
|
||||
// qDebug("Data: %s",data.toHex().data());
|
||||
|
||||
data = Transaction.mPDU.mData.left(4); //The response corresponds to the Reg. Address & the value. Which is the first 4 bytes of the initial request.
|
||||
SendModbusResponse(Transaction, data);
|
||||
RegistersDatabaseUpdated(StartAdress,1);
|
||||
|
||||
break;
|
||||
}
|
||||
case MODBUS_FCT_WRITE_MULTIPLE_REGISTERS:
|
||||
{
|
||||
unsigned short StartAdress = 0;
|
||||
StartAdress = Transaction.mPDU.mData[0]&0xFF;
|
||||
StartAdress <<= 8;
|
||||
StartAdress += Transaction.mPDU.mData[1]&0xFF;
|
||||
|
||||
unsigned short NbRegisters = 0;
|
||||
NbRegisters = Transaction.mPDU.mData[2]&0xFF;
|
||||
NbRegisters <<= 8;
|
||||
NbRegisters += Transaction.mPDU.mData[3]&0xFF;
|
||||
|
||||
quint8 ByteCount = Transaction.mPDU.mData[4];
|
||||
|
||||
//Validate nb of registers
|
||||
if(NbRegisters < 1 || NbRegisters > 0x7D || ByteCount != (NbRegisters*2))
|
||||
{
|
||||
qDebug("Invalid register number or byte count ");
|
||||
SendErrorResponse(Transaction,MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE);
|
||||
ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,MODBUS_FCT_WRITE_MULTIPLE_REGISTERS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Validate data range
|
||||
if(!mModbusRepo->IsHRValid(StartAdress,NbRegisters))
|
||||
{
|
||||
qDebug("Reg invalid");
|
||||
//Send negative response
|
||||
SendErrorResponse(Transaction,MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS);
|
||||
ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS,MODBUS_FCT_WRITE_MULTIPLE_REGISTERS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Extract data.
|
||||
QByteArray data = Transaction.mPDU.mData.right(ByteCount);
|
||||
|
||||
//Write register data
|
||||
mModbusRepo->WriteHRData(StartAdress,NbRegisters,data);
|
||||
|
||||
// qDebug("\nSlave Rx Write Multiple Registers. Address: %d, Nb Reg: %d",StartAdress, NbRegisters);
|
||||
// qDebug("Data: %s\n",data.toHex().data());
|
||||
|
||||
data = Transaction.mPDU.mData.left(4); //The response corresponds to the Start Adress and Nb of Regs. Which is the first 4 bytes of the initial request.
|
||||
SendModbusResponse(Transaction, data);
|
||||
|
||||
RegistersDatabaseUpdated(StartAdress,NbRegisters);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
//Received "Illegal function code". Send the exception code to master
|
||||
//TODO: Log this.
|
||||
qDebug("Slave received illegal function code from master: 0x%x",Transaction.mPDU.mFunctionCode);
|
||||
SendErrorResponse(Transaction,MODBUS_EXCEPTION_ILLEGAL_FCT);
|
||||
ModbusRequestException(MODBUS_EXCEPTION_ILLEGAL_FCT,Transaction.mPDU.mFunctionCode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CModbusBackend::SendModbusResponse(CModbusTransaction RequestTransaction, QByteArray Data)
|
||||
{
|
||||
QByteArray ModbusPacket;
|
||||
|
||||
QBuffer Buffer(&ModbusPacket);
|
||||
Buffer.open(QIODevice::WriteOnly|QIODevice::Unbuffered);
|
||||
Buffer.seek(0);
|
||||
QDataStream *PacketDataStrm = new QDataStream(&Buffer);
|
||||
|
||||
//For a response, the header will be the same as the original request, except for the msg. length.
|
||||
//Set the appropriate msg length.
|
||||
RequestTransaction.mHeader.mMessageLength = Data.size() + 2; //+2 to add function code & Unit ID.
|
||||
RequestTransaction.mPDU.mData = Data;
|
||||
|
||||
*PacketDataStrm << RequestTransaction.mHeader;
|
||||
*PacketDataStrm << RequestTransaction.mPDU.mFunctionCode;
|
||||
Buffer.close();
|
||||
ModbusPacket.append(Data);
|
||||
|
||||
|
||||
// qDebug("Response packet: %s",ModbusPacket.toHex().data());
|
||||
|
||||
mModbusTCPSocketHandle->write(ModbusPacket);
|
||||
|
||||
delete PacketDataStrm;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
//In Master mode. This is the response from slave to a previously sent request.
|
||||
int CModbusBackend::AnalyzeModbusResponse(CModbusTransaction Transaction)
|
||||
{
|
||||
if(Transaction.mHeader.mProtocolID != 0)
|
||||
{
|
||||
//Invalid protocol... what can we do?
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
//Find matching request and remove it from the queue...
|
||||
CModbusRequest *Request;
|
||||
bool Found = false;
|
||||
for(int i = 0; i < mRequestsList.size(); i++)
|
||||
{
|
||||
if(mRequestsList.at(i)->mHeader.mTransactionID == Transaction.mHeader.mTransactionID)
|
||||
{
|
||||
Request = mRequestsList.takeAt(i); //Remove from queue and keep a copy
|
||||
Request->mRequestTimer->stop(); //Stop the resend timer
|
||||
Found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(Found == false)
|
||||
{
|
||||
//Invalid request number. This should happen only if a very long delay exists in the comm.
|
||||
//TODO: Log this...
|
||||
qDebug("Master received response to a non existent request!!!");
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
//check if we have an exception response
|
||||
if((Transaction.mPDU.mFunctionCode & MODBUS_EXCEPTION_FCT_MASK) != 0)
|
||||
{
|
||||
//we have an exception response... something went wrong.
|
||||
quint8 ExceptionCode = Transaction.mPDU.mData[0];
|
||||
|
||||
//TODO: Manage this!
|
||||
qDebug("Master Rx exception code %d to request %d",ExceptionCode,Request->mPDU.mFunctionCode);
|
||||
emit ModbusResponseException(ExceptionCode,Request->mPDU.mFunctionCode);
|
||||
delete Request;
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
switch(Transaction.mPDU.mFunctionCode)
|
||||
{
|
||||
case MODBUS_FCT_READ_HOLDING_REGISTERS:
|
||||
{
|
||||
quint8 ByteCount = 0;
|
||||
ByteCount = Transaction.mPDU.mData.at(0);
|
||||
|
||||
if((Request->mNbRegisters*2) != ByteCount)
|
||||
{
|
||||
//Inconsistency between the data range and the data count.
|
||||
//TODO: Log the error.
|
||||
qDebug("Master eceived a wrong data size in response for a MODBUS_FCT_READ_HOLDING_REGISTERS request");
|
||||
emit ModbusResponseException(MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,MODBUS_FCT_READ_HOLDING_REGISTERS);
|
||||
delete Request;
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
QByteArray RegisterValues = Transaction.mPDU.mData.right(ByteCount);
|
||||
|
||||
|
||||
// qDebug("Master Rx Read Holding Registers Response.");
|
||||
// qDebug("Data: %s",RegisterValues.toHex().data());
|
||||
|
||||
mModbusRepo->WriteHRData(Request->mStartAddress,Request->mNbRegisters,RegisterValues);
|
||||
RegistersDatabaseUpdated(Request->mStartAddress, Request->mNbRegisters);
|
||||
|
||||
break;
|
||||
}
|
||||
case MODBUS_WRITE_SINGLE_REGISTER:
|
||||
{
|
||||
quint16 RegAddress = 0;
|
||||
RegAddress = Transaction.mPDU.mData[0]&0xFF;
|
||||
RegAddress <<= 8;
|
||||
RegAddress += Transaction.mPDU.mData[1]&0xFF;
|
||||
|
||||
if(Request->mStartAddress != RegAddress)
|
||||
{
|
||||
//Inconsistency between the request Adress and response Adress.
|
||||
//TODO: Log the error.
|
||||
qDebug("Master received a wrong Register Adress in response for a MODBUS_WRITE_SINGLE_REGISTER request");
|
||||
emit ModbusResponseException(MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,MODBUS_WRITE_SINGLE_REGISTER);
|
||||
delete Request;
|
||||
return RET_ERROR;
|
||||
}
|
||||
// qDebug("Master Rx Write Single Register response. Address: %d,",RegAddress);
|
||||
// qDebug("Data: %s",Transaction.mPDU.mData.toHex().data());
|
||||
|
||||
ModbusWriteSingleRegsSuccess();
|
||||
|
||||
//Everything seems good.
|
||||
|
||||
break;
|
||||
}
|
||||
case MODBUS_FCT_WRITE_MULTIPLE_REGISTERS:
|
||||
{
|
||||
unsigned short StartAdress = 0;
|
||||
StartAdress = Transaction.mPDU.mData[0]&0xFF;
|
||||
StartAdress <<= 8;
|
||||
StartAdress += Transaction.mPDU.mData[1]&0xFF;
|
||||
|
||||
unsigned short NbRegisters = 0;
|
||||
NbRegisters = Transaction.mPDU.mData[2]&0xFF;
|
||||
NbRegisters <<= 8;
|
||||
NbRegisters += Transaction.mPDU.mData[3]&0xFF;
|
||||
|
||||
if(StartAdress != Request->mStartAddress || NbRegisters != Request->mNbRegisters)
|
||||
{
|
||||
//Inconsistency between the request Adress or NbRegisters and response.
|
||||
//TODO: Log the error.
|
||||
qDebug("Master Received a wrong Register Adress or NbRegisters in response for a MODBUS_FCT_WRITE_MULTIPLE_REGISTERS request");
|
||||
emit ModbusResponseException(MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE,MODBUS_FCT_WRITE_MULTIPLE_REGISTERS);
|
||||
delete Request;
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
// qDebug("Master Rx Write Multiple Registers response. Address: %d, Nb Reg: %d",StartAdress, NbRegisters);
|
||||
// qDebug("Data: %s",Transaction.mPDU.mData.toHex().data());
|
||||
ModbusWriteMultipleRegsSuccess();
|
||||
|
||||
//All is good.
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
//Received "Illegal function code" response
|
||||
//TODO: Log this.
|
||||
//CEngLog::instance()->AddLogString(QString().sprintf("Modbus Maître, réception d'un code de fonction illégal: 0x%x",Transaction.mPDU.mFunctionCode));
|
||||
// qDebug("Master received illegal function code 0x%x",Transaction.mPDU.mFunctionCode);
|
||||
emit ModbusResponseException(MODBUS_EXCEPTION_ILLEGAL_FCT,MODBUS_FCT_WRITE_MULTIPLE_REGISTERS);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
delete Request;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CModbusBackend::SendModbusRequest(CModbusRequest *Request)
|
||||
{
|
||||
QByteArray ModbusPacket;
|
||||
|
||||
QBuffer Buffer(&ModbusPacket);
|
||||
Buffer.open(QIODevice::WriteOnly|QIODevice::Unbuffered);
|
||||
Buffer.seek(0);
|
||||
QDataStream *PacketDataStrm = new QDataStream(&Buffer);
|
||||
|
||||
*PacketDataStrm << Request->mHeader;
|
||||
*PacketDataStrm << Request->mPDU.mFunctionCode;
|
||||
Buffer.close();
|
||||
ModbusPacket.append(Request->mPDU.mData);
|
||||
|
||||
|
||||
// qDebug("Request packet: %s",ModbusPacket.toHex().data());
|
||||
|
||||
mModbusTCPSocketHandle->write(ModbusPacket);
|
||||
delete PacketDataStrm;
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int CModbusBackend::SendErrorResponse(CModbusTransaction RequestTransaction, quint8 ErrorCode)
|
||||
{
|
||||
QByteArray ModbusPacket;
|
||||
|
||||
QBuffer Buffer(&ModbusPacket);
|
||||
Buffer.open(QIODevice::WriteOnly|QIODevice::Unbuffered);
|
||||
Buffer.seek(0);
|
||||
QDataStream *PacketDataStrm = new QDataStream(&Buffer);
|
||||
|
||||
//For a response, the header will be the same as the original request, except for the msg. length.
|
||||
//Set the appropriate msg length.
|
||||
RequestTransaction.mHeader.mMessageLength = 3; //Unit ID, function code & Exception code.
|
||||
|
||||
*PacketDataStrm << RequestTransaction.mHeader;
|
||||
Buffer.close();
|
||||
ModbusPacket.append(RequestTransaction.mPDU.mFunctionCode + 0x80);
|
||||
ModbusPacket.append(ErrorCode);
|
||||
|
||||
|
||||
|
||||
//CEngLog::instance()->AddLogString(QString("Modbus: Envoi d'un code d'un code d'erreur. Error Code %1, Error Packet: %2").arg(ErrorCode).arg(ModbusPacket.toHex().data()));
|
||||
// qDebug("Sending error code %d. Error packet: %s",ErrorCode,ModbusPacket.toHex().data());
|
||||
|
||||
mModbusTCPSocketHandle->write(ModbusPacket);
|
||||
|
||||
delete PacketDataStrm;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
|
||||
int CModbusBackend::SendReadHoldingRegistersRequest(quint16 StartAddress, quint16 RegisterCount)
|
||||
{
|
||||
//First, validate that the reading range is within our repo
|
||||
if(mModbusRepo->IsHRValid(StartAddress,RegisterCount) == false)
|
||||
{
|
||||
//CEngLog::instance()->AddLogString("ModbusBackend: Tentative de lecture d'un registre hors de portée.");
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
//Create a request.
|
||||
CModbusRequest *NewRequest = new CModbusRequest;
|
||||
NewRequest->mStartAddress = StartAddress;
|
||||
NewRequest->mNbRegisters = RegisterCount;
|
||||
connect(NewRequest->mRequestTimer,SIGNAL(timeout()),this,SLOT(RequestTimerExpired()));
|
||||
|
||||
NewRequest->mPDU.mData.clear();
|
||||
NewRequest->mPDU.mFunctionCode = MODBUS_FCT_READ_HOLDING_REGISTERS;
|
||||
|
||||
quint8 HighByte, LowByte;
|
||||
LowByte = StartAddress & 0x00FF;
|
||||
HighByte = (StartAddress >> 8) & 0x00FF;
|
||||
NewRequest->mPDU.mData.append(HighByte);
|
||||
NewRequest->mPDU.mData.append(LowByte);
|
||||
|
||||
LowByte = RegisterCount & 0x00FF;
|
||||
HighByte = (RegisterCount >> 8) & 0x00FF;
|
||||
NewRequest->mPDU.mData.append(HighByte);
|
||||
NewRequest->mPDU.mData.append(LowByte);
|
||||
|
||||
NewRequest->mHeader.mMessageLength = NewRequest->mPDU.mData.size() + 2;
|
||||
NewRequest->mHeader.mProtocolID = 0;
|
||||
NewRequest->mHeader.mTransactionID = (qint16)GetNewTransactionID();
|
||||
NewRequest->mHeader.mUnitID = mDeviceID;
|
||||
|
||||
mRequestsList.append(NewRequest);
|
||||
|
||||
SendModbusRequest(NewRequest);
|
||||
|
||||
NewRequest->mRequestTimer->start(mModbusRequestTimeout);
|
||||
|
||||
|
||||
return RET_OK;
|
||||
|
||||
}
|
||||
|
||||
int CModbusBackend::SendWriteHoldingRegistersRequest(quint16 StartAddress, quint16 RegisterCount)
|
||||
{
|
||||
//First, validate that the reading range is within our repo
|
||||
if(mModbusRepo->IsHRValid(StartAddress,RegisterCount) == false)
|
||||
{
|
||||
//CEngLog::instance()->AddLogString("Trying to send a Write HR in an invalid range SendWriteHoldingRegistersRequest()");
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
if(RegisterCount > MODBUS_MAX_NB_REGISTERS)
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
//Get data.
|
||||
bool OK;
|
||||
QByteArray RegData = mModbusRepo->GetHRData(StartAddress,RegisterCount,&OK);
|
||||
if(OK == false)
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
//Create a request.
|
||||
CModbusRequest *NewRequest = new CModbusRequest;
|
||||
NewRequest->mStartAddress = StartAddress;
|
||||
NewRequest->mNbRegisters = RegisterCount;
|
||||
connect(NewRequest->mRequestTimer,SIGNAL(timeout()),this,SLOT(RequestTimerExpired()));
|
||||
|
||||
NewRequest->mPDU.mData.clear();
|
||||
NewRequest->mPDU.mFunctionCode = MODBUS_FCT_WRITE_MULTIPLE_REGISTERS;
|
||||
|
||||
//Start address
|
||||
quint8 HighByte, LowByte;
|
||||
LowByte = StartAddress & 0x00FF;
|
||||
HighByte = (StartAddress >> 8) & 0x00FF;
|
||||
NewRequest->mPDU.mData.append(HighByte);
|
||||
NewRequest->mPDU.mData.append(LowByte);
|
||||
|
||||
//Nb Registers
|
||||
LowByte = RegisterCount & 0x00FF;
|
||||
HighByte = (RegisterCount >> 8) & 0x00FF;
|
||||
NewRequest->mPDU.mData.append(HighByte);
|
||||
NewRequest->mPDU.mData.append(LowByte);
|
||||
|
||||
//Byte Count
|
||||
NewRequest->mPDU.mData.append(RegData.size());
|
||||
|
||||
NewRequest->mPDU.mData.append(RegData);
|
||||
|
||||
NewRequest->mHeader.mMessageLength = NewRequest->mPDU.mData.size() + 2;
|
||||
NewRequest->mHeader.mProtocolID = 0;
|
||||
NewRequest->mHeader.mTransactionID = (qint16)GetNewTransactionID();
|
||||
NewRequest->mHeader.mUnitID = mDeviceID;
|
||||
|
||||
mRequestsList.append(NewRequest);
|
||||
|
||||
SendModbusRequest(NewRequest);
|
||||
|
||||
NewRequest->mRequestTimer->start(mModbusRequestTimeout);
|
||||
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int CModbusBackend::SendWriteSingleRegisterRequest(quint16 Address)
|
||||
{
|
||||
//First, validate that the reading range is within our repo
|
||||
if(mModbusRepo->IsHRValid(Address,1) == false)
|
||||
{
|
||||
//CEngLog::instance()->AddLogString("Trying to send a Write HR in an invalid range SendWriteSingleRegisterRequest()");
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
//Get data.
|
||||
bool OK;
|
||||
QByteArray RegData = mModbusRepo->GetHRData(Address,1,&OK);
|
||||
if(OK == false)
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
//Create a request.
|
||||
CModbusRequest *NewRequest = new CModbusRequest;
|
||||
NewRequest->mStartAddress = Address;
|
||||
NewRequest->mNbRegisters = 1;
|
||||
connect(NewRequest->mRequestTimer,SIGNAL(timeout()),this,SLOT(RequestTimerExpired()));
|
||||
|
||||
NewRequest->mPDU.mData.clear();
|
||||
NewRequest->mPDU.mFunctionCode = MODBUS_WRITE_SINGLE_REGISTER;
|
||||
|
||||
quint8 HighByte, LowByte;
|
||||
LowByte = Address & 0x00FF;
|
||||
HighByte = (Address >> 8) & 0x00FF;
|
||||
NewRequest->mPDU.mData.append(HighByte);
|
||||
NewRequest->mPDU.mData.append(LowByte);
|
||||
|
||||
NewRequest->mPDU.mData.append(RegData);
|
||||
|
||||
NewRequest->mHeader.mMessageLength = NewRequest->mPDU.mData.size() + 2;
|
||||
NewRequest->mHeader.mProtocolID = 0;
|
||||
NewRequest->mHeader.mTransactionID = (qint16)GetNewTransactionID();
|
||||
NewRequest->mHeader.mUnitID = mDeviceID;
|
||||
|
||||
mRequestsList.append(NewRequest);
|
||||
|
||||
SendModbusRequest(NewRequest);
|
||||
|
||||
NewRequest->mRequestTimer->start(mModbusRequestTimeout);
|
||||
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
void CModbusBackend::RequestTimerExpired()
|
||||
{
|
||||
//find the expired request
|
||||
for(int i = 0; i < mRequestsList.size(); i++)
|
||||
{
|
||||
if(mRequestsList.at(i)->mRequestTimer->isActive() == false)
|
||||
{
|
||||
if(mRequestsList.at(i)->mRetries >= mModbusMaxRetry)
|
||||
{
|
||||
//The max number of retry has been reached. The device is probably offline.
|
||||
|
||||
// CZTLog::instance()->AddLogString("Modbus Maître: Nombre maximal de tentatives sans réponse atteint avec le partenaire",true);
|
||||
|
||||
|
||||
delete mRequestsList[i];
|
||||
mRequestsList.removeAt(i);
|
||||
ModbusRequestMaxRetryReached();
|
||||
|
||||
//TODO: Manage this situation (log?)
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
SendModbusRequest(mRequestsList[i]);
|
||||
mRequestsList.at(i)->mRequestTimer->start(mModbusRequestTimeout);
|
||||
mRequestsList[i]->mRetries++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
quint16 CModbusBackend::GetNewTransactionID()
|
||||
{
|
||||
quint16 ID = mTransactionIDCounter++;
|
||||
|
||||
if(mTransactionIDCounter == 0xFFFF - 10)
|
||||
{
|
||||
mTransactionIDCounter = 0;
|
||||
}
|
||||
|
||||
return ID;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CModbusRequest::CModbusRequest():
|
||||
mRetries(0)
|
||||
{
|
||||
mRequestTimer = new QTimer;
|
||||
mRequestTimer->setSingleShot(true);
|
||||
}
|
||||
CModbusRequest::~CModbusRequest()
|
||||
{
|
||||
delete mRequestTimer;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
QDataStream &operator<<(QDataStream &out, const CModbusHeader &source)
|
||||
{
|
||||
out << source.mTransactionID
|
||||
<< source.mProtocolID
|
||||
<< source.mMessageLength
|
||||
<< source.mUnitID
|
||||
;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
QDataStream &operator>>(QDataStream &in, CModbusHeader &dest)
|
||||
{
|
||||
in >> dest.mTransactionID
|
||||
>> dest.mProtocolID
|
||||
>> dest.mMessageLength
|
||||
>> dest.mUnitID
|
||||
;
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
//Virtual function that should not even get called...
|
||||
void CModbusBackend::ModbusResponseException(quint8 ExceptionCode, quint8 FctCode)
|
||||
{
|
||||
Q_UNUSED(ExceptionCode)
|
||||
Q_UNUSED(FctCode)
|
||||
//CEngLog::instance()->AddLogString("ModbusResponseException called from within slave object... weird stuff!");
|
||||
}
|
||||
|
||||
//Virtual function that should not even get called...
|
||||
void CModbusBackend::ModbusRequestException(quint8 ExceptionCode, quint8 FctCode)
|
||||
{
|
||||
Q_UNUSED(ExceptionCode)
|
||||
Q_UNUSED(FctCode)
|
||||
//CEngLog::instance()->AddLogString("ModbusResponseException called from within master object... weird stuff!");
|
||||
}
|
||||
|
||||
void CModbusBackend::ModbusWriteMultipleRegsSuccess()
|
||||
{
|
||||
qDebug("Weird! Default implementation of ModbusWriteMultipleRegsSuccess() called in CModbusBackend. This function should be reimplemented in the ModbusMaster child class");
|
||||
}
|
||||
|
||||
void CModbusBackend::ModbusWriteSingleRegsSuccess()
|
||||
{
|
||||
qDebug("Weird! Default implementation of ModbusWriteSingleRegsSuccess() called in CModbusBackend. This function should be reimplemented in the ModbusMaster child class");
|
||||
}
|
||||
|
||||
void CModbusBackend::ModbusRequestMaxRetryReached()
|
||||
{
|
||||
qDebug("Weird! Default implementation of ModbusRequestMaxRetryReached() called in CModbusBackend. This function should be reimplemented in the ModbusMaster child class");
|
||||
}
|
||||
203
Sources/Modbus/ModbusBackend.h
Normal file
203
Sources/Modbus/ModbusBackend.h
Normal file
@ -0,0 +1,203 @@
|
||||
/*******************************************************************************/
|
||||
/*
|
||||
Description:
|
||||
Classe qui implémente le protocole Modbus.
|
||||
Cette classe est héritée par la classe serveur (CModbusCCMgr) ou client (CModbusMaster).
|
||||
Elle sert à interpréter ou formatter des paquets Modbus provenant ou destinés au partenaire.
|
||||
Elle peut être héritée soit un parent qui implémente une instance maître ou client mais pas les deux à la fois.
|
||||
sur le réseau.
|
||||
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* Revision:
|
||||
### YYYMMDD JFM
|
||||
Verision d'origine.
|
||||
|
||||
### YYYYMMDD Description du besoin ou du bug
|
||||
Description du changement.
|
||||
*/
|
||||
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef CMODBUSBACKEND_H
|
||||
#define CMODBUSBACKEND_H
|
||||
#include <QObject>
|
||||
#include <QTcpSocket>
|
||||
#include "ModbusRepository.h"
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
#define MODBUS_EXCEPTION_FCT_MASK 0x80
|
||||
#define MODBUS_RETRY_DELAY 2000 //millisecs
|
||||
#define MODBUS_RETRY_MAX_COUNT 2 //resend an unanswered request this many times
|
||||
#define MODBUS_MAX_NB_REGISTERS 0x7D
|
||||
|
||||
enum eModbusFunctions
|
||||
{
|
||||
MODBUS_FCT_READ_HOLDING_REGISTERS = 3,
|
||||
MODBUS_WRITE_SINGLE_REGISTER = 6,
|
||||
MODBUS_FCT_WRITE_MULTIPLE_REGISTERS = 16
|
||||
};
|
||||
|
||||
enum eModbusExceptionCodes
|
||||
{
|
||||
MODBUS_EXCEPTION_ILLEGAL_FCT = 1,
|
||||
MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS = 2,
|
||||
MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE = 3,
|
||||
MODBUS_EXCEPTION_SERVER_DEVICE_FAILURE = 4,
|
||||
MODBUS_EXCEPTION_ACKNOWLEDGE = 5,
|
||||
MODBUS_EXCEPTION_SERVER_DEVICE_BUSY = 6,
|
||||
MODBUS_EXCEPTION_MEMORY_PARITY_ERROR = 8,
|
||||
MODBUS_EXCEPTION_GATEWAY_PATH_UNAVAILABLE = 10,
|
||||
MODBUS_EXCEPTION_GATEWAY_TARGET_DEV_NOT_RESPONDING = 11
|
||||
};
|
||||
|
||||
//Énumération des différents modes possibles
|
||||
enum eModbusModes
|
||||
{
|
||||
MODBUS_MASTER_MODE,
|
||||
MODBUS_SLAVE_MODE,
|
||||
MODBUS_INVALID_MODE
|
||||
};
|
||||
|
||||
class CModbusException
|
||||
{
|
||||
public:
|
||||
|
||||
};
|
||||
|
||||
class CModbusPDU
|
||||
{
|
||||
public:
|
||||
qint8 mFunctionCode; //Type de transaction (voir structure eModbusFunctions) pour les fonctions implémentées par le présent module
|
||||
QByteArray mData; //Les données de la transaction
|
||||
};
|
||||
|
||||
class CModbusHeader //Objet contenant les données d'un header Modbus (selon la spécification)
|
||||
{
|
||||
public:
|
||||
qint16 mTransactionID;
|
||||
qint16 mProtocolID;
|
||||
qint16 mMessageLength;
|
||||
qint8 mUnitID;
|
||||
};
|
||||
|
||||
class CModbusTransaction //Objet contenant les données d'une transaction Modbus
|
||||
{
|
||||
public:
|
||||
CModbusHeader mHeader; //Le header de la transaction
|
||||
CModbusPDU mPDU; //Le PDU (fonction & données) de la transaction (voir classe CModbusPDU)
|
||||
};
|
||||
|
||||
class CModbusRequest : public CModbusTransaction //Objet représentant une transaction (mode maître)
|
||||
{
|
||||
public:
|
||||
CModbusRequest();
|
||||
~CModbusRequest();
|
||||
int mRetries; //nombre de fois que la transaction a été retransmise
|
||||
QTimer *mRequestTimer; //Timer servant à retransmettre la requête si aucune réponse ne survient
|
||||
quint16 mStartAddress, mNbRegisters; //For convinience...
|
||||
};
|
||||
|
||||
class CModbusBackend : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
|
||||
|
||||
private:
|
||||
//enum eModbusMasterSMStates
|
||||
//{
|
||||
// MODBUS_SM_WAIT_FOR__STATE
|
||||
//};
|
||||
|
||||
//enum eModbusSlaveSMStates
|
||||
//{
|
||||
|
||||
//};
|
||||
|
||||
public:
|
||||
CModbusBackend(CModbusRepository *Repo); //Le pointeur vers le registre des données est obligatoire.
|
||||
virtual ~CModbusBackend();
|
||||
QTcpSocket *mModbusTCPSocketHandle; //Pointeur vers le Socket TCP du réseau Modbus.
|
||||
CModbusRepository *mModbusRepo; //Pointeur vers le registre de données Modbus
|
||||
|
||||
bool mDataLinkValid; //Flag indiquant si le lien de communication est en santé
|
||||
int mModbusMode; //Indique si le lien modbus de cette instance est exploitée en "slave" (serveur) ou un "master" (client) (voir struct eModbusModes ci-haut).
|
||||
qint8 mDeviceID; //Le device ID Modbus de cette instance.
|
||||
void ModbusLinkDisconnected(); //Fonction appelée par le parent lors d'une perte de la connection.
|
||||
void SetDeviceID(qint8 ID){mDeviceID = ID;}
|
||||
|
||||
//Master (client)
|
||||
int SendReadHoldingRegistersRequest(quint16 StartAddress, quint16 RegisterCount); //Fonction servant à transmettre la fonction modbus "Read HR" au partenaire
|
||||
int SendWriteHoldingRegistersRequest(quint16 StartAddress, quint16 RegisterCount); //Fonction servant à transmettre la fonction modbus "Write HR" au partenaire
|
||||
int SendWriteSingleRegisterRequest(quint16 Address); //Fonction servant à transmettre la fonction modbus "Write Single Register" au partenaire
|
||||
|
||||
|
||||
|
||||
|
||||
virtual void RegistersDatabaseUpdated(quint16 StartAdderss, quint16 Length) = 0; //Fonction virtuelle à être implémentée par la classe dérivée
|
||||
//Appelée lorsque de nouvelles données ont été reçues du réseau Modbus et écrites dans le registre
|
||||
|
||||
|
||||
|
||||
//Master virtual functions
|
||||
virtual void ModbusResponseException(quint8 ExceptionCode, quint8 FctCode); //Fonction virtuelle à être implémentée par la classe dérivée
|
||||
virtual void ModbusWriteMultipleRegsSuccess(); //Fonction virtuelle à être implémentée par la classe dérivée (Modbus Master seulement). Appelée suite à la réception d'une réponse à une requête d'écriture multiple.
|
||||
virtual void ModbusWriteSingleRegsSuccess(); //Fonction virtuelle à être implémentée par la classe dérivée (Modbus Master seulement). Appelée suite à la réception d'une réponse à une requête d'écriture simple.
|
||||
virtual void ModbusRequestMaxRetryReached(); //Fonction virtuelle à être implémentée par la classe dérivée (Modbus Master seulement). Appelée lors de l'atteinte du nombre maximal d'essai de transmission d'une requête.
|
||||
//Sert à informer la classe dérivée lorsqu'une exception se produit dans la communication Modbus (réponse)
|
||||
|
||||
|
||||
//Slave virtual function
|
||||
virtual void ModbusRequestException(quint8 ExceptionCode, quint8 FctCode); //Fonction virtuelle à être implémentée par la classe dérivée
|
||||
//Sert à informer le parent lorsqu'une exception se produit dans la communication Modbus (requête)
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
//Sur un réseau Modbus, l'eslcave (slave) est un serveur et le maître (master) est un client.
|
||||
|
||||
|
||||
//Slave (server)
|
||||
int AnalyzeModbusRequest(CModbusTransaction Transaction); //Exécute l'analyse des données reçues d'une requête Modbus
|
||||
int SendModbusResponse(CModbusTransaction RequestTransaction, QByteArray Data); //Fonction servant à composer et transmettre une réponse à une requête.
|
||||
int SendErrorResponse(CModbusTransaction RequestTransaction, quint8 ErrorCode); //Fonction servant à composer et transmettre une réponse d'erreur à une requête.
|
||||
|
||||
//Master (client)
|
||||
QList<CModbusRequest*> mRequestsList; //Liste des requêtes courantes en attente d'une réponse du serveur
|
||||
int SendModbusRequest(CModbusRequest *Request); //Construit et transmet une nouvelle requête Modbus au partenaire.
|
||||
quint16 GetNewTransactionID(); //Fonction (helper) servant à générer un nouvel ID de transaction nécessaire pour transmettre une nouvelle requête.
|
||||
int AnalyzeModbusResponse(CModbusTransaction Transaction); //Exécute l'analyse des données reçues d'une réponse Modbus
|
||||
|
||||
quint16 mTransactionIDCounter; //Compteur interne des ID de transactions Modbus
|
||||
int mModbusRequestTimeout; //Valeur du délai d'attente maximal avant de recevoir une réponse à une requête. À l'expiration du timer, la requête est renvoyée.
|
||||
int mModbusMaxRetry; //Valeur du nombre maximal de renvoi d'une requête avant d'invalider la requête.
|
||||
|
||||
signals:
|
||||
|
||||
// void RegistersDatabaseUpdated(quint16 StartAdderss, quint16 Length);
|
||||
|
||||
// //Master signals
|
||||
// void ModbusResponseException(quint8 ExceptionCode, quint8 FctCode);
|
||||
|
||||
//// //Slave signals
|
||||
// void ModbusRequestException(quint8 ExceptionCode, quint8 FctCode);
|
||||
|
||||
|
||||
|
||||
public slots:
|
||||
void ModbusDataReady(); //Slot indiquant au module que des données sont arrivées et sont attente dans le Socket.
|
||||
|
||||
void RequestTimerExpired(); //Slot indiquant qu'un timer de requête a expiré.
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
QDataStream &operator<<(QDataStream &out, const CModbusHeader &source);
|
||||
QDataStream &operator>>(QDataStream &in, CModbusHeader &dest);
|
||||
|
||||
#endif // CMODBUSBACKEND_H
|
||||
220
Sources/Modbus/ModbusRepository.cpp
Normal file
220
Sources/Modbus/ModbusRepository.cpp
Normal file
@ -0,0 +1,220 @@
|
||||
#include "ModbusRepository.h"
|
||||
#include <QByteArray>
|
||||
#include <QBuffer>
|
||||
#include <QDataStream>
|
||||
//#include "EngLog.h"
|
||||
|
||||
CModbusRepository::CModbusRepository()
|
||||
{
|
||||
}
|
||||
|
||||
int CModbusRepository::AddHRDataMap(quint16 StartAddress, quint16 Length)
|
||||
{
|
||||
mMutex.lockForWrite();
|
||||
for(int i= 0; i < mHoldingRegisters.size(); i++)
|
||||
{
|
||||
if((StartAddress >= mHoldingRegisters.at(i).mStartAddress && StartAddress <= mHoldingRegisters.at(i).mEndAddress) ||
|
||||
(StartAddress + Length - 1 >= mHoldingRegisters.at(i).mStartAddress && StartAddress + Length - 1 <= mHoldingRegisters.at(i).mEndAddress))
|
||||
{
|
||||
mMutex.unlock();
|
||||
return RET_ERROR; //The data map overlaps an existing map.
|
||||
}
|
||||
}
|
||||
|
||||
CHRDataMap NewHRMap(StartAddress,Length);
|
||||
|
||||
mHoldingRegisters.append(NewHRMap);
|
||||
mMutex.unlock();
|
||||
|
||||
// CEngLog::instance()->AddLogString(QString("Création d'une zone registre modbus à l'adresse: %1 de taille %2").arg(StartAddress).arg(Length));
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
bool CModbusRepository::IsHRValid(quint16 StartAddress, quint16 Length, int *index)
|
||||
{
|
||||
mMutex.lockForRead();
|
||||
for(int i= 0; i < mHoldingRegisters.size(); i++)
|
||||
{
|
||||
if((StartAddress >= mHoldingRegisters.at(i).mStartAddress && StartAddress + Length - 1 <= mHoldingRegisters.at(i).mEndAddress))
|
||||
{
|
||||
if(index != 0)
|
||||
{
|
||||
*index = i;
|
||||
}
|
||||
mMutex.unlock();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
mMutex.unlock();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray CModbusRepository::GetHRData(quint16 StartAddress, quint16 Length, bool *OK)
|
||||
{
|
||||
QByteArray Data;
|
||||
int RegisterIndex = 0;
|
||||
|
||||
if(IsHRValid(StartAddress,Length, &RegisterIndex) == false)
|
||||
{
|
||||
if(OK != 0)
|
||||
{
|
||||
*OK = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mMutex.lockForRead();
|
||||
int DataIndex = StartAddress - mHoldingRegisters.at(RegisterIndex).mStartAddress;
|
||||
for(int i = 0; i < Length; i++)
|
||||
{
|
||||
quint16 CurReg = mHoldingRegisters.at(RegisterIndex).mRegistersData.at(DataIndex++);
|
||||
quint8 HighByte, LowByte;
|
||||
|
||||
LowByte = CurReg & 0x00FF;
|
||||
HighByte = (CurReg >> 8) & 0x00FF;
|
||||
Data.append(HighByte);
|
||||
Data.append(LowByte);
|
||||
}
|
||||
mMutex.unlock();
|
||||
|
||||
if(OK != 0)
|
||||
*OK = true;
|
||||
}
|
||||
|
||||
return Data;
|
||||
}
|
||||
|
||||
int CModbusRepository::WriteHRData(quint16 StartAddress, quint16 Length, QByteArray Data)
|
||||
{
|
||||
int RegisterIndex;
|
||||
|
||||
if(IsHRValid(StartAddress,Length, &RegisterIndex) == false)
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
if(Length*2 != Data.size())
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
mMutex.lockForWrite();
|
||||
int DataIndex = StartAddress - mHoldingRegisters.at(RegisterIndex).mStartAddress;
|
||||
|
||||
for(int i = 0; i < Length; i++)
|
||||
{
|
||||
quint8 HighByte = Data.at(i*2);
|
||||
quint8 LowByte = Data.at(i*2 + 1);
|
||||
qint16 Word = HighByte;
|
||||
Word <<= 8;
|
||||
Word += LowByte;
|
||||
Word = Word &0xFFFF;
|
||||
|
||||
mHoldingRegisters[RegisterIndex].mRegistersData[DataIndex++] = Word;
|
||||
}
|
||||
mMutex.unlock();
|
||||
|
||||
emit RepoChanged(StartAddress,Length);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int CModbusRepository::WriteSingleReg(quint16 Address, quint16 Value)
|
||||
{
|
||||
int RegisterIndex;
|
||||
|
||||
if(IsHRValid(Address,1, &RegisterIndex) == false)
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
mMutex.lockForWrite();
|
||||
int DataIndex = Address - mHoldingRegisters.at(RegisterIndex).mStartAddress;
|
||||
mHoldingRegisters[RegisterIndex].mRegistersData[DataIndex] = Value;
|
||||
mMutex.unlock();
|
||||
|
||||
emit RepoChanged(Address,1);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
int CModbusRepository::WriteMultipleRegs(quint16 StartAddress, QList<qint16> Data)
|
||||
{
|
||||
int RegisterIndex;
|
||||
|
||||
if(IsHRValid(StartAddress,Data.size(), &RegisterIndex) == false)
|
||||
{
|
||||
return RET_ERROR;
|
||||
}
|
||||
|
||||
mMutex.lockForWrite();
|
||||
int DataIndex = StartAddress - mHoldingRegisters.at(RegisterIndex).mStartAddress;
|
||||
for(int i = 0; i < Data.size(); i++)
|
||||
{
|
||||
mHoldingRegisters[RegisterIndex].mRegistersData[DataIndex++] = Data.at(i);
|
||||
}
|
||||
mMutex.unlock();
|
||||
|
||||
emit RepoChanged(StartAddress,Data.size());
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
QList<qint16> CModbusRepository::GetRegs(quint16 StartAddress, quint16 Length, bool *OK)
|
||||
{
|
||||
int RegisterIndex;
|
||||
|
||||
if(IsHRValid(StartAddress,Length, &RegisterIndex) == false)
|
||||
{
|
||||
if(OK != 0)
|
||||
{
|
||||
*OK = false;
|
||||
}
|
||||
return QList<qint16>();
|
||||
}
|
||||
|
||||
if(OK != 0)
|
||||
{
|
||||
*OK = true;
|
||||
}
|
||||
|
||||
int DataIndex = StartAddress - mHoldingRegisters.at(RegisterIndex).mStartAddress;
|
||||
return mHoldingRegisters[RegisterIndex].mRegistersData.mid(DataIndex,Length);
|
||||
}
|
||||
quint16 CModbusRepository::GetSingleReg(quint16 Address, bool *OK)
|
||||
{
|
||||
int RegisterIndex;
|
||||
|
||||
if(IsHRValid(Address,1, &RegisterIndex) == false)
|
||||
{
|
||||
if(OK != 0)
|
||||
*OK = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(OK != 0)
|
||||
*OK = true;
|
||||
|
||||
mMutex.lockForRead();
|
||||
int DataIndex = Address - mHoldingRegisters.at(RegisterIndex).mStartAddress;
|
||||
quint16 Data = mHoldingRegisters[RegisterIndex].mRegistersData[DataIndex];
|
||||
mMutex.unlock();
|
||||
|
||||
return Data;
|
||||
}
|
||||
|
||||
|
||||
CHRDataMap::CHRDataMap(quint16 StartAddress, quint16 Length)
|
||||
{
|
||||
mStartAddress = StartAddress;
|
||||
mLength = Length;
|
||||
for(int i = 0; i < Length; i++)
|
||||
{
|
||||
mRegistersData.append(0);
|
||||
}
|
||||
mEndAddress = StartAddress + Length - 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
44
Sources/Modbus/ModbusRepository.h
Normal file
44
Sources/Modbus/ModbusRepository.h
Normal file
@ -0,0 +1,44 @@
|
||||
#ifndef MODBUSREPOSITORY_H
|
||||
#define MODBUSREPOSITORY_H
|
||||
#include "GlobalDefine.h"
|
||||
#include <QList>
|
||||
#include <QReadWriteLock>
|
||||
|
||||
class CHRDataMap ///Holding Register data map.
|
||||
{
|
||||
public:
|
||||
CHRDataMap(quint16 StartAddress, quint16 Length);
|
||||
quint16 mStartAddress,mEndAddress;
|
||||
quint16 mLength;
|
||||
QList<qint16> mRegistersData;
|
||||
|
||||
};
|
||||
|
||||
class CModbusRepository : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CModbusRepository();
|
||||
|
||||
//Holding Registers
|
||||
int AddHRDataMap(quint16 StartAddress, quint16 Length);
|
||||
bool IsHRValid(quint16 StartAddress, quint16 Length, int *index = 0);
|
||||
QByteArray GetHRData(quint16 StartAddress, quint16 Length, bool *OK = 0);
|
||||
quint16 GetSingleReg(quint16 Address, bool *OK = 0);
|
||||
QList<qint16> GetRegs(quint16 StartAddress, quint16 Length, bool *OK = 0);
|
||||
int WriteHRData(quint16 StartAddress, quint16 Length, QByteArray Data);
|
||||
int WriteSingleReg(quint16 Address, quint16 Value);
|
||||
int WriteMultipleRegs(quint16 StartAddress, QList<qint16> Data);
|
||||
const QList<CHRDataMap> *GetRepo(){return &mHoldingRegisters;}
|
||||
|
||||
|
||||
private:
|
||||
QList<CHRDataMap> mHoldingRegisters;
|
||||
QReadWriteLock mMutex;
|
||||
|
||||
signals:
|
||||
void RepoChanged(quint16 StartAddress, quint16 Length);
|
||||
|
||||
};
|
||||
|
||||
#endif // MODBUSREPOSITORY_H
|
||||
@ -13,7 +13,7 @@ CNetworkDevice::~CNetworkDevice()
|
||||
{
|
||||
if(mNetworkInterfacePtr != 0)
|
||||
{
|
||||
delete mNetworkInterfacePtr;
|
||||
// delete mNetworkInterfacePtr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -265,6 +265,11 @@ enum CHALET_INTERFACE_CMDS
|
||||
CHALET_INTERFACE_DO_HARAKIRI_RESPONSE,
|
||||
CHALET_INTERFACE_REBOOT_CPU_REQUEST,
|
||||
CHALET_INTERFACE_REBOOT_CPU_RESPONSE,
|
||||
CHALET_INTERFACE_GET_TODAYS_DATA_LOG_REQUEST,
|
||||
CHALET_INTERFACE_GET_TODAYS_DATA_LOG_RESPONSE,
|
||||
CHALET_INTERFACE_CHALET_ACTIVITY_RESPONSE,
|
||||
CHALET_INTERFACE_GET_DATA_LOG_REQUEST,
|
||||
CHALET_INTERFACE_GET_DATA_LOG_RESPONSE,
|
||||
|
||||
MAX_CHALET_INTERFACE_CMD
|
||||
};
|
||||
|
||||
@ -69,7 +69,7 @@ int CSprinklerDevice::NewDeviceFrameReceived(int DeviceID, int DeviceAddress, in
|
||||
}
|
||||
case SPRINKLER_DEVICE_SET_SPRINKLER_STATE_ACK:
|
||||
{
|
||||
mNetworkInterfacePtr->SendNetworkMessage(ID_SPRINKLER_DEVICE,1,SPRINKLER_DEVICE_GET_SPRINKLER_STATE_REQUEST,0,QByteArray());
|
||||
mNetworkInterfacePtr->SendNetworkMessage(ID_SPRINKLER_DEVICE,1,SPRINKLER_DEVICE_GET_SPRINKLER_STATE_REQUEST,0,0);
|
||||
break;
|
||||
}
|
||||
case SPRINKLER_DEVICE_GET_SPRINKLER_STATE_RESPONSE:
|
||||
@ -143,5 +143,5 @@ int CSprinklerDevice::NewDeviceFrameReceived(int DeviceID, int DeviceAddress, in
|
||||
|
||||
void CSprinklerDevice::StatusTimerExpired()
|
||||
{
|
||||
mNetworkInterfacePtr->SendNetworkMessage(ID_SPRINKLER_DEVICE,1,SPRINKLER_DEVICE_STATUS_REQUEST,0,QByteArray());
|
||||
mNetworkInterfacePtr->SendNetworkMessage(ID_SPRINKLER_DEVICE,1,SPRINKLER_DEVICE_STATUS_REQUEST,0,0);
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ int CSprinklerInterface::NewDeviceFrameReceived(int DeviceID, int DeviceAddress,
|
||||
MsgData.append(Sprinkler->mDeviceAddress); //1st device address
|
||||
MsgData.append((unsigned char)Sprinkler->mSprinklerState);
|
||||
|
||||
mNetworkInterfacePtr->SendNetworkMessage(ID_SPRINKLER_INTERFACE,mDeviceAddress,SPRINKLER_INTERFACE_GET_SPRINKLER_STATE_RESPONSE,MsgData.size(),MsgData);
|
||||
mNetworkInterfacePtr->SendNetworkMessage(ID_SPRINKLER_INTERFACE,mDeviceAddress,SPRINKLER_INTERFACE_GET_SPRINKLER_STATE_RESPONSE,MsgData.size(),&MsgData);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ int CSMSDevice::NewDeviceFrameReceived(int DeviceID, int DeviceAddress, int Mess
|
||||
*FrameDataStrm << DID;
|
||||
|
||||
FrameBuffer.seek(0);
|
||||
mNetworkInterfacePtr->SendNetworkMessage(mDeviceID,mDeviceAddress,SMS_CLIENT_DEVICE_DID_INFO_RESPONSE,FrameData.size(),FrameData);
|
||||
mNetworkInterfacePtr->SendNetworkMessage(mDeviceID,mDeviceAddress,SMS_CLIENT_DEVICE_DID_INFO_RESPONSE,FrameData.size(),&FrameData);
|
||||
delete FrameDataStrm;
|
||||
|
||||
break;
|
||||
@ -81,7 +81,7 @@ int CSMSDevice::NewDeviceFrameReceived(int DeviceID, int DeviceAddress, int Mess
|
||||
}
|
||||
|
||||
FrameBuffer.seek(0);
|
||||
mNetworkInterfacePtr->SendNetworkMessage(mDeviceID,mDeviceAddress,SMS_CLIENT_DEVICE_GET_ALL_MSG_RESPONSE,FrameData.size(),FrameData);
|
||||
mNetworkInterfacePtr->SendNetworkMessage(mDeviceID,mDeviceAddress,SMS_CLIENT_DEVICE_GET_ALL_MSG_RESPONSE,FrameData.size(),&FrameData);
|
||||
|
||||
FrameBuffer.close();
|
||||
delete FrameDataStrm;
|
||||
@ -131,7 +131,7 @@ int CSMSDevice::NewDeviceFrameReceived(int DeviceID, int DeviceAddress, int Mess
|
||||
}
|
||||
|
||||
FrameBuffer.seek(0);
|
||||
mNetworkInterfacePtr->SendNetworkMessage(mDeviceID,mDeviceAddress,SMS_CLIENT_DEVICE_GET_CONTACTS_RESPONSE,FrameData.size(),FrameData);
|
||||
mNetworkInterfacePtr->SendNetworkMessage(mDeviceID,mDeviceAddress,SMS_CLIENT_DEVICE_GET_CONTACTS_RESPONSE,FrameData.size(),&FrameData);
|
||||
|
||||
FrameBuffer.close();
|
||||
delete FrameDataStrm;
|
||||
@ -159,7 +159,7 @@ int CSMSDevice::NewDeviceFrameReceived(int DeviceID, int DeviceAddress, int Mess
|
||||
|
||||
void CSMSDevice::RequestStatus()
|
||||
{
|
||||
mNetworkInterfacePtr->SendNetworkMessage(mDeviceID,mDeviceAddress,SMS_CLIENT_DEVICE_STATUS_REQUEST,0,QByteArray());
|
||||
mNetworkInterfacePtr->SendNetworkMessage(mDeviceID,mDeviceAddress,SMS_CLIENT_DEVICE_STATUS_REQUEST,0,0);
|
||||
}
|
||||
|
||||
void CSMSDevice::SendSMSSentAck(bool Ack)
|
||||
@ -176,7 +176,7 @@ void CSMSDevice::SendSMSSentAck(bool Ack)
|
||||
}
|
||||
*FrameDataStrm << ACKData;
|
||||
|
||||
mNetworkInterfacePtr->SendNetworkMessage(mDeviceID,mDeviceAddress,SMS_CLIENT_DEVICE_SEND_SMS_ACK,FrameData.size(),FrameData);
|
||||
mNetworkInterfacePtr->SendNetworkMessage(mDeviceID,mDeviceAddress,SMS_CLIENT_DEVICE_SEND_SMS_ACK,FrameData.size(),&FrameData);
|
||||
|
||||
|
||||
FrameBuffer.close();
|
||||
@ -198,7 +198,7 @@ void CSMSDevice::SendNewSMSReceived(QList<CSMSMessage> NewMessages)
|
||||
}
|
||||
|
||||
FrameBuffer.seek(0);
|
||||
mNetworkInterfacePtr->SendNetworkMessage(mDeviceID,mDeviceAddress,SMS_CLIENT_DEVICE_NEW_MSG_NOTIFICATION,FrameData.size(),FrameData);
|
||||
mNetworkInterfacePtr->SendNetworkMessage(mDeviceID,mDeviceAddress,SMS_CLIENT_DEVICE_NEW_MSG_NOTIFICATION,FrameData.size(),&FrameData);
|
||||
|
||||
FrameBuffer.close();
|
||||
delete FrameDataStrm;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user