Commit 210d2652ba1b511557ec5065768a02e10d0c7376
0 parents
Initial commit.
Showing
43 changed files
with
7543 additions
and
0 deletions
.gitignore
0 → 100644
CMakeLists.txt
0 → 100644
| 1 | +++ a/CMakeLists.txt | ||
| 1 | +cmake_minimum_required(VERSION 3.0) | ||
| 2 | + | ||
| 3 | +# Check to see where cmake is located. | ||
| 4 | +if( IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/cmake ) | ||
| 5 | + LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) | ||
| 6 | +elseif( IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../cmake ) | ||
| 7 | + LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) | ||
| 8 | +else() | ||
| 9 | + return() | ||
| 10 | +endif() | ||
| 11 | + | ||
| 12 | +# Check to see if there is versioning information available | ||
| 13 | +if(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/osdev_versioning/cmake) | ||
| 14 | + LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/osdev_versioning/cmake) | ||
| 15 | + include(osdevversion) | ||
| 16 | +endif() | ||
| 17 | + | ||
| 18 | +include(projectheader) | ||
| 19 | +project_header(osdev_qt-mqtt) | ||
| 20 | + | ||
| 21 | +add_subdirectory(src) | ||
| 22 | +add_subdirectory(tests) | ||
| 23 | + | ||
| 24 | +# include(packaging) | ||
| 25 | +# package_component() |
README.md
0 → 100644
| 1 | +++ a/README.md |
src/CMakeLists.txt
0 → 100644
| 1 | +++ a/src/CMakeLists.txt | ||
| 1 | +cmake_minimum_required(VERSION 3.0) | ||
| 2 | +LIST( APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) | ||
| 3 | +include(projectheader) | ||
| 4 | +project_header(qmqtt) | ||
| 5 | + | ||
| 6 | +option( ${PROJECT_NAME}_SHARED "Build a shared library. Turn off for static." ON ) | ||
| 7 | +option( ${PROJECT_NAME}_WEBSOCKETS "Enable WebSockets for MQTT" OFF ) | ||
| 8 | +option( ${PROJECT_NAME}_SSL "Enable SSL support for MQTT" OFF ) | ||
| 9 | + | ||
| 10 | +set( ws_component ) | ||
| 11 | +set( ws_libname ) | ||
| 12 | +set( qt5_min_version "5.3.0" ) | ||
| 13 | + | ||
| 14 | +if ( ${PROJECT_NAME}_WEBSOCKETS ) | ||
| 15 | + set( ws_component WebSockets ) | ||
| 16 | + set( ws_libname Qt5::WebSockets ) | ||
| 17 | + set( qt5_min_version "5.7.0" ) | ||
| 18 | +endif() | ||
| 19 | + | ||
| 20 | +if ( NOT ${PROJECT_NAME}_SSL) | ||
| 21 | + set( ssl_defs QT_NO_SSL ) | ||
| 22 | +endif() | ||
| 23 | + | ||
| 24 | +find_package( Qt5 ${qt5_min_version} COMPONENTS Core Network ${ws_component} CONFIG REQUIRED ) | ||
| 25 | + | ||
| 26 | +include_directories( SYSTEM | ||
| 27 | + ${Qt5Core_INCLUDE_DIRS} | ||
| 28 | + ${Qt5Network_INCLUDE_DIRS} | ||
| 29 | + ${Qt5WebSockets_INCLUDE_DIRS} | ||
| 30 | + ${CMAKE_CURRENT_SOURCE_DIR}/../logutils | ||
| 31 | +) | ||
| 32 | + | ||
| 33 | +# include(compiler) | ||
| 34 | + | ||
| 35 | +set( SRC_LIST | ||
| 36 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt.cpp | ||
| 37 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_states.h | ||
| 38 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_configsettings.cpp | ||
| 39 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_pubsubclient.cpp | ||
| 40 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_client_p.cpp | ||
| 41 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_client.cpp | ||
| 42 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_frame.cpp | ||
| 43 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_message.cpp | ||
| 44 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_network.cpp | ||
| 45 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_routesubscription.cpp | ||
| 46 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_router.cpp | ||
| 47 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_socket.cpp | ||
| 48 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_timer.cpp | ||
| 49 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_websocket.cpp | ||
| 50 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_websocketiodevice.cpp | ||
| 51 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_ssl_socket.cpp | ||
| 52 | +) | ||
| 53 | + | ||
| 54 | +include(qtmoc) | ||
| 55 | +create_mocs( SRC_LIST MOC_LIST | ||
| 56 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt.h | ||
| 57 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_client.h | ||
| 58 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_pubsubclient.h | ||
| 59 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_routesubscription.h | ||
| 60 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_router.h | ||
| 61 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_networkinterface.h | ||
| 62 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_socketinterface.h | ||
| 63 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_timerinterface.h | ||
| 64 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_network_p.h | ||
| 65 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_socket_p.h | ||
| 66 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_timer_p.h | ||
| 67 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_websocket_p.h | ||
| 68 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_websocketiodevice_p.h | ||
| 69 | + ${CMAKE_CURRENT_SOURCE_DIR}/qmqtt_ssl_socket_p.h | ||
| 70 | +) | ||
| 71 | + | ||
| 72 | +link_directories( | ||
| 73 | + ${CMAKE_BINARY_DIR}/lib | ||
| 74 | +) | ||
| 75 | + | ||
| 76 | +include(library) | ||
| 77 | +add_libraries( | ||
| 78 | + ${Qt5Core_LIBRARIES} | ||
| 79 | + ${Qt5Network_LIBRARIES} | ||
| 80 | + ${Qt5WebSocket_LIBRARIES} | ||
| 81 | + logutils | ||
| 82 | +) | ||
| 83 | + | ||
| 84 | +include(installation) | ||
| 85 | +install_component() |
src/Doxyfile
0 → 100644
| 1 | +++ a/src/Doxyfile | ||
| 1 | +# Doxyfile 1.8.15 | ||
| 2 | + | ||
| 3 | +# This file describes the settings to be used by the documentation system | ||
| 4 | +# doxygen (www.doxygen.org) for a project. | ||
| 5 | +# | ||
| 6 | +# All text after a double hash (##) is considered a comment and is placed in | ||
| 7 | +# front of the TAG it is preceding. | ||
| 8 | +# | ||
| 9 | +# All text after a single hash (#) is considered a comment and will be ignored. | ||
| 10 | +# The format is: | ||
| 11 | +# TAG = value [value, ...] | ||
| 12 | +# For lists, items can also be appended using: | ||
| 13 | +# TAG += value [value, ...] | ||
| 14 | +# Values that contain spaces should be placed between quotes (\" \"). | ||
| 15 | + | ||
| 16 | +#--------------------------------------------------------------------------- | ||
| 17 | +# Project related configuration options | ||
| 18 | +#--------------------------------------------------------------------------- | ||
| 19 | + | ||
| 20 | +# This tag specifies the encoding used for all characters in the configuration | ||
| 21 | +# file that follow. The default is UTF-8 which is also the encoding used for all | ||
| 22 | +# text before the first occurrence of this tag. Doxygen uses libiconv (or the | ||
| 23 | +# iconv built into libc) for the transcoding. See | ||
| 24 | +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. | ||
| 25 | +# The default value is: UTF-8. | ||
| 26 | + | ||
| 27 | +DOXYFILE_ENCODING = UTF-8 | ||
| 28 | + | ||
| 29 | +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by | ||
| 30 | +# double-quotes, unless you are using Doxywizard) that should identify the | ||
| 31 | +# project for which the documentation is generated. This name is used in the | ||
| 32 | +# title of most generated pages and in a few other places. | ||
| 33 | +# The default value is: My Project. | ||
| 34 | + | ||
| 35 | +PROJECT_NAME = QMQTT | ||
| 36 | + | ||
| 37 | +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This | ||
| 38 | +# could be handy for archiving the generated documentation or if some version | ||
| 39 | +# control system is used. | ||
| 40 | + | ||
| 41 | +PROJECT_NUMBER = | ||
| 42 | + | ||
| 43 | +# Using the PROJECT_BRIEF tag one can provide an optional one line description | ||
| 44 | +# for a project that appears at the top of each page and should give viewer a | ||
| 45 | +# quick idea about the purpose of the project. Keep the description short. | ||
| 46 | + | ||
| 47 | +PROJECT_BRIEF = | ||
| 48 | + | ||
| 49 | +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included | ||
| 50 | +# in the documentation. The maximum height of the logo should not exceed 55 | ||
| 51 | +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy | ||
| 52 | +# the logo to the output directory. | ||
| 53 | + | ||
| 54 | +PROJECT_LOGO = | ||
| 55 | + | ||
| 56 | +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path | ||
| 57 | +# into which the generated documentation will be written. If a relative path is | ||
| 58 | +# entered, it will be relative to the location where doxygen was started. If | ||
| 59 | +# left blank the current directory will be used. | ||
| 60 | + | ||
| 61 | +OUTPUT_DIRECTORY = /home/pgroen/projects/osdev_components/Documentation | ||
| 62 | + | ||
| 63 | +# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- | ||
| 64 | +# directories (in 2 levels) under the output directory of each output format and | ||
| 65 | +# will distribute the generated files over these directories. Enabling this | ||
| 66 | +# option can be useful when feeding doxygen a huge amount of source files, where | ||
| 67 | +# putting all generated files in the same directory would otherwise causes | ||
| 68 | +# performance problems for the file system. | ||
| 69 | +# The default value is: NO. | ||
| 70 | + | ||
| 71 | +CREATE_SUBDIRS = NO | ||
| 72 | + | ||
| 73 | +# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII | ||
| 74 | +# characters to appear in the names of generated files. If set to NO, non-ASCII | ||
| 75 | +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode | ||
| 76 | +# U+3044. | ||
| 77 | +# The default value is: NO. | ||
| 78 | + | ||
| 79 | +ALLOW_UNICODE_NAMES = NO | ||
| 80 | + | ||
| 81 | +# The OUTPUT_LANGUAGE tag is used to specify the language in which all | ||
| 82 | +# documentation generated by doxygen is written. Doxygen will use this | ||
| 83 | +# information to generate all constant output in the proper language. | ||
| 84 | +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, | ||
| 85 | +# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), | ||
| 86 | +# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, | ||
| 87 | +# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), | ||
| 88 | +# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, | ||
| 89 | +# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, | ||
| 90 | +# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, | ||
| 91 | +# Ukrainian and Vietnamese. | ||
| 92 | +# The default value is: English. | ||
| 93 | + | ||
| 94 | +OUTPUT_LANGUAGE = English | ||
| 95 | + | ||
| 96 | +# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all | ||
| 97 | +# documentation generated by doxygen is written. Doxygen will use this | ||
| 98 | +# information to generate all generated output in the proper direction. | ||
| 99 | +# Possible values are: None, LTR, RTL and Context. | ||
| 100 | +# The default value is: None. | ||
| 101 | + | ||
| 102 | +OUTPUT_TEXT_DIRECTION = None | ||
| 103 | + | ||
| 104 | +# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member | ||
| 105 | +# descriptions after the members that are listed in the file and class | ||
| 106 | +# documentation (similar to Javadoc). Set to NO to disable this. | ||
| 107 | +# The default value is: YES. | ||
| 108 | + | ||
| 109 | +BRIEF_MEMBER_DESC = YES | ||
| 110 | + | ||
| 111 | +# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief | ||
| 112 | +# description of a member or function before the detailed description | ||
| 113 | +# | ||
| 114 | +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the | ||
| 115 | +# brief descriptions will be completely suppressed. | ||
| 116 | +# The default value is: YES. | ||
| 117 | + | ||
| 118 | +REPEAT_BRIEF = YES | ||
| 119 | + | ||
| 120 | +# This tag implements a quasi-intelligent brief description abbreviator that is | ||
| 121 | +# used to form the text in various listings. Each string in this list, if found | ||
| 122 | +# as the leading text of the brief description, will be stripped from the text | ||
| 123 | +# and the result, after processing the whole list, is used as the annotated | ||
| 124 | +# text. Otherwise, the brief description is used as-is. If left blank, the | ||
| 125 | +# following values are used ($name is automatically replaced with the name of | ||
| 126 | +# the entity):The $name class, The $name widget, The $name file, is, provides, | ||
| 127 | +# specifies, contains, represents, a, an and the. | ||
| 128 | + | ||
| 129 | +ABBREVIATE_BRIEF = "The $name class" \ | ||
| 130 | + "The $name widget" \ | ||
| 131 | + "The $name file" \ | ||
| 132 | + is \ | ||
| 133 | + provides \ | ||
| 134 | + specifies \ | ||
| 135 | + contains \ | ||
| 136 | + represents \ | ||
| 137 | + a \ | ||
| 138 | + an \ | ||
| 139 | + the | ||
| 140 | + | ||
| 141 | +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then | ||
| 142 | +# doxygen will generate a detailed section even if there is only a brief | ||
| 143 | +# description. | ||
| 144 | +# The default value is: NO. | ||
| 145 | + | ||
| 146 | +ALWAYS_DETAILED_SEC = NO | ||
| 147 | + | ||
| 148 | +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all | ||
| 149 | +# inherited members of a class in the documentation of that class as if those | ||
| 150 | +# members were ordinary class members. Constructors, destructors and assignment | ||
| 151 | +# operators of the base classes will not be shown. | ||
| 152 | +# The default value is: NO. | ||
| 153 | + | ||
| 154 | +INLINE_INHERITED_MEMB = NO | ||
| 155 | + | ||
| 156 | +# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path | ||
| 157 | +# before files name in the file list and in the header files. If set to NO the | ||
| 158 | +# shortest path that makes the file name unique will be used | ||
| 159 | +# The default value is: YES. | ||
| 160 | + | ||
| 161 | +FULL_PATH_NAMES = YES | ||
| 162 | + | ||
| 163 | +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. | ||
| 164 | +# Stripping is only done if one of the specified strings matches the left-hand | ||
| 165 | +# part of the path. The tag can be used to show relative paths in the file list. | ||
| 166 | +# If left blank the directory from which doxygen is run is used as the path to | ||
| 167 | +# strip. | ||
| 168 | +# | ||
| 169 | +# Note that you can specify absolute paths here, but also relative paths, which | ||
| 170 | +# will be relative from the directory where doxygen is started. | ||
| 171 | +# This tag requires that the tag FULL_PATH_NAMES is set to YES. | ||
| 172 | + | ||
| 173 | +STRIP_FROM_PATH = | ||
| 174 | + | ||
| 175 | +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the | ||
| 176 | +# path mentioned in the documentation of a class, which tells the reader which | ||
| 177 | +# header file to include in order to use a class. If left blank only the name of | ||
| 178 | +# the header file containing the class definition is used. Otherwise one should | ||
| 179 | +# specify the list of include paths that are normally passed to the compiler | ||
| 180 | +# using the -I flag. | ||
| 181 | + | ||
| 182 | +STRIP_FROM_INC_PATH = | ||
| 183 | + | ||
| 184 | +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but | ||
| 185 | +# less readable) file names. This can be useful is your file systems doesn't | ||
| 186 | +# support long names like on DOS, Mac, or CD-ROM. | ||
| 187 | +# The default value is: NO. | ||
| 188 | + | ||
| 189 | +SHORT_NAMES = NO | ||
| 190 | + | ||
| 191 | +# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the | ||
| 192 | +# first line (until the first dot) of a Javadoc-style comment as the brief | ||
| 193 | +# description. If set to NO, the Javadoc-style will behave just like regular Qt- | ||
| 194 | +# style comments (thus requiring an explicit @brief command for a brief | ||
| 195 | +# description.) | ||
| 196 | +# The default value is: NO. | ||
| 197 | + | ||
| 198 | +JAVADOC_AUTOBRIEF = NO | ||
| 199 | + | ||
| 200 | +# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first | ||
| 201 | +# line (until the first dot) of a Qt-style comment as the brief description. If | ||
| 202 | +# set to NO, the Qt-style will behave just like regular Qt-style comments (thus | ||
| 203 | +# requiring an explicit \brief command for a brief description.) | ||
| 204 | +# The default value is: NO. | ||
| 205 | + | ||
| 206 | +QT_AUTOBRIEF = NO | ||
| 207 | + | ||
| 208 | +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a | ||
| 209 | +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as | ||
| 210 | +# a brief description. This used to be the default behavior. The new default is | ||
| 211 | +# to treat a multi-line C++ comment block as a detailed description. Set this | ||
| 212 | +# tag to YES if you prefer the old behavior instead. | ||
| 213 | +# | ||
| 214 | +# Note that setting this tag to YES also means that rational rose comments are | ||
| 215 | +# not recognized any more. | ||
| 216 | +# The default value is: NO. | ||
| 217 | + | ||
| 218 | +MULTILINE_CPP_IS_BRIEF = NO | ||
| 219 | + | ||
| 220 | +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the | ||
| 221 | +# documentation from any documented member that it re-implements. | ||
| 222 | +# The default value is: YES. | ||
| 223 | + | ||
| 224 | +INHERIT_DOCS = YES | ||
| 225 | + | ||
| 226 | +# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new | ||
| 227 | +# page for each member. If set to NO, the documentation of a member will be part | ||
| 228 | +# of the file/class/namespace that contains it. | ||
| 229 | +# The default value is: NO. | ||
| 230 | + | ||
| 231 | +SEPARATE_MEMBER_PAGES = NO | ||
| 232 | + | ||
| 233 | +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen | ||
| 234 | +# uses this value to replace tabs by spaces in code fragments. | ||
| 235 | +# Minimum value: 1, maximum value: 16, default value: 4. | ||
| 236 | + | ||
| 237 | +TAB_SIZE = 4 | ||
| 238 | + | ||
| 239 | +# This tag can be used to specify a number of aliases that act as commands in | ||
| 240 | +# the documentation. An alias has the form: | ||
| 241 | +# name=value | ||
| 242 | +# For example adding | ||
| 243 | +# "sideeffect=@par Side Effects:\n" | ||
| 244 | +# will allow you to put the command \sideeffect (or @sideeffect) in the | ||
| 245 | +# documentation, which will result in a user-defined paragraph with heading | ||
| 246 | +# "Side Effects:". You can put \n's in the value part of an alias to insert | ||
| 247 | +# newlines (in the resulting output). You can put ^^ in the value part of an | ||
| 248 | +# alias to insert a newline as if a physical newline was in the original file. | ||
| 249 | +# When you need a literal { or } or , in the value part of an alias you have to | ||
| 250 | +# escape them by means of a backslash (\), this can lead to conflicts with the | ||
| 251 | +# commands \{ and \} for these it is advised to use the version @{ and @} or use | ||
| 252 | +# a double escape (\\{ and \\}) | ||
| 253 | + | ||
| 254 | +ALIASES = | ||
| 255 | + | ||
| 256 | +# This tag can be used to specify a number of word-keyword mappings (TCL only). | ||
| 257 | +# A mapping has the form "name=value". For example adding "class=itcl::class" | ||
| 258 | +# will allow you to use the command class in the itcl::class meaning. | ||
| 259 | + | ||
| 260 | +TCL_SUBST = | ||
| 261 | + | ||
| 262 | +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources | ||
| 263 | +# only. Doxygen will then generate output that is more tailored for C. For | ||
| 264 | +# instance, some of the names that are used will be different. The list of all | ||
| 265 | +# members will be omitted, etc. | ||
| 266 | +# The default value is: NO. | ||
| 267 | + | ||
| 268 | +OPTIMIZE_OUTPUT_FOR_C = NO | ||
| 269 | + | ||
| 270 | +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or | ||
| 271 | +# Python sources only. Doxygen will then generate output that is more tailored | ||
| 272 | +# for that language. For instance, namespaces will be presented as packages, | ||
| 273 | +# qualified scopes will look different, etc. | ||
| 274 | +# The default value is: NO. | ||
| 275 | + | ||
| 276 | +OPTIMIZE_OUTPUT_JAVA = NO | ||
| 277 | + | ||
| 278 | +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran | ||
| 279 | +# sources. Doxygen will then generate output that is tailored for Fortran. | ||
| 280 | +# The default value is: NO. | ||
| 281 | + | ||
| 282 | +OPTIMIZE_FOR_FORTRAN = NO | ||
| 283 | + | ||
| 284 | +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL | ||
| 285 | +# sources. Doxygen will then generate output that is tailored for VHDL. | ||
| 286 | +# The default value is: NO. | ||
| 287 | + | ||
| 288 | +OPTIMIZE_OUTPUT_VHDL = NO | ||
| 289 | + | ||
| 290 | +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice | ||
| 291 | +# sources only. Doxygen will then generate output that is more tailored for that | ||
| 292 | +# language. For instance, namespaces will be presented as modules, types will be | ||
| 293 | +# separated into more groups, etc. | ||
| 294 | +# The default value is: NO. | ||
| 295 | + | ||
| 296 | +OPTIMIZE_OUTPUT_SLICE = NO | ||
| 297 | + | ||
| 298 | +# Doxygen selects the parser to use depending on the extension of the files it | ||
| 299 | +# parses. With this tag you can assign which parser to use for a given | ||
| 300 | +# extension. Doxygen has a built-in mapping, but you can override or extend it | ||
| 301 | +# using this tag. The format is ext=language, where ext is a file extension, and | ||
| 302 | +# language is one of the parsers supported by doxygen: IDL, Java, Javascript, | ||
| 303 | +# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, | ||
| 304 | +# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: | ||
| 305 | +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser | ||
| 306 | +# tries to guess whether the code is fixed or free formatted code, this is the | ||
| 307 | +# default for Fortran type files), VHDL, tcl. For instance to make doxygen treat | ||
| 308 | +# .inc files as Fortran files (default is PHP), and .f files as C (default is | ||
| 309 | +# Fortran), use: inc=Fortran f=C. | ||
| 310 | +# | ||
| 311 | +# Note: For files without extension you can use no_extension as a placeholder. | ||
| 312 | +# | ||
| 313 | +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise | ||
| 314 | +# the files are not read by doxygen. | ||
| 315 | + | ||
| 316 | +EXTENSION_MAPPING = | ||
| 317 | + | ||
| 318 | +# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments | ||
| 319 | +# according to the Markdown format, which allows for more readable | ||
| 320 | +# documentation. See https://daringfireball.net/projects/markdown/ for details. | ||
| 321 | +# The output of markdown processing is further processed by doxygen, so you can | ||
| 322 | +# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in | ||
| 323 | +# case of backward compatibilities issues. | ||
| 324 | +# The default value is: YES. | ||
| 325 | + | ||
| 326 | +MARKDOWN_SUPPORT = YES | ||
| 327 | + | ||
| 328 | +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up | ||
| 329 | +# to that level are automatically included in the table of contents, even if | ||
| 330 | +# they do not have an id attribute. | ||
| 331 | +# Note: This feature currently applies only to Markdown headings. | ||
| 332 | +# Minimum value: 0, maximum value: 99, default value: 0. | ||
| 333 | +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. | ||
| 334 | + | ||
| 335 | +TOC_INCLUDE_HEADINGS = 0 | ||
| 336 | + | ||
| 337 | +# When enabled doxygen tries to link words that correspond to documented | ||
| 338 | +# classes, or namespaces to their corresponding documentation. Such a link can | ||
| 339 | +# be prevented in individual cases by putting a % sign in front of the word or | ||
| 340 | +# globally by setting AUTOLINK_SUPPORT to NO. | ||
| 341 | +# The default value is: YES. | ||
| 342 | + | ||
| 343 | +AUTOLINK_SUPPORT = YES | ||
| 344 | + | ||
| 345 | +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want | ||
| 346 | +# to include (a tag file for) the STL sources as input, then you should set this | ||
| 347 | +# tag to YES in order to let doxygen match functions declarations and | ||
| 348 | +# definitions whose arguments contain STL classes (e.g. func(std::string); | ||
| 349 | +# versus func(std::string) {}). This also make the inheritance and collaboration | ||
| 350 | +# diagrams that involve STL classes more complete and accurate. | ||
| 351 | +# The default value is: NO. | ||
| 352 | + | ||
| 353 | +BUILTIN_STL_SUPPORT = NO | ||
| 354 | + | ||
| 355 | +# If you use Microsoft's C++/CLI language, you should set this option to YES to | ||
| 356 | +# enable parsing support. | ||
| 357 | +# The default value is: NO. | ||
| 358 | + | ||
| 359 | +CPP_CLI_SUPPORT = NO | ||
| 360 | + | ||
| 361 | +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: | ||
| 362 | +# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen | ||
| 363 | +# will parse them like normal C++ but will assume all classes use public instead | ||
| 364 | +# of private inheritance when no explicit protection keyword is present. | ||
| 365 | +# The default value is: NO. | ||
| 366 | + | ||
| 367 | +SIP_SUPPORT = NO | ||
| 368 | + | ||
| 369 | +# For Microsoft's IDL there are propget and propput attributes to indicate | ||
| 370 | +# getter and setter methods for a property. Setting this option to YES will make | ||
| 371 | +# doxygen to replace the get and set methods by a property in the documentation. | ||
| 372 | +# This will only work if the methods are indeed getting or setting a simple | ||
| 373 | +# type. If this is not the case, or you want to show the methods anyway, you | ||
| 374 | +# should set this option to NO. | ||
| 375 | +# The default value is: YES. | ||
| 376 | + | ||
| 377 | +IDL_PROPERTY_SUPPORT = YES | ||
| 378 | + | ||
| 379 | +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC | ||
| 380 | +# tag is set to YES then doxygen will reuse the documentation of the first | ||
| 381 | +# member in the group (if any) for the other members of the group. By default | ||
| 382 | +# all members of a group must be documented explicitly. | ||
| 383 | +# The default value is: NO. | ||
| 384 | + | ||
| 385 | +DISTRIBUTE_GROUP_DOC = NO | ||
| 386 | + | ||
| 387 | +# If one adds a struct or class to a group and this option is enabled, then also | ||
| 388 | +# any nested class or struct is added to the same group. By default this option | ||
| 389 | +# is disabled and one has to add nested compounds explicitly via \ingroup. | ||
| 390 | +# The default value is: NO. | ||
| 391 | + | ||
| 392 | +GROUP_NESTED_COMPOUNDS = NO | ||
| 393 | + | ||
| 394 | +# Set the SUBGROUPING tag to YES to allow class member groups of the same type | ||
| 395 | +# (for instance a group of public functions) to be put as a subgroup of that | ||
| 396 | +# type (e.g. under the Public Functions section). Set it to NO to prevent | ||
| 397 | +# subgrouping. Alternatively, this can be done per class using the | ||
| 398 | +# \nosubgrouping command. | ||
| 399 | +# The default value is: YES. | ||
| 400 | + | ||
| 401 | +SUBGROUPING = YES | ||
| 402 | + | ||
| 403 | +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions | ||
| 404 | +# are shown inside the group in which they are included (e.g. using \ingroup) | ||
| 405 | +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX | ||
| 406 | +# and RTF). | ||
| 407 | +# | ||
| 408 | +# Note that this feature does not work in combination with | ||
| 409 | +# SEPARATE_MEMBER_PAGES. | ||
| 410 | +# The default value is: NO. | ||
| 411 | + | ||
| 412 | +INLINE_GROUPED_CLASSES = NO | ||
| 413 | + | ||
| 414 | +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions | ||
| 415 | +# with only public data fields or simple typedef fields will be shown inline in | ||
| 416 | +# the documentation of the scope in which they are defined (i.e. file, | ||
| 417 | +# namespace, or group documentation), provided this scope is documented. If set | ||
| 418 | +# to NO, structs, classes, and unions are shown on a separate page (for HTML and | ||
| 419 | +# Man pages) or section (for LaTeX and RTF). | ||
| 420 | +# The default value is: NO. | ||
| 421 | + | ||
| 422 | +INLINE_SIMPLE_STRUCTS = NO | ||
| 423 | + | ||
| 424 | +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or | ||
| 425 | +# enum is documented as struct, union, or enum with the name of the typedef. So | ||
| 426 | +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct | ||
| 427 | +# with name TypeT. When disabled the typedef will appear as a member of a file, | ||
| 428 | +# namespace, or class. And the struct will be named TypeS. This can typically be | ||
| 429 | +# useful for C code in case the coding convention dictates that all compound | ||
| 430 | +# types are typedef'ed and only the typedef is referenced, never the tag name. | ||
| 431 | +# The default value is: NO. | ||
| 432 | + | ||
| 433 | +TYPEDEF_HIDES_STRUCT = NO | ||
| 434 | + | ||
| 435 | +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This | ||
| 436 | +# cache is used to resolve symbols given their name and scope. Since this can be | ||
| 437 | +# an expensive process and often the same symbol appears multiple times in the | ||
| 438 | +# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small | ||
| 439 | +# doxygen will become slower. If the cache is too large, memory is wasted. The | ||
| 440 | +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range | ||
| 441 | +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 | ||
| 442 | +# symbols. At the end of a run doxygen will report the cache usage and suggest | ||
| 443 | +# the optimal cache size from a speed point of view. | ||
| 444 | +# Minimum value: 0, maximum value: 9, default value: 0. | ||
| 445 | + | ||
| 446 | +LOOKUP_CACHE_SIZE = 0 | ||
| 447 | + | ||
| 448 | +#--------------------------------------------------------------------------- | ||
| 449 | +# Build related configuration options | ||
| 450 | +#--------------------------------------------------------------------------- | ||
| 451 | + | ||
| 452 | +# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in | ||
| 453 | +# documentation are documented, even if no documentation was available. Private | ||
| 454 | +# class members and static file members will be hidden unless the | ||
| 455 | +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. | ||
| 456 | +# Note: This will also disable the warnings about undocumented members that are | ||
| 457 | +# normally produced when WARNINGS is set to YES. | ||
| 458 | +# The default value is: NO. | ||
| 459 | + | ||
| 460 | +EXTRACT_ALL = YES | ||
| 461 | + | ||
| 462 | +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will | ||
| 463 | +# be included in the documentation. | ||
| 464 | +# The default value is: NO. | ||
| 465 | + | ||
| 466 | +EXTRACT_PRIVATE = NO | ||
| 467 | + | ||
| 468 | +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal | ||
| 469 | +# scope will be included in the documentation. | ||
| 470 | +# The default value is: NO. | ||
| 471 | + | ||
| 472 | +EXTRACT_PACKAGE = NO | ||
| 473 | + | ||
| 474 | +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be | ||
| 475 | +# included in the documentation. | ||
| 476 | +# The default value is: NO. | ||
| 477 | + | ||
| 478 | +EXTRACT_STATIC = NO | ||
| 479 | + | ||
| 480 | +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined | ||
| 481 | +# locally in source files will be included in the documentation. If set to NO, | ||
| 482 | +# only classes defined in header files are included. Does not have any effect | ||
| 483 | +# for Java sources. | ||
| 484 | +# The default value is: YES. | ||
| 485 | + | ||
| 486 | +EXTRACT_LOCAL_CLASSES = YES | ||
| 487 | + | ||
| 488 | +# This flag is only useful for Objective-C code. If set to YES, local methods, | ||
| 489 | +# which are defined in the implementation section but not in the interface are | ||
| 490 | +# included in the documentation. If set to NO, only methods in the interface are | ||
| 491 | +# included. | ||
| 492 | +# The default value is: NO. | ||
| 493 | + | ||
| 494 | +EXTRACT_LOCAL_METHODS = NO | ||
| 495 | + | ||
| 496 | +# If this flag is set to YES, the members of anonymous namespaces will be | ||
| 497 | +# extracted and appear in the documentation as a namespace called | ||
| 498 | +# 'anonymous_namespace{file}', where file will be replaced with the base name of | ||
| 499 | +# the file that contains the anonymous namespace. By default anonymous namespace | ||
| 500 | +# are hidden. | ||
| 501 | +# The default value is: NO. | ||
| 502 | + | ||
| 503 | +EXTRACT_ANON_NSPACES = NO | ||
| 504 | + | ||
| 505 | +# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all | ||
| 506 | +# undocumented members inside documented classes or files. If set to NO these | ||
| 507 | +# members will be included in the various overviews, but no documentation | ||
| 508 | +# section is generated. This option has no effect if EXTRACT_ALL is enabled. | ||
| 509 | +# The default value is: NO. | ||
| 510 | + | ||
| 511 | +HIDE_UNDOC_MEMBERS = NO | ||
| 512 | + | ||
| 513 | +# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all | ||
| 514 | +# undocumented classes that are normally visible in the class hierarchy. If set | ||
| 515 | +# to NO, these classes will be included in the various overviews. This option | ||
| 516 | +# has no effect if EXTRACT_ALL is enabled. | ||
| 517 | +# The default value is: NO. | ||
| 518 | + | ||
| 519 | +HIDE_UNDOC_CLASSES = NO | ||
| 520 | + | ||
| 521 | +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend | ||
| 522 | +# (class|struct|union) declarations. If set to NO, these declarations will be | ||
| 523 | +# included in the documentation. | ||
| 524 | +# The default value is: NO. | ||
| 525 | + | ||
| 526 | +HIDE_FRIEND_COMPOUNDS = NO | ||
| 527 | + | ||
| 528 | +# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any | ||
| 529 | +# documentation blocks found inside the body of a function. If set to NO, these | ||
| 530 | +# blocks will be appended to the function's detailed documentation block. | ||
| 531 | +# The default value is: NO. | ||
| 532 | + | ||
| 533 | +HIDE_IN_BODY_DOCS = NO | ||
| 534 | + | ||
| 535 | +# The INTERNAL_DOCS tag determines if documentation that is typed after a | ||
| 536 | +# \internal command is included. If the tag is set to NO then the documentation | ||
| 537 | +# will be excluded. Set it to YES to include the internal documentation. | ||
| 538 | +# The default value is: NO. | ||
| 539 | + | ||
| 540 | +INTERNAL_DOCS = NO | ||
| 541 | + | ||
| 542 | +# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file | ||
| 543 | +# names in lower-case letters. If set to YES, upper-case letters are also | ||
| 544 | +# allowed. This is useful if you have classes or files whose names only differ | ||
| 545 | +# in case and if your file system supports case sensitive file names. Windows | ||
| 546 | +# and Mac users are advised to set this option to NO. | ||
| 547 | +# The default value is: system dependent. | ||
| 548 | + | ||
| 549 | +CASE_SENSE_NAMES = NO | ||
| 550 | + | ||
| 551 | +# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with | ||
| 552 | +# their full class and namespace scopes in the documentation. If set to YES, the | ||
| 553 | +# scope will be hidden. | ||
| 554 | +# The default value is: NO. | ||
| 555 | + | ||
| 556 | +HIDE_SCOPE_NAMES = NO | ||
| 557 | + | ||
| 558 | +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will | ||
| 559 | +# append additional text to a page's title, such as Class Reference. If set to | ||
| 560 | +# YES the compound reference will be hidden. | ||
| 561 | +# The default value is: NO. | ||
| 562 | + | ||
| 563 | +HIDE_COMPOUND_REFERENCE= NO | ||
| 564 | + | ||
| 565 | +# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of | ||
| 566 | +# the files that are included by a file in the documentation of that file. | ||
| 567 | +# The default value is: YES. | ||
| 568 | + | ||
| 569 | +SHOW_INCLUDE_FILES = YES | ||
| 570 | + | ||
| 571 | +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each | ||
| 572 | +# grouped member an include statement to the documentation, telling the reader | ||
| 573 | +# which file to include in order to use the member. | ||
| 574 | +# The default value is: NO. | ||
| 575 | + | ||
| 576 | +SHOW_GROUPED_MEMB_INC = NO | ||
| 577 | + | ||
| 578 | +# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include | ||
| 579 | +# files with double quotes in the documentation rather than with sharp brackets. | ||
| 580 | +# The default value is: NO. | ||
| 581 | + | ||
| 582 | +FORCE_LOCAL_INCLUDES = NO | ||
| 583 | + | ||
| 584 | +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the | ||
| 585 | +# documentation for inline members. | ||
| 586 | +# The default value is: YES. | ||
| 587 | + | ||
| 588 | +INLINE_INFO = YES | ||
| 589 | + | ||
| 590 | +# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the | ||
| 591 | +# (detailed) documentation of file and class members alphabetically by member | ||
| 592 | +# name. If set to NO, the members will appear in declaration order. | ||
| 593 | +# The default value is: YES. | ||
| 594 | + | ||
| 595 | +SORT_MEMBER_DOCS = YES | ||
| 596 | + | ||
| 597 | +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief | ||
| 598 | +# descriptions of file, namespace and class members alphabetically by member | ||
| 599 | +# name. If set to NO, the members will appear in declaration order. Note that | ||
| 600 | +# this will also influence the order of the classes in the class list. | ||
| 601 | +# The default value is: NO. | ||
| 602 | + | ||
| 603 | +SORT_BRIEF_DOCS = NO | ||
| 604 | + | ||
| 605 | +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the | ||
| 606 | +# (brief and detailed) documentation of class members so that constructors and | ||
| 607 | +# destructors are listed first. If set to NO the constructors will appear in the | ||
| 608 | +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. | ||
| 609 | +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief | ||
| 610 | +# member documentation. | ||
| 611 | +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting | ||
| 612 | +# detailed member documentation. | ||
| 613 | +# The default value is: NO. | ||
| 614 | + | ||
| 615 | +SORT_MEMBERS_CTORS_1ST = NO | ||
| 616 | + | ||
| 617 | +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy | ||
| 618 | +# of group names into alphabetical order. If set to NO the group names will | ||
| 619 | +# appear in their defined order. | ||
| 620 | +# The default value is: NO. | ||
| 621 | + | ||
| 622 | +SORT_GROUP_NAMES = NO | ||
| 623 | + | ||
| 624 | +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by | ||
| 625 | +# fully-qualified names, including namespaces. If set to NO, the class list will | ||
| 626 | +# be sorted only by class name, not including the namespace part. | ||
| 627 | +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. | ||
| 628 | +# Note: This option applies only to the class list, not to the alphabetical | ||
| 629 | +# list. | ||
| 630 | +# The default value is: NO. | ||
| 631 | + | ||
| 632 | +SORT_BY_SCOPE_NAME = NO | ||
| 633 | + | ||
| 634 | +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper | ||
| 635 | +# type resolution of all parameters of a function it will reject a match between | ||
| 636 | +# the prototype and the implementation of a member function even if there is | ||
| 637 | +# only one candidate or it is obvious which candidate to choose by doing a | ||
| 638 | +# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still | ||
| 639 | +# accept a match between prototype and implementation in such cases. | ||
| 640 | +# The default value is: NO. | ||
| 641 | + | ||
| 642 | +STRICT_PROTO_MATCHING = NO | ||
| 643 | + | ||
| 644 | +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo | ||
| 645 | +# list. This list is created by putting \todo commands in the documentation. | ||
| 646 | +# The default value is: YES. | ||
| 647 | + | ||
| 648 | +GENERATE_TODOLIST = YES | ||
| 649 | + | ||
| 650 | +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test | ||
| 651 | +# list. This list is created by putting \test commands in the documentation. | ||
| 652 | +# The default value is: YES. | ||
| 653 | + | ||
| 654 | +GENERATE_TESTLIST = YES | ||
| 655 | + | ||
| 656 | +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug | ||
| 657 | +# list. This list is created by putting \bug commands in the documentation. | ||
| 658 | +# The default value is: YES. | ||
| 659 | + | ||
| 660 | +GENERATE_BUGLIST = YES | ||
| 661 | + | ||
| 662 | +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) | ||
| 663 | +# the deprecated list. This list is created by putting \deprecated commands in | ||
| 664 | +# the documentation. | ||
| 665 | +# The default value is: YES. | ||
| 666 | + | ||
| 667 | +GENERATE_DEPRECATEDLIST= YES | ||
| 668 | + | ||
| 669 | +# The ENABLED_SECTIONS tag can be used to enable conditional documentation | ||
| 670 | +# sections, marked by \if <section_label> ... \endif and \cond <section_label> | ||
| 671 | +# ... \endcond blocks. | ||
| 672 | + | ||
| 673 | +ENABLED_SECTIONS = | ||
| 674 | + | ||
| 675 | +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the | ||
| 676 | +# initial value of a variable or macro / define can have for it to appear in the | ||
| 677 | +# documentation. If the initializer consists of more lines than specified here | ||
| 678 | +# it will be hidden. Use a value of 0 to hide initializers completely. The | ||
| 679 | +# appearance of the value of individual variables and macros / defines can be | ||
| 680 | +# controlled using \showinitializer or \hideinitializer command in the | ||
| 681 | +# documentation regardless of this setting. | ||
| 682 | +# Minimum value: 0, maximum value: 10000, default value: 30. | ||
| 683 | + | ||
| 684 | +MAX_INITIALIZER_LINES = 30 | ||
| 685 | + | ||
| 686 | +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at | ||
| 687 | +# the bottom of the documentation of classes and structs. If set to YES, the | ||
| 688 | +# list will mention the files that were used to generate the documentation. | ||
| 689 | +# The default value is: YES. | ||
| 690 | + | ||
| 691 | +SHOW_USED_FILES = YES | ||
| 692 | + | ||
| 693 | +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This | ||
| 694 | +# will remove the Files entry from the Quick Index and from the Folder Tree View | ||
| 695 | +# (if specified). | ||
| 696 | +# The default value is: YES. | ||
| 697 | + | ||
| 698 | +SHOW_FILES = YES | ||
| 699 | + | ||
| 700 | +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces | ||
| 701 | +# page. This will remove the Namespaces entry from the Quick Index and from the | ||
| 702 | +# Folder Tree View (if specified). | ||
| 703 | +# The default value is: YES. | ||
| 704 | + | ||
| 705 | +SHOW_NAMESPACES = YES | ||
| 706 | + | ||
| 707 | +# The FILE_VERSION_FILTER tag can be used to specify a program or script that | ||
| 708 | +# doxygen should invoke to get the current version for each file (typically from | ||
| 709 | +# the version control system). Doxygen will invoke the program by executing (via | ||
| 710 | +# popen()) the command command input-file, where command is the value of the | ||
| 711 | +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided | ||
| 712 | +# by doxygen. Whatever the program writes to standard output is used as the file | ||
| 713 | +# version. For an example see the documentation. | ||
| 714 | + | ||
| 715 | +FILE_VERSION_FILTER = | ||
| 716 | + | ||
| 717 | +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed | ||
| 718 | +# by doxygen. The layout file controls the global structure of the generated | ||
| 719 | +# output files in an output format independent way. To create the layout file | ||
| 720 | +# that represents doxygen's defaults, run doxygen with the -l option. You can | ||
| 721 | +# optionally specify a file name after the option, if omitted DoxygenLayout.xml | ||
| 722 | +# will be used as the name of the layout file. | ||
| 723 | +# | ||
| 724 | +# Note that if you run doxygen from a directory containing a file called | ||
| 725 | +# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE | ||
| 726 | +# tag is left empty. | ||
| 727 | + | ||
| 728 | +LAYOUT_FILE = | ||
| 729 | + | ||
| 730 | +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing | ||
| 731 | +# the reference definitions. This must be a list of .bib files. The .bib | ||
| 732 | +# extension is automatically appended if omitted. This requires the bibtex tool | ||
| 733 | +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. | ||
| 734 | +# For LaTeX the style of the bibliography can be controlled using | ||
| 735 | +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the | ||
| 736 | +# search path. See also \cite for info how to create references. | ||
| 737 | + | ||
| 738 | +CITE_BIB_FILES = | ||
| 739 | + | ||
| 740 | +#--------------------------------------------------------------------------- | ||
| 741 | +# Configuration options related to warning and progress messages | ||
| 742 | +#--------------------------------------------------------------------------- | ||
| 743 | + | ||
| 744 | +# The QUIET tag can be used to turn on/off the messages that are generated to | ||
| 745 | +# standard output by doxygen. If QUIET is set to YES this implies that the | ||
| 746 | +# messages are off. | ||
| 747 | +# The default value is: NO. | ||
| 748 | + | ||
| 749 | +QUIET = NO | ||
| 750 | + | ||
| 751 | +# The WARNINGS tag can be used to turn on/off the warning messages that are | ||
| 752 | +# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES | ||
| 753 | +# this implies that the warnings are on. | ||
| 754 | +# | ||
| 755 | +# Tip: Turn warnings on while writing the documentation. | ||
| 756 | +# The default value is: YES. | ||
| 757 | + | ||
| 758 | +WARNINGS = YES | ||
| 759 | + | ||
| 760 | +# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate | ||
| 761 | +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag | ||
| 762 | +# will automatically be disabled. | ||
| 763 | +# The default value is: YES. | ||
| 764 | + | ||
| 765 | +WARN_IF_UNDOCUMENTED = YES | ||
| 766 | + | ||
| 767 | +# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for | ||
| 768 | +# potential errors in the documentation, such as not documenting some parameters | ||
| 769 | +# in a documented function, or documenting parameters that don't exist or using | ||
| 770 | +# markup commands wrongly. | ||
| 771 | +# The default value is: YES. | ||
| 772 | + | ||
| 773 | +WARN_IF_DOC_ERROR = YES | ||
| 774 | + | ||
| 775 | +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that | ||
| 776 | +# are documented, but have no documentation for their parameters or return | ||
| 777 | +# value. If set to NO, doxygen will only warn about wrong or incomplete | ||
| 778 | +# parameter documentation, but not about the absence of documentation. If | ||
| 779 | +# EXTRACT_ALL is set to YES then this flag will automatically be disabled. | ||
| 780 | +# The default value is: NO. | ||
| 781 | + | ||
| 782 | +WARN_NO_PARAMDOC = NO | ||
| 783 | + | ||
| 784 | +# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when | ||
| 785 | +# a warning is encountered. | ||
| 786 | +# The default value is: NO. | ||
| 787 | + | ||
| 788 | +WARN_AS_ERROR = NO | ||
| 789 | + | ||
| 790 | +# The WARN_FORMAT tag determines the format of the warning messages that doxygen | ||
| 791 | +# can produce. The string should contain the $file, $line, and $text tags, which | ||
| 792 | +# will be replaced by the file and line number from which the warning originated | ||
| 793 | +# and the warning text. Optionally the format may contain $version, which will | ||
| 794 | +# be replaced by the version of the file (if it could be obtained via | ||
| 795 | +# FILE_VERSION_FILTER) | ||
| 796 | +# The default value is: $file:$line: $text. | ||
| 797 | + | ||
| 798 | +WARN_FORMAT = "$file:$line: $text" | ||
| 799 | + | ||
| 800 | +# The WARN_LOGFILE tag can be used to specify a file to which warning and error | ||
| 801 | +# messages should be written. If left blank the output is written to standard | ||
| 802 | +# error (stderr). | ||
| 803 | + | ||
| 804 | +WARN_LOGFILE = | ||
| 805 | + | ||
| 806 | +#--------------------------------------------------------------------------- | ||
| 807 | +# Configuration options related to the input files | ||
| 808 | +#--------------------------------------------------------------------------- | ||
| 809 | + | ||
| 810 | +# The INPUT tag is used to specify the files and/or directories that contain | ||
| 811 | +# documented source files. You may enter file names like myfile.cpp or | ||
| 812 | +# directories like /usr/src/myproject. Separate the files or directories with | ||
| 813 | +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING | ||
| 814 | +# Note: If this tag is empty the current directory is searched. | ||
| 815 | + | ||
| 816 | +INPUT = /home/pgroen/projects/osdev_components/mqtt | ||
| 817 | + | ||
| 818 | +# This tag can be used to specify the character encoding of the source files | ||
| 819 | +# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses | ||
| 820 | +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv | ||
| 821 | +# documentation (see: https://www.gnu.org/software/libiconv/) for the list of | ||
| 822 | +# possible encodings. | ||
| 823 | +# The default value is: UTF-8. | ||
| 824 | + | ||
| 825 | +INPUT_ENCODING = UTF-8 | ||
| 826 | + | ||
| 827 | +# If the value of the INPUT tag contains directories, you can use the | ||
| 828 | +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and | ||
| 829 | +# *.h) to filter out the source-files in the directories. | ||
| 830 | +# | ||
| 831 | +# Note that for custom extensions or not directly supported extensions you also | ||
| 832 | +# need to set EXTENSION_MAPPING for the extension otherwise the files are not | ||
| 833 | +# read by doxygen. | ||
| 834 | +# | ||
| 835 | +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, | ||
| 836 | +# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, | ||
| 837 | +# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, | ||
| 838 | +# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, | ||
| 839 | +# *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice. | ||
| 840 | + | ||
| 841 | +FILE_PATTERNS = *.c \ | ||
| 842 | + *.cc \ | ||
| 843 | + *.cxx \ | ||
| 844 | + *.cpp \ | ||
| 845 | + *.c++ \ | ||
| 846 | + *.java \ | ||
| 847 | + *.ii \ | ||
| 848 | + *.ixx \ | ||
| 849 | + *.ipp \ | ||
| 850 | + *.i++ \ | ||
| 851 | + *.inl \ | ||
| 852 | + *.idl \ | ||
| 853 | + *.ddl \ | ||
| 854 | + *.odl \ | ||
| 855 | + *.h \ | ||
| 856 | + *.hh \ | ||
| 857 | + *.hxx \ | ||
| 858 | + *.hpp \ | ||
| 859 | + *.h++ \ | ||
| 860 | + *.cs \ | ||
| 861 | + *.d \ | ||
| 862 | + *.php \ | ||
| 863 | + *.php4 \ | ||
| 864 | + *.php5 \ | ||
| 865 | + *.phtml \ | ||
| 866 | + *.inc \ | ||
| 867 | + *.m \ | ||
| 868 | + *.markdown \ | ||
| 869 | + *.md \ | ||
| 870 | + *.mm \ | ||
| 871 | + *.dox \ | ||
| 872 | + *.py \ | ||
| 873 | + *.pyw \ | ||
| 874 | + *.f90 \ | ||
| 875 | + *.f95 \ | ||
| 876 | + *.f03 \ | ||
| 877 | + *.f08 \ | ||
| 878 | + *.f \ | ||
| 879 | + *.for \ | ||
| 880 | + *.tcl \ | ||
| 881 | + *.vhd \ | ||
| 882 | + *.vhdl \ | ||
| 883 | + *.ucf \ | ||
| 884 | + *.qsf \ | ||
| 885 | + *.ice | ||
| 886 | + | ||
| 887 | +# The RECURSIVE tag can be used to specify whether or not subdirectories should | ||
| 888 | +# be searched for input files as well. | ||
| 889 | +# The default value is: NO. | ||
| 890 | + | ||
| 891 | +RECURSIVE = NO | ||
| 892 | + | ||
| 893 | +# The EXCLUDE tag can be used to specify files and/or directories that should be | ||
| 894 | +# excluded from the INPUT source files. This way you can easily exclude a | ||
| 895 | +# subdirectory from a directory tree whose root is specified with the INPUT tag. | ||
| 896 | +# | ||
| 897 | +# Note that relative paths are relative to the directory from which doxygen is | ||
| 898 | +# run. | ||
| 899 | + | ||
| 900 | +EXCLUDE = | ||
| 901 | + | ||
| 902 | +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or | ||
| 903 | +# directories that are symbolic links (a Unix file system feature) are excluded | ||
| 904 | +# from the input. | ||
| 905 | +# The default value is: NO. | ||
| 906 | + | ||
| 907 | +EXCLUDE_SYMLINKS = NO | ||
| 908 | + | ||
| 909 | +# If the value of the INPUT tag contains directories, you can use the | ||
| 910 | +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude | ||
| 911 | +# certain files from those directories. | ||
| 912 | +# | ||
| 913 | +# Note that the wildcards are matched against the file with absolute path, so to | ||
| 914 | +# exclude all test directories for example use the pattern */test/* | ||
| 915 | + | ||
| 916 | +EXCLUDE_PATTERNS = | ||
| 917 | + | ||
| 918 | +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names | ||
| 919 | +# (namespaces, classes, functions, etc.) that should be excluded from the | ||
| 920 | +# output. The symbol name can be a fully qualified name, a word, or if the | ||
| 921 | +# wildcard * is used, a substring. Examples: ANamespace, AClass, | ||
| 922 | +# AClass::ANamespace, ANamespace::*Test | ||
| 923 | +# | ||
| 924 | +# Note that the wildcards are matched against the file with absolute path, so to | ||
| 925 | +# exclude all test directories use the pattern */test/* | ||
| 926 | + | ||
| 927 | +EXCLUDE_SYMBOLS = | ||
| 928 | + | ||
| 929 | +# The EXAMPLE_PATH tag can be used to specify one or more files or directories | ||
| 930 | +# that contain example code fragments that are included (see the \include | ||
| 931 | +# command). | ||
| 932 | + | ||
| 933 | +EXAMPLE_PATH = | ||
| 934 | + | ||
| 935 | +# If the value of the EXAMPLE_PATH tag contains directories, you can use the | ||
| 936 | +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and | ||
| 937 | +# *.h) to filter out the source-files in the directories. If left blank all | ||
| 938 | +# files are included. | ||
| 939 | + | ||
| 940 | +EXAMPLE_PATTERNS = * | ||
| 941 | + | ||
| 942 | +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be | ||
| 943 | +# searched for input files to be used with the \include or \dontinclude commands | ||
| 944 | +# irrespective of the value of the RECURSIVE tag. | ||
| 945 | +# The default value is: NO. | ||
| 946 | + | ||
| 947 | +EXAMPLE_RECURSIVE = NO | ||
| 948 | + | ||
| 949 | +# The IMAGE_PATH tag can be used to specify one or more files or directories | ||
| 950 | +# that contain images that are to be included in the documentation (see the | ||
| 951 | +# \image command). | ||
| 952 | + | ||
| 953 | +IMAGE_PATH = | ||
| 954 | + | ||
| 955 | +# The INPUT_FILTER tag can be used to specify a program that doxygen should | ||
| 956 | +# invoke to filter for each input file. Doxygen will invoke the filter program | ||
| 957 | +# by executing (via popen()) the command: | ||
| 958 | +# | ||
| 959 | +# <filter> <input-file> | ||
| 960 | +# | ||
| 961 | +# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the | ||
| 962 | +# name of an input file. Doxygen will then use the output that the filter | ||
| 963 | +# program writes to standard output. If FILTER_PATTERNS is specified, this tag | ||
| 964 | +# will be ignored. | ||
| 965 | +# | ||
| 966 | +# Note that the filter must not add or remove lines; it is applied before the | ||
| 967 | +# code is scanned, but not when the output code is generated. If lines are added | ||
| 968 | +# or removed, the anchors will not be placed correctly. | ||
| 969 | +# | ||
| 970 | +# Note that for custom extensions or not directly supported extensions you also | ||
| 971 | +# need to set EXTENSION_MAPPING for the extension otherwise the files are not | ||
| 972 | +# properly processed by doxygen. | ||
| 973 | + | ||
| 974 | +INPUT_FILTER = | ||
| 975 | + | ||
| 976 | +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern | ||
| 977 | +# basis. Doxygen will compare the file name with each pattern and apply the | ||
| 978 | +# filter if there is a match. The filters are a list of the form: pattern=filter | ||
| 979 | +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how | ||
| 980 | +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the | ||
| 981 | +# patterns match the file name, INPUT_FILTER is applied. | ||
| 982 | +# | ||
| 983 | +# Note that for custom extensions or not directly supported extensions you also | ||
| 984 | +# need to set EXTENSION_MAPPING for the extension otherwise the files are not | ||
| 985 | +# properly processed by doxygen. | ||
| 986 | + | ||
| 987 | +FILTER_PATTERNS = | ||
| 988 | + | ||
| 989 | +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using | ||
| 990 | +# INPUT_FILTER) will also be used to filter the input files that are used for | ||
| 991 | +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). | ||
| 992 | +# The default value is: NO. | ||
| 993 | + | ||
| 994 | +FILTER_SOURCE_FILES = NO | ||
| 995 | + | ||
| 996 | +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file | ||
| 997 | +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and | ||
| 998 | +# it is also possible to disable source filtering for a specific pattern using | ||
| 999 | +# *.ext= (so without naming a filter). | ||
| 1000 | +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. | ||
| 1001 | + | ||
| 1002 | +FILTER_SOURCE_PATTERNS = | ||
| 1003 | + | ||
| 1004 | +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that | ||
| 1005 | +# is part of the input, its contents will be placed on the main page | ||
| 1006 | +# (index.html). This can be useful if you have a project on for instance GitHub | ||
| 1007 | +# and want to reuse the introduction page also for the doxygen output. | ||
| 1008 | + | ||
| 1009 | +USE_MDFILE_AS_MAINPAGE = | ||
| 1010 | + | ||
| 1011 | +#--------------------------------------------------------------------------- | ||
| 1012 | +# Configuration options related to source browsing | ||
| 1013 | +#--------------------------------------------------------------------------- | ||
| 1014 | + | ||
| 1015 | +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be | ||
| 1016 | +# generated. Documented entities will be cross-referenced with these sources. | ||
| 1017 | +# | ||
| 1018 | +# Note: To get rid of all source code in the generated output, make sure that | ||
| 1019 | +# also VERBATIM_HEADERS is set to NO. | ||
| 1020 | +# The default value is: NO. | ||
| 1021 | + | ||
| 1022 | +SOURCE_BROWSER = NO | ||
| 1023 | + | ||
| 1024 | +# Setting the INLINE_SOURCES tag to YES will include the body of functions, | ||
| 1025 | +# classes and enums directly into the documentation. | ||
| 1026 | +# The default value is: NO. | ||
| 1027 | + | ||
| 1028 | +INLINE_SOURCES = NO | ||
| 1029 | + | ||
| 1030 | +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any | ||
| 1031 | +# special comment blocks from generated source code fragments. Normal C, C++ and | ||
| 1032 | +# Fortran comments will always remain visible. | ||
| 1033 | +# The default value is: YES. | ||
| 1034 | + | ||
| 1035 | +STRIP_CODE_COMMENTS = YES | ||
| 1036 | + | ||
| 1037 | +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented | ||
| 1038 | +# entity all documented functions referencing it will be listed. | ||
| 1039 | +# The default value is: NO. | ||
| 1040 | + | ||
| 1041 | +REFERENCED_BY_RELATION = NO | ||
| 1042 | + | ||
| 1043 | +# If the REFERENCES_RELATION tag is set to YES then for each documented function | ||
| 1044 | +# all documented entities called/used by that function will be listed. | ||
| 1045 | +# The default value is: NO. | ||
| 1046 | + | ||
| 1047 | +REFERENCES_RELATION = NO | ||
| 1048 | + | ||
| 1049 | +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set | ||
| 1050 | +# to YES then the hyperlinks from functions in REFERENCES_RELATION and | ||
| 1051 | +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will | ||
| 1052 | +# link to the documentation. | ||
| 1053 | +# The default value is: YES. | ||
| 1054 | + | ||
| 1055 | +REFERENCES_LINK_SOURCE = YES | ||
| 1056 | + | ||
| 1057 | +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the | ||
| 1058 | +# source code will show a tooltip with additional information such as prototype, | ||
| 1059 | +# brief description and links to the definition and documentation. Since this | ||
| 1060 | +# will make the HTML file larger and loading of large files a bit slower, you | ||
| 1061 | +# can opt to disable this feature. | ||
| 1062 | +# The default value is: YES. | ||
| 1063 | +# This tag requires that the tag SOURCE_BROWSER is set to YES. | ||
| 1064 | + | ||
| 1065 | +SOURCE_TOOLTIPS = YES | ||
| 1066 | + | ||
| 1067 | +# If the USE_HTAGS tag is set to YES then the references to source code will | ||
| 1068 | +# point to the HTML generated by the htags(1) tool instead of doxygen built-in | ||
| 1069 | +# source browser. The htags tool is part of GNU's global source tagging system | ||
| 1070 | +# (see https://www.gnu.org/software/global/global.html). You will need version | ||
| 1071 | +# 4.8.6 or higher. | ||
| 1072 | +# | ||
| 1073 | +# To use it do the following: | ||
| 1074 | +# - Install the latest version of global | ||
| 1075 | +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file | ||
| 1076 | +# - Make sure the INPUT points to the root of the source tree | ||
| 1077 | +# - Run doxygen as normal | ||
| 1078 | +# | ||
| 1079 | +# Doxygen will invoke htags (and that will in turn invoke gtags), so these | ||
| 1080 | +# tools must be available from the command line (i.e. in the search path). | ||
| 1081 | +# | ||
| 1082 | +# The result: instead of the source browser generated by doxygen, the links to | ||
| 1083 | +# source code will now point to the output of htags. | ||
| 1084 | +# The default value is: NO. | ||
| 1085 | +# This tag requires that the tag SOURCE_BROWSER is set to YES. | ||
| 1086 | + | ||
| 1087 | +USE_HTAGS = NO | ||
| 1088 | + | ||
| 1089 | +# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a | ||
| 1090 | +# verbatim copy of the header file for each class for which an include is | ||
| 1091 | +# specified. Set to NO to disable this. | ||
| 1092 | +# See also: Section \class. | ||
| 1093 | +# The default value is: YES. | ||
| 1094 | + | ||
| 1095 | +VERBATIM_HEADERS = YES | ||
| 1096 | + | ||
| 1097 | +#--------------------------------------------------------------------------- | ||
| 1098 | +# Configuration options related to the alphabetical class index | ||
| 1099 | +#--------------------------------------------------------------------------- | ||
| 1100 | + | ||
| 1101 | +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all | ||
| 1102 | +# compounds will be generated. Enable this if the project contains a lot of | ||
| 1103 | +# classes, structs, unions or interfaces. | ||
| 1104 | +# The default value is: YES. | ||
| 1105 | + | ||
| 1106 | +ALPHABETICAL_INDEX = YES | ||
| 1107 | + | ||
| 1108 | +# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in | ||
| 1109 | +# which the alphabetical index list will be split. | ||
| 1110 | +# Minimum value: 1, maximum value: 20, default value: 5. | ||
| 1111 | +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. | ||
| 1112 | + | ||
| 1113 | +COLS_IN_ALPHA_INDEX = 5 | ||
| 1114 | + | ||
| 1115 | +# In case all classes in a project start with a common prefix, all classes will | ||
| 1116 | +# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag | ||
| 1117 | +# can be used to specify a prefix (or a list of prefixes) that should be ignored | ||
| 1118 | +# while generating the index headers. | ||
| 1119 | +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. | ||
| 1120 | + | ||
| 1121 | +IGNORE_PREFIX = | ||
| 1122 | + | ||
| 1123 | +#--------------------------------------------------------------------------- | ||
| 1124 | +# Configuration options related to the HTML output | ||
| 1125 | +#--------------------------------------------------------------------------- | ||
| 1126 | + | ||
| 1127 | +# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output | ||
| 1128 | +# The default value is: YES. | ||
| 1129 | + | ||
| 1130 | +GENERATE_HTML = YES | ||
| 1131 | + | ||
| 1132 | +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a | ||
| 1133 | +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of | ||
| 1134 | +# it. | ||
| 1135 | +# The default directory is: html. | ||
| 1136 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1137 | + | ||
| 1138 | +HTML_OUTPUT = html | ||
| 1139 | + | ||
| 1140 | +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each | ||
| 1141 | +# generated HTML page (for example: .htm, .php, .asp). | ||
| 1142 | +# The default value is: .html. | ||
| 1143 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1144 | + | ||
| 1145 | +HTML_FILE_EXTENSION = .html | ||
| 1146 | + | ||
| 1147 | +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for | ||
| 1148 | +# each generated HTML page. If the tag is left blank doxygen will generate a | ||
| 1149 | +# standard header. | ||
| 1150 | +# | ||
| 1151 | +# To get valid HTML the header file that includes any scripts and style sheets | ||
| 1152 | +# that doxygen needs, which is dependent on the configuration options used (e.g. | ||
| 1153 | +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a | ||
| 1154 | +# default header using | ||
| 1155 | +# doxygen -w html new_header.html new_footer.html new_stylesheet.css | ||
| 1156 | +# YourConfigFile | ||
| 1157 | +# and then modify the file new_header.html. See also section "Doxygen usage" | ||
| 1158 | +# for information on how to generate the default header that doxygen normally | ||
| 1159 | +# uses. | ||
| 1160 | +# Note: The header is subject to change so you typically have to regenerate the | ||
| 1161 | +# default header when upgrading to a newer version of doxygen. For a description | ||
| 1162 | +# of the possible markers and block names see the documentation. | ||
| 1163 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1164 | + | ||
| 1165 | +HTML_HEADER = | ||
| 1166 | + | ||
| 1167 | +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each | ||
| 1168 | +# generated HTML page. If the tag is left blank doxygen will generate a standard | ||
| 1169 | +# footer. See HTML_HEADER for more information on how to generate a default | ||
| 1170 | +# footer and what special commands can be used inside the footer. See also | ||
| 1171 | +# section "Doxygen usage" for information on how to generate the default footer | ||
| 1172 | +# that doxygen normally uses. | ||
| 1173 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1174 | + | ||
| 1175 | +HTML_FOOTER = | ||
| 1176 | + | ||
| 1177 | +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style | ||
| 1178 | +# sheet that is used by each HTML page. It can be used to fine-tune the look of | ||
| 1179 | +# the HTML output. If left blank doxygen will generate a default style sheet. | ||
| 1180 | +# See also section "Doxygen usage" for information on how to generate the style | ||
| 1181 | +# sheet that doxygen normally uses. | ||
| 1182 | +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as | ||
| 1183 | +# it is more robust and this tag (HTML_STYLESHEET) will in the future become | ||
| 1184 | +# obsolete. | ||
| 1185 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1186 | + | ||
| 1187 | +HTML_STYLESHEET = | ||
| 1188 | + | ||
| 1189 | +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined | ||
| 1190 | +# cascading style sheets that are included after the standard style sheets | ||
| 1191 | +# created by doxygen. Using this option one can overrule certain style aspects. | ||
| 1192 | +# This is preferred over using HTML_STYLESHEET since it does not replace the | ||
| 1193 | +# standard style sheet and is therefore more robust against future updates. | ||
| 1194 | +# Doxygen will copy the style sheet files to the output directory. | ||
| 1195 | +# Note: The order of the extra style sheet files is of importance (e.g. the last | ||
| 1196 | +# style sheet in the list overrules the setting of the previous ones in the | ||
| 1197 | +# list). For an example see the documentation. | ||
| 1198 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1199 | + | ||
| 1200 | +HTML_EXTRA_STYLESHEET = | ||
| 1201 | + | ||
| 1202 | +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or | ||
| 1203 | +# other source files which should be copied to the HTML output directory. Note | ||
| 1204 | +# that these files will be copied to the base HTML output directory. Use the | ||
| 1205 | +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these | ||
| 1206 | +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the | ||
| 1207 | +# files will be copied as-is; there are no commands or markers available. | ||
| 1208 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1209 | + | ||
| 1210 | +HTML_EXTRA_FILES = | ||
| 1211 | + | ||
| 1212 | +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen | ||
| 1213 | +# will adjust the colors in the style sheet and background images according to | ||
| 1214 | +# this color. Hue is specified as an angle on a colorwheel, see | ||
| 1215 | +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value | ||
| 1216 | +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 | ||
| 1217 | +# purple, and 360 is red again. | ||
| 1218 | +# Minimum value: 0, maximum value: 359, default value: 220. | ||
| 1219 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1220 | + | ||
| 1221 | +HTML_COLORSTYLE_HUE = 220 | ||
| 1222 | + | ||
| 1223 | +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors | ||
| 1224 | +# in the HTML output. For a value of 0 the output will use grayscales only. A | ||
| 1225 | +# value of 255 will produce the most vivid colors. | ||
| 1226 | +# Minimum value: 0, maximum value: 255, default value: 100. | ||
| 1227 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1228 | + | ||
| 1229 | +HTML_COLORSTYLE_SAT = 100 | ||
| 1230 | + | ||
| 1231 | +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the | ||
| 1232 | +# luminance component of the colors in the HTML output. Values below 100 | ||
| 1233 | +# gradually make the output lighter, whereas values above 100 make the output | ||
| 1234 | +# darker. The value divided by 100 is the actual gamma applied, so 80 represents | ||
| 1235 | +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not | ||
| 1236 | +# change the gamma. | ||
| 1237 | +# Minimum value: 40, maximum value: 240, default value: 80. | ||
| 1238 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1239 | + | ||
| 1240 | +HTML_COLORSTYLE_GAMMA = 80 | ||
| 1241 | + | ||
| 1242 | +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML | ||
| 1243 | +# page will contain the date and time when the page was generated. Setting this | ||
| 1244 | +# to YES can help to show when doxygen was last run and thus if the | ||
| 1245 | +# documentation is up to date. | ||
| 1246 | +# The default value is: NO. | ||
| 1247 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1248 | + | ||
| 1249 | +HTML_TIMESTAMP = NO | ||
| 1250 | + | ||
| 1251 | +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML | ||
| 1252 | +# documentation will contain a main index with vertical navigation menus that | ||
| 1253 | +# are dynamically created via Javascript. If disabled, the navigation index will | ||
| 1254 | +# consists of multiple levels of tabs that are statically embedded in every HTML | ||
| 1255 | +# page. Disable this option to support browsers that do not have Javascript, | ||
| 1256 | +# like the Qt help browser. | ||
| 1257 | +# The default value is: YES. | ||
| 1258 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1259 | + | ||
| 1260 | +HTML_DYNAMIC_MENUS = YES | ||
| 1261 | + | ||
| 1262 | +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML | ||
| 1263 | +# documentation will contain sections that can be hidden and shown after the | ||
| 1264 | +# page has loaded. | ||
| 1265 | +# The default value is: NO. | ||
| 1266 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1267 | + | ||
| 1268 | +HTML_DYNAMIC_SECTIONS = NO | ||
| 1269 | + | ||
| 1270 | +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries | ||
| 1271 | +# shown in the various tree structured indices initially; the user can expand | ||
| 1272 | +# and collapse entries dynamically later on. Doxygen will expand the tree to | ||
| 1273 | +# such a level that at most the specified number of entries are visible (unless | ||
| 1274 | +# a fully collapsed tree already exceeds this amount). So setting the number of | ||
| 1275 | +# entries 1 will produce a full collapsed tree by default. 0 is a special value | ||
| 1276 | +# representing an infinite number of entries and will result in a full expanded | ||
| 1277 | +# tree by default. | ||
| 1278 | +# Minimum value: 0, maximum value: 9999, default value: 100. | ||
| 1279 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1280 | + | ||
| 1281 | +HTML_INDEX_NUM_ENTRIES = 100 | ||
| 1282 | + | ||
| 1283 | +# If the GENERATE_DOCSET tag is set to YES, additional index files will be | ||
| 1284 | +# generated that can be used as input for Apple's Xcode 3 integrated development | ||
| 1285 | +# environment (see: https://developer.apple.com/xcode/), introduced with OSX | ||
| 1286 | +# 10.5 (Leopard). To create a documentation set, doxygen will generate a | ||
| 1287 | +# Makefile in the HTML output directory. Running make will produce the docset in | ||
| 1288 | +# that directory and running make install will install the docset in | ||
| 1289 | +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at | ||
| 1290 | +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy | ||
| 1291 | +# genXcode/_index.html for more information. | ||
| 1292 | +# The default value is: NO. | ||
| 1293 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1294 | + | ||
| 1295 | +GENERATE_DOCSET = NO | ||
| 1296 | + | ||
| 1297 | +# This tag determines the name of the docset feed. A documentation feed provides | ||
| 1298 | +# an umbrella under which multiple documentation sets from a single provider | ||
| 1299 | +# (such as a company or product suite) can be grouped. | ||
| 1300 | +# The default value is: Doxygen generated docs. | ||
| 1301 | +# This tag requires that the tag GENERATE_DOCSET is set to YES. | ||
| 1302 | + | ||
| 1303 | +DOCSET_FEEDNAME = "Doxygen generated docs" | ||
| 1304 | + | ||
| 1305 | +# This tag specifies a string that should uniquely identify the documentation | ||
| 1306 | +# set bundle. This should be a reverse domain-name style string, e.g. | ||
| 1307 | +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. | ||
| 1308 | +# The default value is: org.doxygen.Project. | ||
| 1309 | +# This tag requires that the tag GENERATE_DOCSET is set to YES. | ||
| 1310 | + | ||
| 1311 | +DOCSET_BUNDLE_ID = org.doxygen.Project | ||
| 1312 | + | ||
| 1313 | +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify | ||
| 1314 | +# the documentation publisher. This should be a reverse domain-name style | ||
| 1315 | +# string, e.g. com.mycompany.MyDocSet.documentation. | ||
| 1316 | +# The default value is: org.doxygen.Publisher. | ||
| 1317 | +# This tag requires that the tag GENERATE_DOCSET is set to YES. | ||
| 1318 | + | ||
| 1319 | +DOCSET_PUBLISHER_ID = org.doxygen.Publisher | ||
| 1320 | + | ||
| 1321 | +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. | ||
| 1322 | +# The default value is: Publisher. | ||
| 1323 | +# This tag requires that the tag GENERATE_DOCSET is set to YES. | ||
| 1324 | + | ||
| 1325 | +DOCSET_PUBLISHER_NAME = Publisher | ||
| 1326 | + | ||
| 1327 | +# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three | ||
| 1328 | +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The | ||
| 1329 | +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop | ||
| 1330 | +# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on | ||
| 1331 | +# Windows. | ||
| 1332 | +# | ||
| 1333 | +# The HTML Help Workshop contains a compiler that can convert all HTML output | ||
| 1334 | +# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML | ||
| 1335 | +# files are now used as the Windows 98 help format, and will replace the old | ||
| 1336 | +# Windows help format (.hlp) on all Windows platforms in the future. Compressed | ||
| 1337 | +# HTML files also contain an index, a table of contents, and you can search for | ||
| 1338 | +# words in the documentation. The HTML workshop also contains a viewer for | ||
| 1339 | +# compressed HTML files. | ||
| 1340 | +# The default value is: NO. | ||
| 1341 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1342 | + | ||
| 1343 | +GENERATE_HTMLHELP = NO | ||
| 1344 | + | ||
| 1345 | +# The CHM_FILE tag can be used to specify the file name of the resulting .chm | ||
| 1346 | +# file. You can add a path in front of the file if the result should not be | ||
| 1347 | +# written to the html output directory. | ||
| 1348 | +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. | ||
| 1349 | + | ||
| 1350 | +CHM_FILE = | ||
| 1351 | + | ||
| 1352 | +# The HHC_LOCATION tag can be used to specify the location (absolute path | ||
| 1353 | +# including file name) of the HTML help compiler (hhc.exe). If non-empty, | ||
| 1354 | +# doxygen will try to run the HTML help compiler on the generated index.hhp. | ||
| 1355 | +# The file has to be specified with full path. | ||
| 1356 | +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. | ||
| 1357 | + | ||
| 1358 | +HHC_LOCATION = | ||
| 1359 | + | ||
| 1360 | +# The GENERATE_CHI flag controls if a separate .chi index file is generated | ||
| 1361 | +# (YES) or that it should be included in the master .chm file (NO). | ||
| 1362 | +# The default value is: NO. | ||
| 1363 | +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. | ||
| 1364 | + | ||
| 1365 | +GENERATE_CHI = NO | ||
| 1366 | + | ||
| 1367 | +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) | ||
| 1368 | +# and project file content. | ||
| 1369 | +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. | ||
| 1370 | + | ||
| 1371 | +CHM_INDEX_ENCODING = | ||
| 1372 | + | ||
| 1373 | +# The BINARY_TOC flag controls whether a binary table of contents is generated | ||
| 1374 | +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it | ||
| 1375 | +# enables the Previous and Next buttons. | ||
| 1376 | +# The default value is: NO. | ||
| 1377 | +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. | ||
| 1378 | + | ||
| 1379 | +BINARY_TOC = NO | ||
| 1380 | + | ||
| 1381 | +# The TOC_EXPAND flag can be set to YES to add extra items for group members to | ||
| 1382 | +# the table of contents of the HTML help documentation and to the tree view. | ||
| 1383 | +# The default value is: NO. | ||
| 1384 | +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. | ||
| 1385 | + | ||
| 1386 | +TOC_EXPAND = NO | ||
| 1387 | + | ||
| 1388 | +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and | ||
| 1389 | +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that | ||
| 1390 | +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help | ||
| 1391 | +# (.qch) of the generated HTML documentation. | ||
| 1392 | +# The default value is: NO. | ||
| 1393 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1394 | + | ||
| 1395 | +GENERATE_QHP = NO | ||
| 1396 | + | ||
| 1397 | +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify | ||
| 1398 | +# the file name of the resulting .qch file. The path specified is relative to | ||
| 1399 | +# the HTML output folder. | ||
| 1400 | +# This tag requires that the tag GENERATE_QHP is set to YES. | ||
| 1401 | + | ||
| 1402 | +QCH_FILE = | ||
| 1403 | + | ||
| 1404 | +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help | ||
| 1405 | +# Project output. For more information please see Qt Help Project / Namespace | ||
| 1406 | +# (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). | ||
| 1407 | +# The default value is: org.doxygen.Project. | ||
| 1408 | +# This tag requires that the tag GENERATE_QHP is set to YES. | ||
| 1409 | + | ||
| 1410 | +QHP_NAMESPACE = org.doxygen.Project | ||
| 1411 | + | ||
| 1412 | +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt | ||
| 1413 | +# Help Project output. For more information please see Qt Help Project / Virtual | ||
| 1414 | +# Folders (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual- | ||
| 1415 | +# folders). | ||
| 1416 | +# The default value is: doc. | ||
| 1417 | +# This tag requires that the tag GENERATE_QHP is set to YES. | ||
| 1418 | + | ||
| 1419 | +QHP_VIRTUAL_FOLDER = doc | ||
| 1420 | + | ||
| 1421 | +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom | ||
| 1422 | +# filter to add. For more information please see Qt Help Project / Custom | ||
| 1423 | +# Filters (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- | ||
| 1424 | +# filters). | ||
| 1425 | +# This tag requires that the tag GENERATE_QHP is set to YES. | ||
| 1426 | + | ||
| 1427 | +QHP_CUST_FILTER_NAME = | ||
| 1428 | + | ||
| 1429 | +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the | ||
| 1430 | +# custom filter to add. For more information please see Qt Help Project / Custom | ||
| 1431 | +# Filters (see: http://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- | ||
| 1432 | +# filters). | ||
| 1433 | +# This tag requires that the tag GENERATE_QHP is set to YES. | ||
| 1434 | + | ||
| 1435 | +QHP_CUST_FILTER_ATTRS = | ||
| 1436 | + | ||
| 1437 | +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this | ||
| 1438 | +# project's filter section matches. Qt Help Project / Filter Attributes (see: | ||
| 1439 | +# http://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). | ||
| 1440 | +# This tag requires that the tag GENERATE_QHP is set to YES. | ||
| 1441 | + | ||
| 1442 | +QHP_SECT_FILTER_ATTRS = | ||
| 1443 | + | ||
| 1444 | +# The QHG_LOCATION tag can be used to specify the location of Qt's | ||
| 1445 | +# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the | ||
| 1446 | +# generated .qhp file. | ||
| 1447 | +# This tag requires that the tag GENERATE_QHP is set to YES. | ||
| 1448 | + | ||
| 1449 | +QHG_LOCATION = | ||
| 1450 | + | ||
| 1451 | +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be | ||
| 1452 | +# generated, together with the HTML files, they form an Eclipse help plugin. To | ||
| 1453 | +# install this plugin and make it available under the help contents menu in | ||
| 1454 | +# Eclipse, the contents of the directory containing the HTML and XML files needs | ||
| 1455 | +# to be copied into the plugins directory of eclipse. The name of the directory | ||
| 1456 | +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. | ||
| 1457 | +# After copying Eclipse needs to be restarted before the help appears. | ||
| 1458 | +# The default value is: NO. | ||
| 1459 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1460 | + | ||
| 1461 | +GENERATE_ECLIPSEHELP = NO | ||
| 1462 | + | ||
| 1463 | +# A unique identifier for the Eclipse help plugin. When installing the plugin | ||
| 1464 | +# the directory name containing the HTML and XML files should also have this | ||
| 1465 | +# name. Each documentation set should have its own identifier. | ||
| 1466 | +# The default value is: org.doxygen.Project. | ||
| 1467 | +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. | ||
| 1468 | + | ||
| 1469 | +ECLIPSE_DOC_ID = org.doxygen.Project | ||
| 1470 | + | ||
| 1471 | +# If you want full control over the layout of the generated HTML pages it might | ||
| 1472 | +# be necessary to disable the index and replace it with your own. The | ||
| 1473 | +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top | ||
| 1474 | +# of each HTML page. A value of NO enables the index and the value YES disables | ||
| 1475 | +# it. Since the tabs in the index contain the same information as the navigation | ||
| 1476 | +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. | ||
| 1477 | +# The default value is: NO. | ||
| 1478 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1479 | + | ||
| 1480 | +DISABLE_INDEX = NO | ||
| 1481 | + | ||
| 1482 | +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index | ||
| 1483 | +# structure should be generated to display hierarchical information. If the tag | ||
| 1484 | +# value is set to YES, a side panel will be generated containing a tree-like | ||
| 1485 | +# index structure (just like the one that is generated for HTML Help). For this | ||
| 1486 | +# to work a browser that supports JavaScript, DHTML, CSS and frames is required | ||
| 1487 | +# (i.e. any modern browser). Windows users are probably better off using the | ||
| 1488 | +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can | ||
| 1489 | +# further fine-tune the look of the index. As an example, the default style | ||
| 1490 | +# sheet generated by doxygen has an example that shows how to put an image at | ||
| 1491 | +# the root of the tree instead of the PROJECT_NAME. Since the tree basically has | ||
| 1492 | +# the same information as the tab index, you could consider setting | ||
| 1493 | +# DISABLE_INDEX to YES when enabling this option. | ||
| 1494 | +# The default value is: NO. | ||
| 1495 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1496 | + | ||
| 1497 | +GENERATE_TREEVIEW = YES | ||
| 1498 | + | ||
| 1499 | +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that | ||
| 1500 | +# doxygen will group on one line in the generated HTML documentation. | ||
| 1501 | +# | ||
| 1502 | +# Note that a value of 0 will completely suppress the enum values from appearing | ||
| 1503 | +# in the overview section. | ||
| 1504 | +# Minimum value: 0, maximum value: 20, default value: 4. | ||
| 1505 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1506 | + | ||
| 1507 | +ENUM_VALUES_PER_LINE = 4 | ||
| 1508 | + | ||
| 1509 | +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used | ||
| 1510 | +# to set the initial width (in pixels) of the frame in which the tree is shown. | ||
| 1511 | +# Minimum value: 0, maximum value: 1500, default value: 250. | ||
| 1512 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1513 | + | ||
| 1514 | +TREEVIEW_WIDTH = 250 | ||
| 1515 | + | ||
| 1516 | +# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to | ||
| 1517 | +# external symbols imported via tag files in a separate window. | ||
| 1518 | +# The default value is: NO. | ||
| 1519 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1520 | + | ||
| 1521 | +EXT_LINKS_IN_WINDOW = NO | ||
| 1522 | + | ||
| 1523 | +# Use this tag to change the font size of LaTeX formulas included as images in | ||
| 1524 | +# the HTML documentation. When you change the font size after a successful | ||
| 1525 | +# doxygen run you need to manually remove any form_*.png images from the HTML | ||
| 1526 | +# output directory to force them to be regenerated. | ||
| 1527 | +# Minimum value: 8, maximum value: 50, default value: 10. | ||
| 1528 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1529 | + | ||
| 1530 | +FORMULA_FONTSIZE = 10 | ||
| 1531 | + | ||
| 1532 | +# Use the FORMULA_TRANSPARENT tag to determine whether or not the images | ||
| 1533 | +# generated for formulas are transparent PNGs. Transparent PNGs are not | ||
| 1534 | +# supported properly for IE 6.0, but are supported on all modern browsers. | ||
| 1535 | +# | ||
| 1536 | +# Note that when changing this option you need to delete any form_*.png files in | ||
| 1537 | +# the HTML output directory before the changes have effect. | ||
| 1538 | +# The default value is: YES. | ||
| 1539 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1540 | + | ||
| 1541 | +FORMULA_TRANSPARENT = YES | ||
| 1542 | + | ||
| 1543 | +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see | ||
| 1544 | +# https://www.mathjax.org) which uses client side Javascript for the rendering | ||
| 1545 | +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX | ||
| 1546 | +# installed or if you want to formulas look prettier in the HTML output. When | ||
| 1547 | +# enabled you may also need to install MathJax separately and configure the path | ||
| 1548 | +# to it using the MATHJAX_RELPATH option. | ||
| 1549 | +# The default value is: NO. | ||
| 1550 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1551 | + | ||
| 1552 | +USE_MATHJAX = NO | ||
| 1553 | + | ||
| 1554 | +# When MathJax is enabled you can set the default output format to be used for | ||
| 1555 | +# the MathJax output. See the MathJax site (see: | ||
| 1556 | +# http://docs.mathjax.org/en/latest/output.html) for more details. | ||
| 1557 | +# Possible values are: HTML-CSS (which is slower, but has the best | ||
| 1558 | +# compatibility), NativeMML (i.e. MathML) and SVG. | ||
| 1559 | +# The default value is: HTML-CSS. | ||
| 1560 | +# This tag requires that the tag USE_MATHJAX is set to YES. | ||
| 1561 | + | ||
| 1562 | +MATHJAX_FORMAT = HTML-CSS | ||
| 1563 | + | ||
| 1564 | +# When MathJax is enabled you need to specify the location relative to the HTML | ||
| 1565 | +# output directory using the MATHJAX_RELPATH option. The destination directory | ||
| 1566 | +# should contain the MathJax.js script. For instance, if the mathjax directory | ||
| 1567 | +# is located at the same level as the HTML output directory, then | ||
| 1568 | +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax | ||
| 1569 | +# Content Delivery Network so you can quickly see the result without installing | ||
| 1570 | +# MathJax. However, it is strongly recommended to install a local copy of | ||
| 1571 | +# MathJax from https://www.mathjax.org before deployment. | ||
| 1572 | +# The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/. | ||
| 1573 | +# This tag requires that the tag USE_MATHJAX is set to YES. | ||
| 1574 | + | ||
| 1575 | +MATHJAX_RELPATH = https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/ | ||
| 1576 | + | ||
| 1577 | +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax | ||
| 1578 | +# extension names that should be enabled during MathJax rendering. For example | ||
| 1579 | +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols | ||
| 1580 | +# This tag requires that the tag USE_MATHJAX is set to YES. | ||
| 1581 | + | ||
| 1582 | +MATHJAX_EXTENSIONS = | ||
| 1583 | + | ||
| 1584 | +# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces | ||
| 1585 | +# of code that will be used on startup of the MathJax code. See the MathJax site | ||
| 1586 | +# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an | ||
| 1587 | +# example see the documentation. | ||
| 1588 | +# This tag requires that the tag USE_MATHJAX is set to YES. | ||
| 1589 | + | ||
| 1590 | +MATHJAX_CODEFILE = | ||
| 1591 | + | ||
| 1592 | +# When the SEARCHENGINE tag is enabled doxygen will generate a search box for | ||
| 1593 | +# the HTML output. The underlying search engine uses javascript and DHTML and | ||
| 1594 | +# should work on any modern browser. Note that when using HTML help | ||
| 1595 | +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) | ||
| 1596 | +# there is already a search function so this one should typically be disabled. | ||
| 1597 | +# For large projects the javascript based search engine can be slow, then | ||
| 1598 | +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to | ||
| 1599 | +# search using the keyboard; to jump to the search box use <access key> + S | ||
| 1600 | +# (what the <access key> is depends on the OS and browser, but it is typically | ||
| 1601 | +# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down | ||
| 1602 | +# key> to jump into the search results window, the results can be navigated | ||
| 1603 | +# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel | ||
| 1604 | +# the search. The filter options can be selected when the cursor is inside the | ||
| 1605 | +# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys> | ||
| 1606 | +# to select a filter and <Enter> or <escape> to activate or cancel the filter | ||
| 1607 | +# option. | ||
| 1608 | +# The default value is: YES. | ||
| 1609 | +# This tag requires that the tag GENERATE_HTML is set to YES. | ||
| 1610 | + | ||
| 1611 | +SEARCHENGINE = YES | ||
| 1612 | + | ||
| 1613 | +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be | ||
| 1614 | +# implemented using a web server instead of a web client using Javascript. There | ||
| 1615 | +# are two flavors of web server based searching depending on the EXTERNAL_SEARCH | ||
| 1616 | +# setting. When disabled, doxygen will generate a PHP script for searching and | ||
| 1617 | +# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing | ||
| 1618 | +# and searching needs to be provided by external tools. See the section | ||
| 1619 | +# "External Indexing and Searching" for details. | ||
| 1620 | +# The default value is: NO. | ||
| 1621 | +# This tag requires that the tag SEARCHENGINE is set to YES. | ||
| 1622 | + | ||
| 1623 | +SERVER_BASED_SEARCH = NO | ||
| 1624 | + | ||
| 1625 | +# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP | ||
| 1626 | +# script for searching. Instead the search results are written to an XML file | ||
| 1627 | +# which needs to be processed by an external indexer. Doxygen will invoke an | ||
| 1628 | +# external search engine pointed to by the SEARCHENGINE_URL option to obtain the | ||
| 1629 | +# search results. | ||
| 1630 | +# | ||
| 1631 | +# Doxygen ships with an example indexer (doxyindexer) and search engine | ||
| 1632 | +# (doxysearch.cgi) which are based on the open source search engine library | ||
| 1633 | +# Xapian (see: https://xapian.org/). | ||
| 1634 | +# | ||
| 1635 | +# See the section "External Indexing and Searching" for details. | ||
| 1636 | +# The default value is: NO. | ||
| 1637 | +# This tag requires that the tag SEARCHENGINE is set to YES. | ||
| 1638 | + | ||
| 1639 | +EXTERNAL_SEARCH = NO | ||
| 1640 | + | ||
| 1641 | +# The SEARCHENGINE_URL should point to a search engine hosted by a web server | ||
| 1642 | +# which will return the search results when EXTERNAL_SEARCH is enabled. | ||
| 1643 | +# | ||
| 1644 | +# Doxygen ships with an example indexer (doxyindexer) and search engine | ||
| 1645 | +# (doxysearch.cgi) which are based on the open source search engine library | ||
| 1646 | +# Xapian (see: https://xapian.org/). See the section "External Indexing and | ||
| 1647 | +# Searching" for details. | ||
| 1648 | +# This tag requires that the tag SEARCHENGINE is set to YES. | ||
| 1649 | + | ||
| 1650 | +SEARCHENGINE_URL = | ||
| 1651 | + | ||
| 1652 | +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed | ||
| 1653 | +# search data is written to a file for indexing by an external tool. With the | ||
| 1654 | +# SEARCHDATA_FILE tag the name of this file can be specified. | ||
| 1655 | +# The default file is: searchdata.xml. | ||
| 1656 | +# This tag requires that the tag SEARCHENGINE is set to YES. | ||
| 1657 | + | ||
| 1658 | +SEARCHDATA_FILE = searchdata.xml | ||
| 1659 | + | ||
| 1660 | +# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the | ||
| 1661 | +# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is | ||
| 1662 | +# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple | ||
| 1663 | +# projects and redirect the results back to the right project. | ||
| 1664 | +# This tag requires that the tag SEARCHENGINE is set to YES. | ||
| 1665 | + | ||
| 1666 | +EXTERNAL_SEARCH_ID = | ||
| 1667 | + | ||
| 1668 | +# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen | ||
| 1669 | +# projects other than the one defined by this configuration file, but that are | ||
| 1670 | +# all added to the same external search index. Each project needs to have a | ||
| 1671 | +# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of | ||
| 1672 | +# to a relative location where the documentation can be found. The format is: | ||
| 1673 | +# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ... | ||
| 1674 | +# This tag requires that the tag SEARCHENGINE is set to YES. | ||
| 1675 | + | ||
| 1676 | +EXTRA_SEARCH_MAPPINGS = | ||
| 1677 | + | ||
| 1678 | +#--------------------------------------------------------------------------- | ||
| 1679 | +# Configuration options related to the LaTeX output | ||
| 1680 | +#--------------------------------------------------------------------------- | ||
| 1681 | + | ||
| 1682 | +# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output. | ||
| 1683 | +# The default value is: YES. | ||
| 1684 | + | ||
| 1685 | +GENERATE_LATEX = YES | ||
| 1686 | + | ||
| 1687 | +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a | ||
| 1688 | +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of | ||
| 1689 | +# it. | ||
| 1690 | +# The default directory is: latex. | ||
| 1691 | +# This tag requires that the tag GENERATE_LATEX is set to YES. | ||
| 1692 | + | ||
| 1693 | +LATEX_OUTPUT = latex | ||
| 1694 | + | ||
| 1695 | +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be | ||
| 1696 | +# invoked. | ||
| 1697 | +# | ||
| 1698 | +# Note that when not enabling USE_PDFLATEX the default is latex when enabling | ||
| 1699 | +# USE_PDFLATEX the default is pdflatex and when in the later case latex is | ||
| 1700 | +# chosen this is overwritten by pdflatex. For specific output languages the | ||
| 1701 | +# default can have been set differently, this depends on the implementation of | ||
| 1702 | +# the output language. | ||
| 1703 | +# This tag requires that the tag GENERATE_LATEX is set to YES. | ||
| 1704 | + | ||
| 1705 | +LATEX_CMD_NAME = | ||
| 1706 | + | ||
| 1707 | +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate | ||
| 1708 | +# index for LaTeX. | ||
| 1709 | +# Note: This tag is used in the Makefile / make.bat. | ||
| 1710 | +# See also: LATEX_MAKEINDEX_CMD for the part in the generated output file | ||
| 1711 | +# (.tex). | ||
| 1712 | +# The default file is: makeindex. | ||
| 1713 | +# This tag requires that the tag GENERATE_LATEX is set to YES. | ||
| 1714 | + | ||
| 1715 | +MAKEINDEX_CMD_NAME = makeindex | ||
| 1716 | + | ||
| 1717 | +# The LATEX_MAKEINDEX_CMD tag can be used to specify the command name to | ||
| 1718 | +# generate index for LaTeX. | ||
| 1719 | +# Note: This tag is used in the generated output file (.tex). | ||
| 1720 | +# See also: MAKEINDEX_CMD_NAME for the part in the Makefile / make.bat. | ||
| 1721 | +# The default value is: \makeindex. | ||
| 1722 | +# This tag requires that the tag GENERATE_LATEX is set to YES. | ||
| 1723 | + | ||
| 1724 | +LATEX_MAKEINDEX_CMD = \makeindex | ||
| 1725 | + | ||
| 1726 | +# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX | ||
| 1727 | +# documents. This may be useful for small projects and may help to save some | ||
| 1728 | +# trees in general. | ||
| 1729 | +# The default value is: NO. | ||
| 1730 | +# This tag requires that the tag GENERATE_LATEX is set to YES. | ||
| 1731 | + | ||
| 1732 | +COMPACT_LATEX = NO | ||
| 1733 | + | ||
| 1734 | +# The PAPER_TYPE tag can be used to set the paper type that is used by the | ||
| 1735 | +# printer. | ||
| 1736 | +# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x | ||
| 1737 | +# 14 inches) and executive (7.25 x 10.5 inches). | ||
| 1738 | +# The default value is: a4. | ||
| 1739 | +# This tag requires that the tag GENERATE_LATEX is set to YES. | ||
| 1740 | + | ||
| 1741 | +PAPER_TYPE = a4 | ||
| 1742 | + | ||
| 1743 | +# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names | ||
| 1744 | +# that should be included in the LaTeX output. The package can be specified just | ||
| 1745 | +# by its name or with the correct syntax as to be used with the LaTeX | ||
| 1746 | +# \usepackage command. To get the times font for instance you can specify : | ||
| 1747 | +# EXTRA_PACKAGES=times or EXTRA_PACKAGES={times} | ||
| 1748 | +# To use the option intlimits with the amsmath package you can specify: | ||
| 1749 | +# EXTRA_PACKAGES=[intlimits]{amsmath} | ||
| 1750 | +# If left blank no extra packages will be included. | ||
| 1751 | +# This tag requires that the tag GENERATE_LATEX is set to YES. | ||
| 1752 | + | ||
| 1753 | +EXTRA_PACKAGES = | ||
| 1754 | + | ||
| 1755 | +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the | ||
| 1756 | +# generated LaTeX document. The header should contain everything until the first | ||
| 1757 | +# chapter. If it is left blank doxygen will generate a standard header. See | ||
| 1758 | +# section "Doxygen usage" for information on how to let doxygen write the | ||
| 1759 | +# default header to a separate file. | ||
| 1760 | +# | ||
| 1761 | +# Note: Only use a user-defined header if you know what you are doing! The | ||
| 1762 | +# following commands have a special meaning inside the header: $title, | ||
| 1763 | +# $datetime, $date, $doxygenversion, $projectname, $projectnumber, | ||
| 1764 | +# $projectbrief, $projectlogo. Doxygen will replace $title with the empty | ||
| 1765 | +# string, for the replacement values of the other commands the user is referred | ||
| 1766 | +# to HTML_HEADER. | ||
| 1767 | +# This tag requires that the tag GENERATE_LATEX is set to YES. | ||
| 1768 | + | ||
| 1769 | +LATEX_HEADER = | ||
| 1770 | + | ||
| 1771 | +# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the | ||
| 1772 | +# generated LaTeX document. The footer should contain everything after the last | ||
| 1773 | +# chapter. If it is left blank doxygen will generate a standard footer. See | ||
| 1774 | +# LATEX_HEADER for more information on how to generate a default footer and what | ||
| 1775 | +# special commands can be used inside the footer. | ||
| 1776 | +# | ||
| 1777 | +# Note: Only use a user-defined footer if you know what you are doing! | ||
| 1778 | +# This tag requires that the tag GENERATE_LATEX is set to YES. | ||
| 1779 | + | ||
| 1780 | +LATEX_FOOTER = | ||
| 1781 | + | ||
| 1782 | +# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined | ||
| 1783 | +# LaTeX style sheets that are included after the standard style sheets created | ||
| 1784 | +# by doxygen. Using this option one can overrule certain style aspects. Doxygen | ||
| 1785 | +# will copy the style sheet files to the output directory. | ||
| 1786 | +# Note: The order of the extra style sheet files is of importance (e.g. the last | ||
| 1787 | +# style sheet in the list overrules the setting of the previous ones in the | ||
| 1788 | +# list). | ||
| 1789 | +# This tag requires that the tag GENERATE_LATEX is set to YES. | ||
| 1790 | + | ||
| 1791 | +LATEX_EXTRA_STYLESHEET = | ||
| 1792 | + | ||
| 1793 | +# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or | ||
| 1794 | +# other source files which should be copied to the LATEX_OUTPUT output | ||
| 1795 | +# directory. Note that the files will be copied as-is; there are no commands or | ||
| 1796 | +# markers available. | ||
| 1797 | +# This tag requires that the tag GENERATE_LATEX is set to YES. | ||
| 1798 | + | ||
| 1799 | +LATEX_EXTRA_FILES = | ||
| 1800 | + | ||
| 1801 | +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is | ||
| 1802 | +# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will | ||
| 1803 | +# contain links (just like the HTML output) instead of page references. This | ||
| 1804 | +# makes the output suitable for online browsing using a PDF viewer. | ||
| 1805 | +# The default value is: YES. | ||
| 1806 | +# This tag requires that the tag GENERATE_LATEX is set to YES. | ||
| 1807 | + | ||
| 1808 | +PDF_HYPERLINKS = NO | ||
| 1809 | + | ||
| 1810 | +# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate | ||
| 1811 | +# the PDF file directly from the LaTeX files. Set this option to YES, to get a | ||
| 1812 | +# higher quality PDF documentation. | ||
| 1813 | +# The default value is: YES. | ||
| 1814 | +# This tag requires that the tag GENERATE_LATEX is set to YES. | ||
| 1815 | + | ||
| 1816 | +USE_PDFLATEX = YES | ||
| 1817 | + | ||
| 1818 | +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode | ||
| 1819 | +# command to the generated LaTeX files. This will instruct LaTeX to keep running | ||
| 1820 | +# if errors occur, instead of asking the user for help. This option is also used | ||
| 1821 | +# when generating formulas in HTML. | ||
| 1822 | +# The default value is: NO. | ||
| 1823 | +# This tag requires that the tag GENERATE_LATEX is set to YES. | ||
| 1824 | + | ||
| 1825 | +LATEX_BATCHMODE = NO | ||
| 1826 | + | ||
| 1827 | +# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the | ||
| 1828 | +# index chapters (such as File Index, Compound Index, etc.) in the output. | ||
| 1829 | +# The default value is: NO. | ||
| 1830 | +# This tag requires that the tag GENERATE_LATEX is set to YES. | ||
| 1831 | + | ||
| 1832 | +LATEX_HIDE_INDICES = NO | ||
| 1833 | + | ||
| 1834 | +# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source | ||
| 1835 | +# code with syntax highlighting in the LaTeX output. | ||
| 1836 | +# | ||
| 1837 | +# Note that which sources are shown also depends on other settings such as | ||
| 1838 | +# SOURCE_BROWSER. | ||
| 1839 | +# The default value is: NO. | ||
| 1840 | +# This tag requires that the tag GENERATE_LATEX is set to YES. | ||
| 1841 | + | ||
| 1842 | +LATEX_SOURCE_CODE = NO | ||
| 1843 | + | ||
| 1844 | +# The LATEX_BIB_STYLE tag can be used to specify the style to use for the | ||
| 1845 | +# bibliography, e.g. plainnat, or ieeetr. See | ||
| 1846 | +# https://en.wikipedia.org/wiki/BibTeX and \cite for more info. | ||
| 1847 | +# The default value is: plain. | ||
| 1848 | +# This tag requires that the tag GENERATE_LATEX is set to YES. | ||
| 1849 | + | ||
| 1850 | +LATEX_BIB_STYLE = plain | ||
| 1851 | + | ||
| 1852 | +# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated | ||
| 1853 | +# page will contain the date and time when the page was generated. Setting this | ||
| 1854 | +# to NO can help when comparing the output of multiple runs. | ||
| 1855 | +# The default value is: NO. | ||
| 1856 | +# This tag requires that the tag GENERATE_LATEX is set to YES. | ||
| 1857 | + | ||
| 1858 | +LATEX_TIMESTAMP = NO | ||
| 1859 | + | ||
| 1860 | +# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute) | ||
| 1861 | +# path from which the emoji images will be read. If a relative path is entered, | ||
| 1862 | +# it will be relative to the LATEX_OUTPUT directory. If left blank the | ||
| 1863 | +# LATEX_OUTPUT directory will be used. | ||
| 1864 | +# This tag requires that the tag GENERATE_LATEX is set to YES. | ||
| 1865 | + | ||
| 1866 | +LATEX_EMOJI_DIRECTORY = | ||
| 1867 | + | ||
| 1868 | +#--------------------------------------------------------------------------- | ||
| 1869 | +# Configuration options related to the RTF output | ||
| 1870 | +#--------------------------------------------------------------------------- | ||
| 1871 | + | ||
| 1872 | +# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The | ||
| 1873 | +# RTF output is optimized for Word 97 and may not look too pretty with other RTF | ||
| 1874 | +# readers/editors. | ||
| 1875 | +# The default value is: NO. | ||
| 1876 | + | ||
| 1877 | +GENERATE_RTF = NO | ||
| 1878 | + | ||
| 1879 | +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a | ||
| 1880 | +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of | ||
| 1881 | +# it. | ||
| 1882 | +# The default directory is: rtf. | ||
| 1883 | +# This tag requires that the tag GENERATE_RTF is set to YES. | ||
| 1884 | + | ||
| 1885 | +RTF_OUTPUT = rtf | ||
| 1886 | + | ||
| 1887 | +# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF | ||
| 1888 | +# documents. This may be useful for small projects and may help to save some | ||
| 1889 | +# trees in general. | ||
| 1890 | +# The default value is: NO. | ||
| 1891 | +# This tag requires that the tag GENERATE_RTF is set to YES. | ||
| 1892 | + | ||
| 1893 | +COMPACT_RTF = NO | ||
| 1894 | + | ||
| 1895 | +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will | ||
| 1896 | +# contain hyperlink fields. The RTF file will contain links (just like the HTML | ||
| 1897 | +# output) instead of page references. This makes the output suitable for online | ||
| 1898 | +# browsing using Word or some other Word compatible readers that support those | ||
| 1899 | +# fields. | ||
| 1900 | +# | ||
| 1901 | +# Note: WordPad (write) and others do not support links. | ||
| 1902 | +# The default value is: NO. | ||
| 1903 | +# This tag requires that the tag GENERATE_RTF is set to YES. | ||
| 1904 | + | ||
| 1905 | +RTF_HYPERLINKS = NO | ||
| 1906 | + | ||
| 1907 | +# Load stylesheet definitions from file. Syntax is similar to doxygen's | ||
| 1908 | +# configuration file, i.e. a series of assignments. You only have to provide | ||
| 1909 | +# replacements, missing definitions are set to their default value. | ||
| 1910 | +# | ||
| 1911 | +# See also section "Doxygen usage" for information on how to generate the | ||
| 1912 | +# default style sheet that doxygen normally uses. | ||
| 1913 | +# This tag requires that the tag GENERATE_RTF is set to YES. | ||
| 1914 | + | ||
| 1915 | +RTF_STYLESHEET_FILE = | ||
| 1916 | + | ||
| 1917 | +# Set optional variables used in the generation of an RTF document. Syntax is | ||
| 1918 | +# similar to doxygen's configuration file. A template extensions file can be | ||
| 1919 | +# generated using doxygen -e rtf extensionFile. | ||
| 1920 | +# This tag requires that the tag GENERATE_RTF is set to YES. | ||
| 1921 | + | ||
| 1922 | +RTF_EXTENSIONS_FILE = | ||
| 1923 | + | ||
| 1924 | +# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code | ||
| 1925 | +# with syntax highlighting in the RTF output. | ||
| 1926 | +# | ||
| 1927 | +# Note that which sources are shown also depends on other settings such as | ||
| 1928 | +# SOURCE_BROWSER. | ||
| 1929 | +# The default value is: NO. | ||
| 1930 | +# This tag requires that the tag GENERATE_RTF is set to YES. | ||
| 1931 | + | ||
| 1932 | +RTF_SOURCE_CODE = NO | ||
| 1933 | + | ||
| 1934 | +#--------------------------------------------------------------------------- | ||
| 1935 | +# Configuration options related to the man page output | ||
| 1936 | +#--------------------------------------------------------------------------- | ||
| 1937 | + | ||
| 1938 | +# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for | ||
| 1939 | +# classes and files. | ||
| 1940 | +# The default value is: NO. | ||
| 1941 | + | ||
| 1942 | +GENERATE_MAN = NO | ||
| 1943 | + | ||
| 1944 | +# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a | ||
| 1945 | +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of | ||
| 1946 | +# it. A directory man3 will be created inside the directory specified by | ||
| 1947 | +# MAN_OUTPUT. | ||
| 1948 | +# The default directory is: man. | ||
| 1949 | +# This tag requires that the tag GENERATE_MAN is set to YES. | ||
| 1950 | + | ||
| 1951 | +MAN_OUTPUT = man | ||
| 1952 | + | ||
| 1953 | +# The MAN_EXTENSION tag determines the extension that is added to the generated | ||
| 1954 | +# man pages. In case the manual section does not start with a number, the number | ||
| 1955 | +# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is | ||
| 1956 | +# optional. | ||
| 1957 | +# The default value is: .3. | ||
| 1958 | +# This tag requires that the tag GENERATE_MAN is set to YES. | ||
| 1959 | + | ||
| 1960 | +MAN_EXTENSION = .3 | ||
| 1961 | + | ||
| 1962 | +# The MAN_SUBDIR tag determines the name of the directory created within | ||
| 1963 | +# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by | ||
| 1964 | +# MAN_EXTENSION with the initial . removed. | ||
| 1965 | +# This tag requires that the tag GENERATE_MAN is set to YES. | ||
| 1966 | + | ||
| 1967 | +MAN_SUBDIR = | ||
| 1968 | + | ||
| 1969 | +# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it | ||
| 1970 | +# will generate one additional man file for each entity documented in the real | ||
| 1971 | +# man page(s). These additional files only source the real man page, but without | ||
| 1972 | +# them the man command would be unable to find the correct page. | ||
| 1973 | +# The default value is: NO. | ||
| 1974 | +# This tag requires that the tag GENERATE_MAN is set to YES. | ||
| 1975 | + | ||
| 1976 | +MAN_LINKS = NO | ||
| 1977 | + | ||
| 1978 | +#--------------------------------------------------------------------------- | ||
| 1979 | +# Configuration options related to the XML output | ||
| 1980 | +#--------------------------------------------------------------------------- | ||
| 1981 | + | ||
| 1982 | +# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that | ||
| 1983 | +# captures the structure of the code including all documentation. | ||
| 1984 | +# The default value is: NO. | ||
| 1985 | + | ||
| 1986 | +GENERATE_XML = NO | ||
| 1987 | + | ||
| 1988 | +# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a | ||
| 1989 | +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of | ||
| 1990 | +# it. | ||
| 1991 | +# The default directory is: xml. | ||
| 1992 | +# This tag requires that the tag GENERATE_XML is set to YES. | ||
| 1993 | + | ||
| 1994 | +XML_OUTPUT = xml | ||
| 1995 | + | ||
| 1996 | +# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program | ||
| 1997 | +# listings (including syntax highlighting and cross-referencing information) to | ||
| 1998 | +# the XML output. Note that enabling this will significantly increase the size | ||
| 1999 | +# of the XML output. | ||
| 2000 | +# The default value is: YES. | ||
| 2001 | +# This tag requires that the tag GENERATE_XML is set to YES. | ||
| 2002 | + | ||
| 2003 | +XML_PROGRAMLISTING = YES | ||
| 2004 | + | ||
| 2005 | +# If the XML_NS_MEMB_FILE_SCOPE tag is set to YES, doxygen will include | ||
| 2006 | +# namespace members in file scope as well, matching the HTML output. | ||
| 2007 | +# The default value is: NO. | ||
| 2008 | +# This tag requires that the tag GENERATE_XML is set to YES. | ||
| 2009 | + | ||
| 2010 | +XML_NS_MEMB_FILE_SCOPE = NO | ||
| 2011 | + | ||
| 2012 | +#--------------------------------------------------------------------------- | ||
| 2013 | +# Configuration options related to the DOCBOOK output | ||
| 2014 | +#--------------------------------------------------------------------------- | ||
| 2015 | + | ||
| 2016 | +# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files | ||
| 2017 | +# that can be used to generate PDF. | ||
| 2018 | +# The default value is: NO. | ||
| 2019 | + | ||
| 2020 | +GENERATE_DOCBOOK = NO | ||
| 2021 | + | ||
| 2022 | +# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put. | ||
| 2023 | +# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in | ||
| 2024 | +# front of it. | ||
| 2025 | +# The default directory is: docbook. | ||
| 2026 | +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. | ||
| 2027 | + | ||
| 2028 | +DOCBOOK_OUTPUT = docbook | ||
| 2029 | + | ||
| 2030 | +# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the | ||
| 2031 | +# program listings (including syntax highlighting and cross-referencing | ||
| 2032 | +# information) to the DOCBOOK output. Note that enabling this will significantly | ||
| 2033 | +# increase the size of the DOCBOOK output. | ||
| 2034 | +# The default value is: NO. | ||
| 2035 | +# This tag requires that the tag GENERATE_DOCBOOK is set to YES. | ||
| 2036 | + | ||
| 2037 | +DOCBOOK_PROGRAMLISTING = NO | ||
| 2038 | + | ||
| 2039 | +#--------------------------------------------------------------------------- | ||
| 2040 | +# Configuration options for the AutoGen Definitions output | ||
| 2041 | +#--------------------------------------------------------------------------- | ||
| 2042 | + | ||
| 2043 | +# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an | ||
| 2044 | +# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures | ||
| 2045 | +# the structure of the code including all documentation. Note that this feature | ||
| 2046 | +# is still experimental and incomplete at the moment. | ||
| 2047 | +# The default value is: NO. | ||
| 2048 | + | ||
| 2049 | +GENERATE_AUTOGEN_DEF = NO | ||
| 2050 | + | ||
| 2051 | +#--------------------------------------------------------------------------- | ||
| 2052 | +# Configuration options related to the Perl module output | ||
| 2053 | +#--------------------------------------------------------------------------- | ||
| 2054 | + | ||
| 2055 | +# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module | ||
| 2056 | +# file that captures the structure of the code including all documentation. | ||
| 2057 | +# | ||
| 2058 | +# Note that this feature is still experimental and incomplete at the moment. | ||
| 2059 | +# The default value is: NO. | ||
| 2060 | + | ||
| 2061 | +GENERATE_PERLMOD = NO | ||
| 2062 | + | ||
| 2063 | +# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary | ||
| 2064 | +# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI | ||
| 2065 | +# output from the Perl module output. | ||
| 2066 | +# The default value is: NO. | ||
| 2067 | +# This tag requires that the tag GENERATE_PERLMOD is set to YES. | ||
| 2068 | + | ||
| 2069 | +PERLMOD_LATEX = NO | ||
| 2070 | + | ||
| 2071 | +# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely | ||
| 2072 | +# formatted so it can be parsed by a human reader. This is useful if you want to | ||
| 2073 | +# understand what is going on. On the other hand, if this tag is set to NO, the | ||
| 2074 | +# size of the Perl module output will be much smaller and Perl will parse it | ||
| 2075 | +# just the same. | ||
| 2076 | +# The default value is: YES. | ||
| 2077 | +# This tag requires that the tag GENERATE_PERLMOD is set to YES. | ||
| 2078 | + | ||
| 2079 | +PERLMOD_PRETTY = YES | ||
| 2080 | + | ||
| 2081 | +# The names of the make variables in the generated doxyrules.make file are | ||
| 2082 | +# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful | ||
| 2083 | +# so different doxyrules.make files included by the same Makefile don't | ||
| 2084 | +# overwrite each other's variables. | ||
| 2085 | +# This tag requires that the tag GENERATE_PERLMOD is set to YES. | ||
| 2086 | + | ||
| 2087 | +PERLMOD_MAKEVAR_PREFIX = | ||
| 2088 | + | ||
| 2089 | +#--------------------------------------------------------------------------- | ||
| 2090 | +# Configuration options related to the preprocessor | ||
| 2091 | +#--------------------------------------------------------------------------- | ||
| 2092 | + | ||
| 2093 | +# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all | ||
| 2094 | +# C-preprocessor directives found in the sources and include files. | ||
| 2095 | +# The default value is: YES. | ||
| 2096 | + | ||
| 2097 | +ENABLE_PREPROCESSING = YES | ||
| 2098 | + | ||
| 2099 | +# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names | ||
| 2100 | +# in the source code. If set to NO, only conditional compilation will be | ||
| 2101 | +# performed. Macro expansion can be done in a controlled way by setting | ||
| 2102 | +# EXPAND_ONLY_PREDEF to YES. | ||
| 2103 | +# The default value is: NO. | ||
| 2104 | +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. | ||
| 2105 | + | ||
| 2106 | +MACRO_EXPANSION = NO | ||
| 2107 | + | ||
| 2108 | +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then | ||
| 2109 | +# the macro expansion is limited to the macros specified with the PREDEFINED and | ||
| 2110 | +# EXPAND_AS_DEFINED tags. | ||
| 2111 | +# The default value is: NO. | ||
| 2112 | +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. | ||
| 2113 | + | ||
| 2114 | +EXPAND_ONLY_PREDEF = NO | ||
| 2115 | + | ||
| 2116 | +# If the SEARCH_INCLUDES tag is set to YES, the include files in the | ||
| 2117 | +# INCLUDE_PATH will be searched if a #include is found. | ||
| 2118 | +# The default value is: YES. | ||
| 2119 | +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. | ||
| 2120 | + | ||
| 2121 | +SEARCH_INCLUDES = YES | ||
| 2122 | + | ||
| 2123 | +# The INCLUDE_PATH tag can be used to specify one or more directories that | ||
| 2124 | +# contain include files that are not input files but should be processed by the | ||
| 2125 | +# preprocessor. | ||
| 2126 | +# This tag requires that the tag SEARCH_INCLUDES is set to YES. | ||
| 2127 | + | ||
| 2128 | +INCLUDE_PATH = | ||
| 2129 | + | ||
| 2130 | +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard | ||
| 2131 | +# patterns (like *.h and *.hpp) to filter out the header-files in the | ||
| 2132 | +# directories. If left blank, the patterns specified with FILE_PATTERNS will be | ||
| 2133 | +# used. | ||
| 2134 | +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. | ||
| 2135 | + | ||
| 2136 | +INCLUDE_FILE_PATTERNS = | ||
| 2137 | + | ||
| 2138 | +# The PREDEFINED tag can be used to specify one or more macro names that are | ||
| 2139 | +# defined before the preprocessor is started (similar to the -D option of e.g. | ||
| 2140 | +# gcc). The argument of the tag is a list of macros of the form: name or | ||
| 2141 | +# name=definition (no spaces). If the definition and the "=" are omitted, "=1" | ||
| 2142 | +# is assumed. To prevent a macro definition from being undefined via #undef or | ||
| 2143 | +# recursively expanded use the := operator instead of the = operator. | ||
| 2144 | +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. | ||
| 2145 | + | ||
| 2146 | +PREDEFINED = | ||
| 2147 | + | ||
| 2148 | +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this | ||
| 2149 | +# tag can be used to specify a list of macro names that should be expanded. The | ||
| 2150 | +# macro definition that is found in the sources will be used. Use the PREDEFINED | ||
| 2151 | +# tag if you want to use a different macro definition that overrules the | ||
| 2152 | +# definition found in the source code. | ||
| 2153 | +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. | ||
| 2154 | + | ||
| 2155 | +EXPAND_AS_DEFINED = | ||
| 2156 | + | ||
| 2157 | +# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will | ||
| 2158 | +# remove all references to function-like macros that are alone on a line, have | ||
| 2159 | +# an all uppercase name, and do not end with a semicolon. Such function macros | ||
| 2160 | +# are typically used for boiler-plate code, and will confuse the parser if not | ||
| 2161 | +# removed. | ||
| 2162 | +# The default value is: YES. | ||
| 2163 | +# This tag requires that the tag ENABLE_PREPROCESSING is set to YES. | ||
| 2164 | + | ||
| 2165 | +SKIP_FUNCTION_MACROS = YES | ||
| 2166 | + | ||
| 2167 | +#--------------------------------------------------------------------------- | ||
| 2168 | +# Configuration options related to external references | ||
| 2169 | +#--------------------------------------------------------------------------- | ||
| 2170 | + | ||
| 2171 | +# The TAGFILES tag can be used to specify one or more tag files. For each tag | ||
| 2172 | +# file the location of the external documentation should be added. The format of | ||
| 2173 | +# a tag file without this location is as follows: | ||
| 2174 | +# TAGFILES = file1 file2 ... | ||
| 2175 | +# Adding location for the tag files is done as follows: | ||
| 2176 | +# TAGFILES = file1=loc1 "file2 = loc2" ... | ||
| 2177 | +# where loc1 and loc2 can be relative or absolute paths or URLs. See the | ||
| 2178 | +# section "Linking to external documentation" for more information about the use | ||
| 2179 | +# of tag files. | ||
| 2180 | +# Note: Each tag file must have a unique name (where the name does NOT include | ||
| 2181 | +# the path). If a tag file is not located in the directory in which doxygen is | ||
| 2182 | +# run, you must also specify the path to the tagfile here. | ||
| 2183 | + | ||
| 2184 | +TAGFILES = | ||
| 2185 | + | ||
| 2186 | +# When a file name is specified after GENERATE_TAGFILE, doxygen will create a | ||
| 2187 | +# tag file that is based on the input files it reads. See section "Linking to | ||
| 2188 | +# external documentation" for more information about the usage of tag files. | ||
| 2189 | + | ||
| 2190 | +GENERATE_TAGFILE = | ||
| 2191 | + | ||
| 2192 | +# If the ALLEXTERNALS tag is set to YES, all external class will be listed in | ||
| 2193 | +# the class index. If set to NO, only the inherited external classes will be | ||
| 2194 | +# listed. | ||
| 2195 | +# The default value is: NO. | ||
| 2196 | + | ||
| 2197 | +ALLEXTERNALS = NO | ||
| 2198 | + | ||
| 2199 | +# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed | ||
| 2200 | +# in the modules index. If set to NO, only the current project's groups will be | ||
| 2201 | +# listed. | ||
| 2202 | +# The default value is: YES. | ||
| 2203 | + | ||
| 2204 | +EXTERNAL_GROUPS = YES | ||
| 2205 | + | ||
| 2206 | +# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in | ||
| 2207 | +# the related pages index. If set to NO, only the current project's pages will | ||
| 2208 | +# be listed. | ||
| 2209 | +# The default value is: YES. | ||
| 2210 | + | ||
| 2211 | +EXTERNAL_PAGES = YES | ||
| 2212 | + | ||
| 2213 | +# The PERL_PATH should be the absolute path and name of the perl script | ||
| 2214 | +# interpreter (i.e. the result of 'which perl'). | ||
| 2215 | +# The default file (with absolute path) is: /usr/bin/perl. | ||
| 2216 | + | ||
| 2217 | +PERL_PATH = /usr/bin/perl | ||
| 2218 | + | ||
| 2219 | +#--------------------------------------------------------------------------- | ||
| 2220 | +# Configuration options related to the dot tool | ||
| 2221 | +#--------------------------------------------------------------------------- | ||
| 2222 | + | ||
| 2223 | +# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram | ||
| 2224 | +# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to | ||
| 2225 | +# NO turns the diagrams off. Note that this option also works with HAVE_DOT | ||
| 2226 | +# disabled, but it is recommended to install and use dot, since it yields more | ||
| 2227 | +# powerful graphs. | ||
| 2228 | +# The default value is: YES. | ||
| 2229 | + | ||
| 2230 | +CLASS_DIAGRAMS = NO | ||
| 2231 | + | ||
| 2232 | +# You can define message sequence charts within doxygen comments using the \msc | ||
| 2233 | +# command. Doxygen will then run the mscgen tool (see: | ||
| 2234 | +# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the | ||
| 2235 | +# documentation. The MSCGEN_PATH tag allows you to specify the directory where | ||
| 2236 | +# the mscgen tool resides. If left empty the tool is assumed to be found in the | ||
| 2237 | +# default search path. | ||
| 2238 | + | ||
| 2239 | +MSCGEN_PATH = | ||
| 2240 | + | ||
| 2241 | +# You can include diagrams made with dia in doxygen documentation. Doxygen will | ||
| 2242 | +# then run dia to produce the diagram and insert it in the documentation. The | ||
| 2243 | +# DIA_PATH tag allows you to specify the directory where the dia binary resides. | ||
| 2244 | +# If left empty dia is assumed to be found in the default search path. | ||
| 2245 | + | ||
| 2246 | +DIA_PATH = | ||
| 2247 | + | ||
| 2248 | +# If set to YES the inheritance and collaboration graphs will hide inheritance | ||
| 2249 | +# and usage relations if the target is undocumented or is not a class. | ||
| 2250 | +# The default value is: YES. | ||
| 2251 | + | ||
| 2252 | +HIDE_UNDOC_RELATIONS = YES | ||
| 2253 | + | ||
| 2254 | +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is | ||
| 2255 | +# available from the path. This tool is part of Graphviz (see: | ||
| 2256 | +# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent | ||
| 2257 | +# Bell Labs. The other options in this section have no effect if this option is | ||
| 2258 | +# set to NO | ||
| 2259 | +# The default value is: NO. | ||
| 2260 | + | ||
| 2261 | +HAVE_DOT = YES | ||
| 2262 | + | ||
| 2263 | +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed | ||
| 2264 | +# to run in parallel. When set to 0 doxygen will base this on the number of | ||
| 2265 | +# processors available in the system. You can set it explicitly to a value | ||
| 2266 | +# larger than 0 to get control over the balance between CPU load and processing | ||
| 2267 | +# speed. | ||
| 2268 | +# Minimum value: 0, maximum value: 32, default value: 0. | ||
| 2269 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2270 | + | ||
| 2271 | +DOT_NUM_THREADS = 0 | ||
| 2272 | + | ||
| 2273 | +# When you want a differently looking font in the dot files that doxygen | ||
| 2274 | +# generates you can specify the font name using DOT_FONTNAME. You need to make | ||
| 2275 | +# sure dot is able to find the font, which can be done by putting it in a | ||
| 2276 | +# standard location or by setting the DOTFONTPATH environment variable or by | ||
| 2277 | +# setting DOT_FONTPATH to the directory containing the font. | ||
| 2278 | +# The default value is: Helvetica. | ||
| 2279 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2280 | + | ||
| 2281 | +DOT_FONTNAME = Helvetica | ||
| 2282 | + | ||
| 2283 | +# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of | ||
| 2284 | +# dot graphs. | ||
| 2285 | +# Minimum value: 4, maximum value: 24, default value: 10. | ||
| 2286 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2287 | + | ||
| 2288 | +DOT_FONTSIZE = 10 | ||
| 2289 | + | ||
| 2290 | +# By default doxygen will tell dot to use the default font as specified with | ||
| 2291 | +# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set | ||
| 2292 | +# the path where dot can find it using this tag. | ||
| 2293 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2294 | + | ||
| 2295 | +DOT_FONTPATH = | ||
| 2296 | + | ||
| 2297 | +# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for | ||
| 2298 | +# each documented class showing the direct and indirect inheritance relations. | ||
| 2299 | +# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO. | ||
| 2300 | +# The default value is: YES. | ||
| 2301 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2302 | + | ||
| 2303 | +CLASS_GRAPH = YES | ||
| 2304 | + | ||
| 2305 | +# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a | ||
| 2306 | +# graph for each documented class showing the direct and indirect implementation | ||
| 2307 | +# dependencies (inheritance, containment, and class references variables) of the | ||
| 2308 | +# class with other documented classes. | ||
| 2309 | +# The default value is: YES. | ||
| 2310 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2311 | + | ||
| 2312 | +COLLABORATION_GRAPH = YES | ||
| 2313 | + | ||
| 2314 | +# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for | ||
| 2315 | +# groups, showing the direct groups dependencies. | ||
| 2316 | +# The default value is: YES. | ||
| 2317 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2318 | + | ||
| 2319 | +GROUP_GRAPHS = YES | ||
| 2320 | + | ||
| 2321 | +# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and | ||
| 2322 | +# collaboration diagrams in a style similar to the OMG's Unified Modeling | ||
| 2323 | +# Language. | ||
| 2324 | +# The default value is: NO. | ||
| 2325 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2326 | + | ||
| 2327 | +UML_LOOK = NO | ||
| 2328 | + | ||
| 2329 | +# If the UML_LOOK tag is enabled, the fields and methods are shown inside the | ||
| 2330 | +# class node. If there are many fields or methods and many nodes the graph may | ||
| 2331 | +# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the | ||
| 2332 | +# number of items for each type to make the size more manageable. Set this to 0 | ||
| 2333 | +# for no limit. Note that the threshold may be exceeded by 50% before the limit | ||
| 2334 | +# is enforced. So when you set the threshold to 10, up to 15 fields may appear, | ||
| 2335 | +# but if the number exceeds 15, the total amount of fields shown is limited to | ||
| 2336 | +# 10. | ||
| 2337 | +# Minimum value: 0, maximum value: 100, default value: 10. | ||
| 2338 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2339 | + | ||
| 2340 | +UML_LIMIT_NUM_FIELDS = 10 | ||
| 2341 | + | ||
| 2342 | +# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and | ||
| 2343 | +# collaboration graphs will show the relations between templates and their | ||
| 2344 | +# instances. | ||
| 2345 | +# The default value is: NO. | ||
| 2346 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2347 | + | ||
| 2348 | +TEMPLATE_RELATIONS = NO | ||
| 2349 | + | ||
| 2350 | +# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to | ||
| 2351 | +# YES then doxygen will generate a graph for each documented file showing the | ||
| 2352 | +# direct and indirect include dependencies of the file with other documented | ||
| 2353 | +# files. | ||
| 2354 | +# The default value is: YES. | ||
| 2355 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2356 | + | ||
| 2357 | +INCLUDE_GRAPH = YES | ||
| 2358 | + | ||
| 2359 | +# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are | ||
| 2360 | +# set to YES then doxygen will generate a graph for each documented file showing | ||
| 2361 | +# the direct and indirect include dependencies of the file with other documented | ||
| 2362 | +# files. | ||
| 2363 | +# The default value is: YES. | ||
| 2364 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2365 | + | ||
| 2366 | +INCLUDED_BY_GRAPH = YES | ||
| 2367 | + | ||
| 2368 | +# If the CALL_GRAPH tag is set to YES then doxygen will generate a call | ||
| 2369 | +# dependency graph for every global function or class method. | ||
| 2370 | +# | ||
| 2371 | +# Note that enabling this option will significantly increase the time of a run. | ||
| 2372 | +# So in most cases it will be better to enable call graphs for selected | ||
| 2373 | +# functions only using the \callgraph command. Disabling a call graph can be | ||
| 2374 | +# accomplished by means of the command \hidecallgraph. | ||
| 2375 | +# The default value is: NO. | ||
| 2376 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2377 | + | ||
| 2378 | +CALL_GRAPH = YES | ||
| 2379 | + | ||
| 2380 | +# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller | ||
| 2381 | +# dependency graph for every global function or class method. | ||
| 2382 | +# | ||
| 2383 | +# Note that enabling this option will significantly increase the time of a run. | ||
| 2384 | +# So in most cases it will be better to enable caller graphs for selected | ||
| 2385 | +# functions only using the \callergraph command. Disabling a caller graph can be | ||
| 2386 | +# accomplished by means of the command \hidecallergraph. | ||
| 2387 | +# The default value is: NO. | ||
| 2388 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2389 | + | ||
| 2390 | +CALLER_GRAPH = YES | ||
| 2391 | + | ||
| 2392 | +# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical | ||
| 2393 | +# hierarchy of all classes instead of a textual one. | ||
| 2394 | +# The default value is: YES. | ||
| 2395 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2396 | + | ||
| 2397 | +GRAPHICAL_HIERARCHY = YES | ||
| 2398 | + | ||
| 2399 | +# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the | ||
| 2400 | +# dependencies a directory has on other directories in a graphical way. The | ||
| 2401 | +# dependency relations are determined by the #include relations between the | ||
| 2402 | +# files in the directories. | ||
| 2403 | +# The default value is: YES. | ||
| 2404 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2405 | + | ||
| 2406 | +DIRECTORY_GRAPH = YES | ||
| 2407 | + | ||
| 2408 | +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images | ||
| 2409 | +# generated by dot. For an explanation of the image formats see the section | ||
| 2410 | +# output formats in the documentation of the dot tool (Graphviz (see: | ||
| 2411 | +# http://www.graphviz.org/)). | ||
| 2412 | +# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order | ||
| 2413 | +# to make the SVG files visible in IE 9+ (other browsers do not have this | ||
| 2414 | +# requirement). | ||
| 2415 | +# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo, | ||
| 2416 | +# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and | ||
| 2417 | +# png:gdiplus:gdiplus. | ||
| 2418 | +# The default value is: png. | ||
| 2419 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2420 | + | ||
| 2421 | +DOT_IMAGE_FORMAT = png | ||
| 2422 | + | ||
| 2423 | +# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to | ||
| 2424 | +# enable generation of interactive SVG images that allow zooming and panning. | ||
| 2425 | +# | ||
| 2426 | +# Note that this requires a modern browser other than Internet Explorer. Tested | ||
| 2427 | +# and working are Firefox, Chrome, Safari, and Opera. | ||
| 2428 | +# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make | ||
| 2429 | +# the SVG files visible. Older versions of IE do not have SVG support. | ||
| 2430 | +# The default value is: NO. | ||
| 2431 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2432 | + | ||
| 2433 | +INTERACTIVE_SVG = NO | ||
| 2434 | + | ||
| 2435 | +# The DOT_PATH tag can be used to specify the path where the dot tool can be | ||
| 2436 | +# found. If left blank, it is assumed the dot tool can be found in the path. | ||
| 2437 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2438 | + | ||
| 2439 | +DOT_PATH = | ||
| 2440 | + | ||
| 2441 | +# The DOTFILE_DIRS tag can be used to specify one or more directories that | ||
| 2442 | +# contain dot files that are included in the documentation (see the \dotfile | ||
| 2443 | +# command). | ||
| 2444 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2445 | + | ||
| 2446 | +DOTFILE_DIRS = | ||
| 2447 | + | ||
| 2448 | +# The MSCFILE_DIRS tag can be used to specify one or more directories that | ||
| 2449 | +# contain msc files that are included in the documentation (see the \mscfile | ||
| 2450 | +# command). | ||
| 2451 | + | ||
| 2452 | +MSCFILE_DIRS = | ||
| 2453 | + | ||
| 2454 | +# The DIAFILE_DIRS tag can be used to specify one or more directories that | ||
| 2455 | +# contain dia files that are included in the documentation (see the \diafile | ||
| 2456 | +# command). | ||
| 2457 | + | ||
| 2458 | +DIAFILE_DIRS = | ||
| 2459 | + | ||
| 2460 | +# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the | ||
| 2461 | +# path where java can find the plantuml.jar file. If left blank, it is assumed | ||
| 2462 | +# PlantUML is not used or called during a preprocessing step. Doxygen will | ||
| 2463 | +# generate a warning when it encounters a \startuml command in this case and | ||
| 2464 | +# will not generate output for the diagram. | ||
| 2465 | + | ||
| 2466 | +PLANTUML_JAR_PATH = | ||
| 2467 | + | ||
| 2468 | +# When using plantuml, the PLANTUML_CFG_FILE tag can be used to specify a | ||
| 2469 | +# configuration file for plantuml. | ||
| 2470 | + | ||
| 2471 | +PLANTUML_CFG_FILE = | ||
| 2472 | + | ||
| 2473 | +# When using plantuml, the specified paths are searched for files specified by | ||
| 2474 | +# the !include statement in a plantuml block. | ||
| 2475 | + | ||
| 2476 | +PLANTUML_INCLUDE_PATH = | ||
| 2477 | + | ||
| 2478 | +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes | ||
| 2479 | +# that will be shown in the graph. If the number of nodes in a graph becomes | ||
| 2480 | +# larger than this value, doxygen will truncate the graph, which is visualized | ||
| 2481 | +# by representing a node as a red box. Note that doxygen if the number of direct | ||
| 2482 | +# children of the root node in a graph is already larger than | ||
| 2483 | +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that | ||
| 2484 | +# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. | ||
| 2485 | +# Minimum value: 0, maximum value: 10000, default value: 50. | ||
| 2486 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2487 | + | ||
| 2488 | +DOT_GRAPH_MAX_NODES = 50 | ||
| 2489 | + | ||
| 2490 | +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs | ||
| 2491 | +# generated by dot. A depth value of 3 means that only nodes reachable from the | ||
| 2492 | +# root by following a path via at most 3 edges will be shown. Nodes that lay | ||
| 2493 | +# further from the root node will be omitted. Note that setting this option to 1 | ||
| 2494 | +# or 2 may greatly reduce the computation time needed for large code bases. Also | ||
| 2495 | +# note that the size of a graph can be further restricted by | ||
| 2496 | +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. | ||
| 2497 | +# Minimum value: 0, maximum value: 1000, default value: 0. | ||
| 2498 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2499 | + | ||
| 2500 | +MAX_DOT_GRAPH_DEPTH = 0 | ||
| 2501 | + | ||
| 2502 | +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent | ||
| 2503 | +# background. This is disabled by default, because dot on Windows does not seem | ||
| 2504 | +# to support this out of the box. | ||
| 2505 | +# | ||
| 2506 | +# Warning: Depending on the platform used, enabling this option may lead to | ||
| 2507 | +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to | ||
| 2508 | +# read). | ||
| 2509 | +# The default value is: NO. | ||
| 2510 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2511 | + | ||
| 2512 | +DOT_TRANSPARENT = NO | ||
| 2513 | + | ||
| 2514 | +# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output | ||
| 2515 | +# files in one run (i.e. multiple -o and -T options on the command line). This | ||
| 2516 | +# makes dot run faster, but since only newer versions of dot (>1.8.10) support | ||
| 2517 | +# this, this feature is disabled by default. | ||
| 2518 | +# The default value is: NO. | ||
| 2519 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2520 | + | ||
| 2521 | +DOT_MULTI_TARGETS = NO | ||
| 2522 | + | ||
| 2523 | +# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page | ||
| 2524 | +# explaining the meaning of the various boxes and arrows in the dot generated | ||
| 2525 | +# graphs. | ||
| 2526 | +# The default value is: YES. | ||
| 2527 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2528 | + | ||
| 2529 | +GENERATE_LEGEND = YES | ||
| 2530 | + | ||
| 2531 | +# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot | ||
| 2532 | +# files that are used to generate the various graphs. | ||
| 2533 | +# The default value is: YES. | ||
| 2534 | +# This tag requires that the tag HAVE_DOT is set to YES. | ||
| 2535 | + | ||
| 2536 | +DOT_CLEANUP = YES |
src/qmqtt.cpp
0 → 100644
| 1 | +++ a/src/qmqtt.cpp | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#include "qmqtt.h" | ||
| 23 | +#include "log.h" | ||
| 24 | + | ||
| 25 | +using namespace osdev::components; | ||
| 26 | + | ||
| 27 | +QMQTTClient::QMQTTClient( const QMqttConfigSettings& connectionSettings, QObject *parent ) | ||
| 28 | + : QObject(parent) | ||
| 29 | + , m_qhConnections() | ||
| 30 | + , m_connConfig( connectionSettings ) | ||
| 31 | +{ | ||
| 32 | + | ||
| 33 | +} | ||
| 34 | + | ||
| 35 | +QMQTTClient::~QMQTTClient() | ||
| 36 | +{ | ||
| 37 | + // Clean up any connections we have. | ||
| 38 | + for( auto key : m_qhConnections.keys()) | ||
| 39 | + { | ||
| 40 | + QPointer<QMqttPubSubClient> pTemp = m_qhConnections.take( key ); | ||
| 41 | + if(pTemp) | ||
| 42 | + { | ||
| 43 | + delete pTemp.data(); | ||
| 44 | + } | ||
| 45 | + } | ||
| 46 | +} | ||
| 47 | + | ||
| 48 | +void QMQTTClient::subscribe( const QString& mqtt_topic ) | ||
| 49 | +{ | ||
| 50 | + if(!topicExists( mqtt_topic ) ) | ||
| 51 | + { | ||
| 52 | + if( !createNewThread( mqtt_topic ) ) | ||
| 53 | + { | ||
| 54 | + LogError("[QMQTTClient::subscribe]", QString("There was an error creating a subscription to : %1").arg(mqtt_topic)); | ||
| 55 | + } | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + if( topicExists( mqtt_topic ) ) | ||
| 59 | + { | ||
| 60 | + m_qhConnections.value( mqtt_topic )->subscribe( mqtt_topic ); | ||
| 61 | + } | ||
| 62 | +} | ||
| 63 | + | ||
| 64 | +void QMQTTClient::unsubscribe(const QString& mqtt_topic) | ||
| 65 | +{ | ||
| 66 | + if( topicExists( mqtt_topic ) ) | ||
| 67 | + { | ||
| 68 | + m_qhConnections.value( mqtt_topic )->unsubscribe( mqtt_topic ); | ||
| 69 | + } | ||
| 70 | +} | ||
| 71 | + | ||
| 72 | +void QMQTTClient::publish(const QString& mqtt_topic, const QString& mqtt_message) | ||
| 73 | +{ | ||
| 74 | + if( !topicExists( mqtt_topic ) ) | ||
| 75 | + { | ||
| 76 | + if( !createNewThread( mqtt_topic ) ) | ||
| 77 | + { | ||
| 78 | + LogError("[QMQTTClient::publish]", QString("There was an error creating publishing to : %1").arg( mqtt_topic ) ); | ||
| 79 | + } | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + if(topicExists(mqtt_topic)) | ||
| 83 | + { | ||
| 84 | + m_qhConnections.value(mqtt_topic)->publish(mqtt_topic, mqtt_message); | ||
| 85 | + } | ||
| 86 | +} | ||
| 87 | + | ||
| 88 | +bool QMQTTClient::createNewThread(const QString& topic) | ||
| 89 | +{ | ||
| 90 | + QPointer<QMqttPubSubClient> pThread = new QMqttPubSubClient(m_connConfig.getHostAddress(), m_connConfig.getPortNumber() ); | ||
| 91 | + if(pThread) | ||
| 92 | + { | ||
| 93 | + connect( pThread.data(), &QMqttPubSubClient::signalMessageReceived, this, &QMQTTClient::signalNewMessageReceived ); | ||
| 94 | + connect( pThread.data(), &QMqttPubSubClient::signalReInitialise, this, &QMQTTClient::signalReInitialize ); | ||
| 95 | + m_qhConnections.insert( topic, pThread ); | ||
| 96 | + } | ||
| 97 | + return m_qhConnections.contains( topic ); | ||
| 98 | +} | ||
| 99 | + | ||
| 100 | +bool QMQTTClient::topicExists( const QString& topic ) | ||
| 101 | +{ | ||
| 102 | + if( m_qhConnections.contains( topic ) ) | ||
| 103 | + return true; | ||
| 104 | + else | ||
| 105 | + return false; | ||
| 106 | +} |
src/qmqtt.h
0 → 100644
| 1 | +++ a/src/qmqtt.h | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifndef OSDEV_COMPONENTS_QMQTT_H | ||
| 23 | +#define OSDEV_COMPONENTS_QMQTT_H | ||
| 24 | + | ||
| 25 | +#include <QObject> | ||
| 26 | +#include <QString> | ||
| 27 | +#include <QHash> | ||
| 28 | +#include <QPointer> | ||
| 29 | + | ||
| 30 | +#include "qmqtt_pubsubclient.h" | ||
| 31 | +#include "qmqtt_configsettings.h" | ||
| 32 | + | ||
| 33 | +namespace osdev { | ||
| 34 | +namespace components { | ||
| 35 | + | ||
| 36 | +class QMQTTClient : public QObject | ||
| 37 | +{ | ||
| 38 | + Q_OBJECT | ||
| 39 | + | ||
| 40 | +public: | ||
| 41 | + QMQTTClient( const QMqttConfigSettings& connectionSettings = QMqttConfigSettings(), QObject *parent = nullptr ); | ||
| 42 | + virtual ~QMQTTClient(); | ||
| 43 | + | ||
| 44 | + void subscribe( const QString& mqtt_topic ); | ||
| 45 | + void unsubscribe( const QString& mqtt_topic ); | ||
| 46 | + void publish( const QString& mqtt_topic, const QString& mqtt_message ); | ||
| 47 | + | ||
| 48 | + int getNumberOfConnections(){ return m_qhConnections.count(); } | ||
| 49 | + | ||
| 50 | +signals: | ||
| 51 | + void signalNewMessageReceived( const QString& mqtt_topic, const QString& mqtt_message ); | ||
| 52 | + void signalReInitialize(); | ||
| 53 | + | ||
| 54 | +private: | ||
| 55 | + bool topicExists( const QString& topic ); | ||
| 56 | + bool createNewThread( const QString& topic ); | ||
| 57 | + | ||
| 58 | +private: // Members (Giggity!) | ||
| 59 | + QHash<QString, QPointer<QMqttPubSubClient>> m_qhConnections; ///< The container that keeps track of all connections by their topics. | ||
| 60 | + QMqttConfigSettings m_connConfig; ///< All kinds of connection parameters in a convenient object. | ||
| 61 | + | ||
| 62 | +}; | ||
| 63 | + | ||
| 64 | +} /* End namespace components */ | ||
| 65 | +} /* End namespace osdev */ | ||
| 66 | + | ||
| 67 | +#endif /* OSDEV_COMPONENTS_QMQTT_H */ |
src/qmqtt_client.cpp
0 → 100644
| 1 | +++ a/src/qmqtt_client.cpp | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#include "qmqtt_client.h" | ||
| 23 | +#include "qmqtt_client_p.h" | ||
| 24 | + | ||
| 25 | +QMQTT::Client::Client(const QHostAddress& host, | ||
| 26 | + const quint16 port, | ||
| 27 | + QObject* parent) | ||
| 28 | + : QObject(parent) | ||
| 29 | + , d_ptr(new ClientPrivate(this)) | ||
| 30 | +{ | ||
| 31 | + Q_D(Client); | ||
| 32 | + d->init(host, port); | ||
| 33 | +} | ||
| 34 | + | ||
| 35 | +#ifndef QT_NO_SSL | ||
| 36 | +QMQTT::Client::Client(const QString &hostName, | ||
| 37 | + const quint16 port, | ||
| 38 | + const QSslConfiguration &config, | ||
| 39 | + const bool ignoreSelfSigned, QObject *parent) | ||
| 40 | + : QObject(parent) | ||
| 41 | + , d_ptr(new ClientPrivate(this)) | ||
| 42 | +{ | ||
| 43 | + Q_D(Client); | ||
| 44 | + d->init(hostName, port, config, ignoreSelfSigned); | ||
| 45 | +} | ||
| 46 | +#endif // QT_NO_SSL | ||
| 47 | + | ||
| 48 | +QMQTT::Client::Client(const QString &hostName, | ||
| 49 | + const quint16 port, | ||
| 50 | + const bool ssl, | ||
| 51 | + const bool ignoreSelfSigned, | ||
| 52 | + QObject* parent) | ||
| 53 | + : QObject(parent) | ||
| 54 | + , d_ptr(new ClientPrivate(this)) | ||
| 55 | +{ | ||
| 56 | + Q_D(Client); | ||
| 57 | + d->init(hostName, port, ssl, ignoreSelfSigned); | ||
| 58 | +} | ||
| 59 | + | ||
| 60 | +#ifdef QT_WEBSOCKETS_LIB | ||
| 61 | +QMQTT::Client::Client(const QString& url, | ||
| 62 | + const QString& origin, | ||
| 63 | + QWebSocketProtocol::Version version, | ||
| 64 | + bool ignoreSelfSigned, | ||
| 65 | + QObject* parent) | ||
| 66 | + : QObject(parent) | ||
| 67 | + , d_ptr(new ClientPrivate(this)) | ||
| 68 | +{ | ||
| 69 | + Q_D(Client); | ||
| 70 | +#ifndef QT_NO_SSL | ||
| 71 | + d->init(url, origin, version, NULL, ignoreSelfSigned); | ||
| 72 | +#else | ||
| 73 | + Q_UNUSED(ignoreSelfSigned) | ||
| 74 | + d->init(url, origin, version); | ||
| 75 | +#endif // QT_NO_SSL | ||
| 76 | +} | ||
| 77 | + | ||
| 78 | +#ifndef QT_NO_SSL | ||
| 79 | +QMQTT::Client::Client(const QString& url, | ||
| 80 | + const QString& origin, | ||
| 81 | + QWebSocketProtocol::Version version, | ||
| 82 | + const QSslConfiguration& sslConfig, | ||
| 83 | + const bool ignoreSelfSigned, | ||
| 84 | + QObject* parent) | ||
| 85 | + : QObject(parent) | ||
| 86 | + , d_ptr(new ClientPrivate(this)) | ||
| 87 | +{ | ||
| 88 | + Q_D(Client); | ||
| 89 | + d->init(url, origin, version, &sslConfig, ignoreSelfSigned); | ||
| 90 | +} | ||
| 91 | +#endif // QT_NO_SSL | ||
| 92 | +#endif // QT_WEBSOCKETS_LIB | ||
| 93 | + | ||
| 94 | +QMQTT::Client::Client(NetworkInterface* network, | ||
| 95 | + const QHostAddress& host, | ||
| 96 | + const quint16 port, | ||
| 97 | + QObject* parent) | ||
| 98 | + : QObject(parent) | ||
| 99 | + , d_ptr(new ClientPrivate(this)) | ||
| 100 | +{ | ||
| 101 | + Q_D(Client); | ||
| 102 | + d->init(host, port, network); | ||
| 103 | +} | ||
| 104 | + | ||
| 105 | +QMQTT::Client::~Client() | ||
| 106 | +{ | ||
| 107 | +} | ||
| 108 | + | ||
| 109 | +QHostAddress QMQTT::Client::host() const | ||
| 110 | +{ | ||
| 111 | + Q_D(const Client); | ||
| 112 | + return d->host(); | ||
| 113 | +} | ||
| 114 | + | ||
| 115 | +void QMQTT::Client::setHost(const QHostAddress& host) | ||
| 116 | +{ | ||
| 117 | + Q_D(Client); | ||
| 118 | + d->setHost(host); | ||
| 119 | +} | ||
| 120 | + | ||
| 121 | +QString QMQTT::Client::hostName() const | ||
| 122 | +{ | ||
| 123 | + Q_D(const Client); | ||
| 124 | + return d->hostName(); | ||
| 125 | +} | ||
| 126 | + | ||
| 127 | +void QMQTT::Client::setHostName(const QString &hostName) | ||
| 128 | +{ | ||
| 129 | + Q_D(Client); | ||
| 130 | + d->setHostName(hostName); | ||
| 131 | +} | ||
| 132 | + | ||
| 133 | +quint16 QMQTT::Client::port() const | ||
| 134 | +{ | ||
| 135 | + Q_D(const Client); | ||
| 136 | + return d->port(); | ||
| 137 | +} | ||
| 138 | + | ||
| 139 | +void QMQTT::Client::setPort(const quint16 port) | ||
| 140 | +{ | ||
| 141 | + Q_D(Client); | ||
| 142 | + d->setPort(port); | ||
| 143 | +} | ||
| 144 | + | ||
| 145 | +QString QMQTT::Client::clientId() const | ||
| 146 | +{ | ||
| 147 | + Q_D(const Client); | ||
| 148 | + return d->clientId(); | ||
| 149 | +} | ||
| 150 | + | ||
| 151 | +void QMQTT::Client::setClientId(const QString& clientId) | ||
| 152 | +{ | ||
| 153 | + Q_D(Client); | ||
| 154 | + d->setClientId(clientId); | ||
| 155 | +} | ||
| 156 | + | ||
| 157 | +QString QMQTT::Client::username() const | ||
| 158 | +{ | ||
| 159 | + Q_D(const Client); | ||
| 160 | + return d->username(); | ||
| 161 | +} | ||
| 162 | + | ||
| 163 | +void QMQTT::Client::setUsername(const QString& username) | ||
| 164 | +{ | ||
| 165 | + Q_D(Client); | ||
| 166 | + d->setUsername(username); | ||
| 167 | +} | ||
| 168 | + | ||
| 169 | +QMQTT::MQTTVersion QMQTT::Client::version() const | ||
| 170 | +{ | ||
| 171 | + Q_D(const Client); | ||
| 172 | + return d->version(); | ||
| 173 | +} | ||
| 174 | + | ||
| 175 | +void QMQTT::Client::setVersion(const QMQTT::MQTTVersion version) | ||
| 176 | +{ | ||
| 177 | + Q_D(Client); | ||
| 178 | + d->setVersion(version); | ||
| 179 | +} | ||
| 180 | + | ||
| 181 | +QByteArray QMQTT::Client::password() const | ||
| 182 | +{ | ||
| 183 | + Q_D(const Client); | ||
| 184 | + return d->password(); | ||
| 185 | +} | ||
| 186 | + | ||
| 187 | +void QMQTT::Client::setPassword(const QByteArray &password) | ||
| 188 | +{ | ||
| 189 | + Q_D(Client); | ||
| 190 | + d->setPassword(password); | ||
| 191 | +} | ||
| 192 | + | ||
| 193 | +quint16 QMQTT::Client::keepAlive() const | ||
| 194 | +{ | ||
| 195 | + Q_D(const Client); | ||
| 196 | + return d->keepAlive(); | ||
| 197 | +} | ||
| 198 | + | ||
| 199 | +void QMQTT::Client::setKeepAlive(const quint16 keepAlive) | ||
| 200 | +{ | ||
| 201 | + Q_D(Client); | ||
| 202 | + d->setKeepAlive(keepAlive); | ||
| 203 | +} | ||
| 204 | + | ||
| 205 | +bool QMQTT::Client::cleanSession() const | ||
| 206 | +{ | ||
| 207 | + Q_D(const Client); | ||
| 208 | + return d->cleanSession(); | ||
| 209 | +} | ||
| 210 | + | ||
| 211 | +void QMQTT::Client::setCleanSession(const bool cleanSession) | ||
| 212 | +{ | ||
| 213 | + Q_D(Client); | ||
| 214 | + d->setCleanSession(cleanSession); | ||
| 215 | +} | ||
| 216 | + | ||
| 217 | +bool QMQTT::Client::autoReconnect() const | ||
| 218 | +{ | ||
| 219 | + Q_D(const Client); | ||
| 220 | + return d->autoReconnect(); | ||
| 221 | +} | ||
| 222 | + | ||
| 223 | +void QMQTT::Client::setAutoReconnect(const bool value) | ||
| 224 | +{ | ||
| 225 | + Q_D(Client); | ||
| 226 | + d->setAutoReconnect(value); | ||
| 227 | +} | ||
| 228 | + | ||
| 229 | +int QMQTT::Client::autoReconnectInterval() const | ||
| 230 | +{ | ||
| 231 | + Q_D(const Client); | ||
| 232 | + return d->autoReconnectInterval(); | ||
| 233 | +} | ||
| 234 | + | ||
| 235 | +void QMQTT::Client::setAutoReconnectInterval(const int autoReconnectInterval) | ||
| 236 | +{ | ||
| 237 | + Q_D(Client); | ||
| 238 | + d->setAutoReconnectInterval(autoReconnectInterval); | ||
| 239 | +} | ||
| 240 | + | ||
| 241 | +QString QMQTT::Client::willTopic() const | ||
| 242 | +{ | ||
| 243 | + Q_D(const Client); | ||
| 244 | + return d->willTopic(); | ||
| 245 | +} | ||
| 246 | + | ||
| 247 | +void QMQTT::Client::setWillTopic(const QString& willTopic) | ||
| 248 | +{ | ||
| 249 | + Q_D(Client); | ||
| 250 | + d->setWillTopic(willTopic); | ||
| 251 | +} | ||
| 252 | + | ||
| 253 | +quint8 QMQTT::Client::willQos() const | ||
| 254 | +{ | ||
| 255 | + Q_D(const Client); | ||
| 256 | + return d->willQos(); | ||
| 257 | +} | ||
| 258 | + | ||
| 259 | +void QMQTT::Client::setWillQos(const quint8 willQos) | ||
| 260 | +{ | ||
| 261 | + Q_D(Client); | ||
| 262 | + d->setWillQos(willQos); | ||
| 263 | +} | ||
| 264 | + | ||
| 265 | +bool QMQTT::Client::willRetain() const | ||
| 266 | +{ | ||
| 267 | + Q_D(const Client); | ||
| 268 | + return d->willRetain(); | ||
| 269 | +} | ||
| 270 | + | ||
| 271 | +void QMQTT::Client::setWillRetain(const bool willRetain) | ||
| 272 | +{ | ||
| 273 | + Q_D(Client); | ||
| 274 | + d->setWillRetain(willRetain); | ||
| 275 | +} | ||
| 276 | + | ||
| 277 | +QByteArray QMQTT::Client::willMessage() const | ||
| 278 | +{ | ||
| 279 | + Q_D(const Client); | ||
| 280 | + return d->willMessage(); | ||
| 281 | +} | ||
| 282 | + | ||
| 283 | +void QMQTT::Client::setWillMessage(const QByteArray &willMessage) | ||
| 284 | +{ | ||
| 285 | + Q_D(Client); | ||
| 286 | + d->setWillMessage(willMessage); | ||
| 287 | +} | ||
| 288 | + | ||
| 289 | +QMQTT::ConnectionState QMQTT::Client::connectionState() const | ||
| 290 | +{ | ||
| 291 | + Q_D(const Client); | ||
| 292 | + return d->connectionState(); | ||
| 293 | +} | ||
| 294 | + | ||
| 295 | +bool QMQTT::Client::isConnectedToHost() const | ||
| 296 | +{ | ||
| 297 | + Q_D(const Client); | ||
| 298 | + return d->isConnectedToHost(); | ||
| 299 | +} | ||
| 300 | + | ||
| 301 | +#ifndef QT_NO_SSL | ||
| 302 | +QSslConfiguration QMQTT::Client::sslConfiguration() const | ||
| 303 | +{ | ||
| 304 | + Q_D(const Client); | ||
| 305 | + return d->sslConfiguration(); | ||
| 306 | +} | ||
| 307 | + | ||
| 308 | +void QMQTT::Client::setSslConfiguration(const QSslConfiguration& config) | ||
| 309 | +{ | ||
| 310 | + Q_D(Client); | ||
| 311 | + d->setSslConfiguration(config); | ||
| 312 | +} | ||
| 313 | +#endif // QT_NO_SSL | ||
| 314 | + | ||
| 315 | +void QMQTT::Client::connectToHost() | ||
| 316 | +{ | ||
| 317 | + Q_D(Client); | ||
| 318 | + d->connectToHost(); | ||
| 319 | +} | ||
| 320 | + | ||
| 321 | +void QMQTT::Client::onNetworkConnected() | ||
| 322 | +{ | ||
| 323 | + Q_D(Client); | ||
| 324 | + d->onNetworkConnected(); | ||
| 325 | +} | ||
| 326 | + | ||
| 327 | +quint16 QMQTT::Client::publish(const Message& message) | ||
| 328 | +{ | ||
| 329 | + Q_D(Client); | ||
| 330 | + return d->publish(message); | ||
| 331 | +} | ||
| 332 | + | ||
| 333 | +void QMQTT::Client::subscribe(const QString& topic, const quint8 qos) | ||
| 334 | +{ | ||
| 335 | + Q_D(Client); | ||
| 336 | + d->subscribe(topic, qos); | ||
| 337 | +} | ||
| 338 | + | ||
| 339 | +void QMQTT::Client::unsubscribe(const QString& topic) | ||
| 340 | +{ | ||
| 341 | + Q_D(Client); | ||
| 342 | + d->unsubscribe(topic); | ||
| 343 | +} | ||
| 344 | + | ||
| 345 | +void QMQTT::Client::onTimerPingReq() | ||
| 346 | +{ | ||
| 347 | + Q_D(Client); | ||
| 348 | + d->onTimerPingReq(); | ||
| 349 | +} | ||
| 350 | + | ||
| 351 | +void QMQTT::Client::onPingTimeout() | ||
| 352 | +{ | ||
| 353 | + Q_D(Client); | ||
| 354 | + d->onPingTimeout(); | ||
| 355 | +} | ||
| 356 | + | ||
| 357 | +void QMQTT::Client::disconnectFromHost() | ||
| 358 | +{ | ||
| 359 | + Q_D(Client); | ||
| 360 | + d->disconnectFromHost(); | ||
| 361 | +} | ||
| 362 | + | ||
| 363 | +void QMQTT::Client::onNetworkReceived(const QMQTT::Frame& frame) | ||
| 364 | +{ | ||
| 365 | + Q_D(Client); | ||
| 366 | + d->onNetworkReceived(frame); | ||
| 367 | +} | ||
| 368 | + | ||
| 369 | +void QMQTT::Client::onNetworkDisconnected() | ||
| 370 | +{ | ||
| 371 | + Q_D(Client); | ||
| 372 | + d->onNetworkDisconnected(); | ||
| 373 | +} | ||
| 374 | + | ||
| 375 | +void QMQTT::Client::onNetworkError(QAbstractSocket::SocketError error) | ||
| 376 | +{ | ||
| 377 | + Q_D(Client); | ||
| 378 | + d->onNetworkError(error); | ||
| 379 | +} | ||
| 380 | + | ||
| 381 | +#ifndef QT_NO_SSL | ||
| 382 | +void QMQTT::Client::onSslErrors(const QList<QSslError>& errors) | ||
| 383 | +{ | ||
| 384 | + Q_D(Client); | ||
| 385 | + d->onSslErrors(errors); | ||
| 386 | +} | ||
| 387 | +#endif // QT_NO_SSL | ||
| 388 | + | ||
| 389 | +#ifndef QT_NO_SSL | ||
| 390 | +void QMQTT::Client::ignoreSslErrors() | ||
| 391 | +{ | ||
| 392 | + Q_D(Client); | ||
| 393 | + d->ignoreSslErrors(); | ||
| 394 | +} | ||
| 395 | + | ||
| 396 | +void QMQTT::Client::ignoreSslErrors(const QList<QSslError>& errors) | ||
| 397 | +{ | ||
| 398 | + Q_D(Client); | ||
| 399 | + d->ignoreSslErrors(errors); | ||
| 400 | +} | ||
| 401 | +#endif // QT_NO_SSL |
src/qmqtt_client.h
0 → 100644
| 1 | +++ a/src/qmqtt_client.h | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifndef QMQTT_CLIENT_H | ||
| 23 | +#define QMQTT_CLIENT_H | ||
| 24 | + | ||
| 25 | +#include "qmqtt_global.h" | ||
| 26 | + | ||
| 27 | +#include <QObject> | ||
| 28 | +#include <QString> | ||
| 29 | +#include <QHostAddress> | ||
| 30 | +#include <QByteArray> | ||
| 31 | +#include <QAbstractSocket> | ||
| 32 | +#include <QScopedPointer> | ||
| 33 | +#include <QList> | ||
| 34 | + | ||
| 35 | +#ifdef QT_WEBSOCKETS_LIB | ||
| 36 | +#include <QWebSocket> | ||
| 37 | +#endif // QT_WEBSOCKETS_LIB | ||
| 38 | + | ||
| 39 | +#ifndef QT_NO_SSL | ||
| 40 | +#include <QSslConfiguration> | ||
| 41 | +QT_FORWARD_DECLARE_CLASS(QSslError) | ||
| 42 | +#endif // QT_NO_SSL | ||
| 43 | + | ||
| 44 | +#ifndef Q_ENUM_NS | ||
| 45 | +#define Q_ENUM_NS(x) | ||
| 46 | +#endif // Q_ENUM_NS | ||
| 47 | + | ||
| 48 | +namespace QMQTT { | ||
| 49 | +#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0)) | ||
| 50 | +Q_MQTT_EXPORT Q_NAMESPACE | ||
| 51 | +#endif | ||
| 52 | + | ||
| 53 | +static const quint8 LIBRARY_VERSION_MAJOR = 0; | ||
| 54 | +static const quint8 LIBRARY_VERSION_MINOR = 3; | ||
| 55 | +static const quint8 LIBRARY_VERSION_REVISION = 1; | ||
| 56 | +//static const char* LIBRARY_VERSION = "0.3.1"; | ||
| 57 | + | ||
| 58 | +enum MQTTVersion | ||
| 59 | +{ | ||
| 60 | + V3_1_0 = 3, | ||
| 61 | + V3_1_1 = 4 | ||
| 62 | +}; | ||
| 63 | +Q_ENUM_NS(MQTTVersion) | ||
| 64 | + | ||
| 65 | +enum ConnectionState | ||
| 66 | +{ | ||
| 67 | + STATE_INIT = 0, | ||
| 68 | + STATE_CONNECTING, | ||
| 69 | + STATE_CONNECTED, | ||
| 70 | + STATE_DISCONNECTED | ||
| 71 | +}; | ||
| 72 | +Q_ENUM_NS(ConnectionState) | ||
| 73 | + | ||
| 74 | +enum ClientError | ||
| 75 | +{ | ||
| 76 | + UnknownError = 0, | ||
| 77 | + SocketConnectionRefusedError, | ||
| 78 | + SocketRemoteHostClosedError, | ||
| 79 | + SocketHostNotFoundError, | ||
| 80 | + SocketAccessError, | ||
| 81 | + SocketResourceError, | ||
| 82 | + SocketTimeoutError, | ||
| 83 | + SocketDatagramTooLargeError, | ||
| 84 | + SocketNetworkError, | ||
| 85 | + SocketAddressInUseError, | ||
| 86 | + SocketAddressNotAvailableError, | ||
| 87 | + SocketUnsupportedSocketOperationError, | ||
| 88 | + SocketUnfinishedSocketOperationError, | ||
| 89 | + SocketProxyAuthenticationRequiredError, | ||
| 90 | + SocketSslHandshakeFailedError, | ||
| 91 | + SocketProxyConnectionRefusedError, | ||
| 92 | + SocketProxyConnectionClosedError, | ||
| 93 | + SocketProxyConnectionTimeoutError, | ||
| 94 | + SocketProxyNotFoundError, | ||
| 95 | + SocketProxyProtocolError, | ||
| 96 | + SocketOperationError, | ||
| 97 | + SocketSslInternalError, | ||
| 98 | + SocketSslInvalidUserDataError, | ||
| 99 | + SocketTemporaryError, | ||
| 100 | + MqttUnacceptableProtocolVersionError=1<<16, | ||
| 101 | + MqttIdentifierRejectedError, | ||
| 102 | + MqttServerUnavailableError, | ||
| 103 | + MqttBadUserNameOrPasswordError, | ||
| 104 | + MqttNotAuthorizedError, | ||
| 105 | + MqttNoPingResponse | ||
| 106 | +}; | ||
| 107 | +Q_ENUM_NS(ClientError) | ||
| 108 | + | ||
| 109 | +class ClientPrivate; | ||
| 110 | +class Message; | ||
| 111 | +class Frame; | ||
| 112 | +class NetworkInterface; | ||
| 113 | + | ||
| 114 | +class Q_MQTT_EXPORT Client : public QObject | ||
| 115 | +{ | ||
| 116 | + Q_OBJECT | ||
| 117 | + Q_PROPERTY(quint16 _port READ port WRITE setPort) | ||
| 118 | + Q_PROPERTY(QHostAddress _host READ host WRITE setHost) | ||
| 119 | + Q_PROPERTY(QString _hostName READ hostName WRITE setHostName) | ||
| 120 | + Q_PROPERTY(QString _clientId READ clientId WRITE setClientId) | ||
| 121 | + Q_PROPERTY(QString _username READ username WRITE setUsername) | ||
| 122 | + Q_PROPERTY(QByteArray _password READ password WRITE setPassword) | ||
| 123 | + Q_PROPERTY(quint16 _keepAlive READ keepAlive WRITE setKeepAlive) | ||
| 124 | + Q_PROPERTY(MQTTVersion _version READ version WRITE setVersion) | ||
| 125 | + Q_PROPERTY(bool _autoReconnect READ autoReconnect WRITE setAutoReconnect) | ||
| 126 | + Q_PROPERTY(int _autoReconnectInterval READ autoReconnectInterval WRITE setAutoReconnectInterval) | ||
| 127 | + Q_PROPERTY(bool _cleanSession READ cleanSession WRITE setCleanSession) | ||
| 128 | + Q_PROPERTY(QString _willTopic READ willTopic WRITE setWillTopic) | ||
| 129 | + Q_PROPERTY(quint8 _willQos READ willQos WRITE setWillQos) | ||
| 130 | + Q_PROPERTY(bool _willRetain READ willRetain WRITE setWillRetain) | ||
| 131 | + Q_PROPERTY(QByteArray _willMessage READ willMessage WRITE setWillMessage) | ||
| 132 | + Q_PROPERTY(QString _connectionState READ connectionState) | ||
| 133 | +#ifndef QT_NO_SSL | ||
| 134 | + Q_PROPERTY(QSslConfiguration _sslConfiguration READ sslConfiguration WRITE setSslConfiguration) | ||
| 135 | +#endif // QT_NO_SSL | ||
| 136 | + | ||
| 137 | +public: | ||
| 138 | + Client(const QHostAddress& host = QHostAddress::LocalHost, | ||
| 139 | + const quint16 port = 1883, | ||
| 140 | + QObject* parent = NULL); | ||
| 141 | + | ||
| 142 | +#ifndef QT_NO_SSL | ||
| 143 | + Client(const QString& hostName, | ||
| 144 | + const quint16 port, | ||
| 145 | + const QSslConfiguration& config, | ||
| 146 | + const bool ignoreSelfSigned=false, | ||
| 147 | + QObject* parent = NULL); | ||
| 148 | +#endif // QT_NO_SSL | ||
| 149 | + | ||
| 150 | + // This function is provided for backward compatibility with older versions of QMQTT. | ||
| 151 | + // If the ssl parameter is true, this function will load a private key ('cert.key') and a local | ||
| 152 | + // certificate ('cert.crt') from the current working directory. It will also set PeerVerifyMode | ||
| 153 | + // to None. This may not be the safest way to set up an SSL connection. | ||
| 154 | + Client(const QString& hostName, | ||
| 155 | + const quint16 port, | ||
| 156 | + const bool ssl, | ||
| 157 | + const bool ignoreSelfSigned, | ||
| 158 | + QObject* parent = NULL); | ||
| 159 | + | ||
| 160 | +#ifdef QT_WEBSOCKETS_LIB | ||
| 161 | + // Create a connection over websockets | ||
| 162 | + Client(const QString& url, | ||
| 163 | + const QString& origin, | ||
| 164 | + QWebSocketProtocol::Version version, | ||
| 165 | + bool ignoreSelfSigned = false, | ||
| 166 | + QObject* parent = NULL); | ||
| 167 | + | ||
| 168 | +#ifndef QT_NO_SSL | ||
| 169 | + Client(const QString& url, | ||
| 170 | + const QString& origin, | ||
| 171 | + QWebSocketProtocol::Version version, | ||
| 172 | + const QSslConfiguration& config, | ||
| 173 | + const bool ignoreSelfSigned = false, | ||
| 174 | + QObject* parent = NULL); | ||
| 175 | +#endif // QT_NO_SSL | ||
| 176 | +#endif // QT_WEBSOCKETS_LIB | ||
| 177 | + | ||
| 178 | + // for testing purposes only | ||
| 179 | + Client(NetworkInterface* network, | ||
| 180 | + const QHostAddress& host = QHostAddress::LocalHost, | ||
| 181 | + const quint16 port = 1883, | ||
| 182 | + QObject* parent = NULL); | ||
| 183 | + | ||
| 184 | + virtual ~Client(); | ||
| 185 | + | ||
| 186 | + QHostAddress host() const; | ||
| 187 | + QString hostName() const; | ||
| 188 | + quint16 port() const; | ||
| 189 | + QString clientId() const; | ||
| 190 | + QString username() const; | ||
| 191 | + QByteArray password() const; | ||
| 192 | + QMQTT::MQTTVersion version() const; | ||
| 193 | + quint16 keepAlive() const; | ||
| 194 | + bool cleanSession() const; | ||
| 195 | + bool autoReconnect() const; | ||
| 196 | + int autoReconnectInterval() const; | ||
| 197 | + ConnectionState connectionState() const; | ||
| 198 | + QString willTopic() const; | ||
| 199 | + quint8 willQos() const; | ||
| 200 | + bool willRetain() const; | ||
| 201 | + QByteArray willMessage() const; | ||
| 202 | + | ||
| 203 | + bool isConnectedToHost() const; | ||
| 204 | +#ifndef QT_NO_SSL | ||
| 205 | + QSslConfiguration sslConfiguration() const; | ||
| 206 | + void setSslConfiguration(const QSslConfiguration& config); | ||
| 207 | +#endif // QT_NO_SSL | ||
| 208 | + | ||
| 209 | +public slots: | ||
| 210 | + void setHost(const QHostAddress& host); | ||
| 211 | + void setHostName(const QString& hostName); | ||
| 212 | + void setPort(const quint16 port); | ||
| 213 | + void setClientId(const QString& clientId); | ||
| 214 | + void setUsername(const QString& username); | ||
| 215 | + void setPassword(const QByteArray& password); | ||
| 216 | + void setVersion(const MQTTVersion version); | ||
| 217 | + void setKeepAlive(const quint16 keepAlive); | ||
| 218 | + void setCleanSession(const bool cleanSession); | ||
| 219 | + void setAutoReconnect(const bool value); | ||
| 220 | + void setAutoReconnectInterval(const int autoReconnectInterval); | ||
| 221 | + void setWillTopic(const QString& willTopic); | ||
| 222 | + void setWillQos(const quint8 willQos); | ||
| 223 | + void setWillRetain(const bool willRetain); | ||
| 224 | + void setWillMessage(const QByteArray& willMessage); | ||
| 225 | + | ||
| 226 | + void connectToHost(); | ||
| 227 | + void disconnectFromHost(); | ||
| 228 | + | ||
| 229 | + void subscribe(const QString& topic, const quint8 qos = 0); | ||
| 230 | + void unsubscribe(const QString& topic); | ||
| 231 | + | ||
| 232 | + quint16 publish(const QMQTT::Message& message); | ||
| 233 | + | ||
| 234 | +#ifndef QT_NO_SSL | ||
| 235 | + void ignoreSslErrors(); | ||
| 236 | + void ignoreSslErrors(const QList<QSslError>& errors); | ||
| 237 | +#endif // QT_NO_SSL | ||
| 238 | + | ||
| 239 | +signals: | ||
| 240 | + void connected(); | ||
| 241 | + void disconnected(); | ||
| 242 | + void error(const QMQTT::ClientError error); | ||
| 243 | + | ||
| 244 | + void subscribed(const QString& topic, const quint8 qos = 0); | ||
| 245 | + void unsubscribed(const QString& topic); | ||
| 246 | + void published(const QMQTT::Message& message, quint16 msgid = 0); | ||
| 247 | + void received(const QMQTT::Message& message); | ||
| 248 | + void pingresp(); | ||
| 249 | +#ifndef QT_NO_SSL | ||
| 250 | + void sslErrors(const QList<QSslError>& errors); | ||
| 251 | +#endif // QT_NO_SSL | ||
| 252 | + | ||
| 253 | +protected slots: | ||
| 254 | + void onNetworkConnected(); | ||
| 255 | + void onNetworkDisconnected(); | ||
| 256 | + void onNetworkReceived(const QMQTT::Frame& frame); | ||
| 257 | + void onTimerPingReq(); | ||
| 258 | + void onPingTimeout(); | ||
| 259 | + void onNetworkError(QAbstractSocket::SocketError error); | ||
| 260 | +#ifndef QT_NO_SSL | ||
| 261 | + void onSslErrors(const QList<QSslError>& errors); | ||
| 262 | +#endif // QT_NO_SSL | ||
| 263 | + | ||
| 264 | +protected: | ||
| 265 | + QScopedPointer<ClientPrivate> d_ptr; | ||
| 266 | + | ||
| 267 | +private: | ||
| 268 | + Q_DISABLE_COPY(Client) | ||
| 269 | + Q_DECLARE_PRIVATE(Client) | ||
| 270 | +}; | ||
| 271 | + | ||
| 272 | +} // namespace QMQTT | ||
| 273 | + | ||
| 274 | +Q_DECLARE_METATYPE(QMQTT::ClientError) | ||
| 275 | + | ||
| 276 | +#endif // QMQTT_CLIENT_H |
src/qmqtt_client_p.cpp
0 → 100644
| 1 | +++ a/src/qmqtt_client_p.cpp | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#include "qmqtt_client_p.h" | ||
| 23 | +#include "qmqtt_network_p.h" | ||
| 24 | +#include "qmqtt_frame.h" | ||
| 25 | +#include "qmqtt_message.h" | ||
| 26 | + | ||
| 27 | +#include <QLoggingCategory> | ||
| 28 | +#include <QUuid> | ||
| 29 | +#ifndef QT_NO_SSL | ||
| 30 | +#include <QFile> | ||
| 31 | +#include <QSslConfiguration> | ||
| 32 | +#include <QSslKey> | ||
| 33 | +#endif // QT_NO_SSL | ||
| 34 | + | ||
| 35 | +Q_LOGGING_CATEGORY(client, "qmqtt.client") | ||
| 36 | + | ||
| 37 | +static const quint8 QOS0 = 0x00; | ||
| 38 | +static const quint8 QOS1 = 0x01; | ||
| 39 | +static const quint8 QOS2 = 0x02; | ||
| 40 | + | ||
| 41 | +QMQTT::ClientPrivate::ClientPrivate(Client* qq_ptr) | ||
| 42 | + : _host(QHostAddress::LocalHost) | ||
| 43 | + , _port(1883) | ||
| 44 | + , _gmid(1) | ||
| 45 | + , _version(MQTTVersion::V3_1_0) | ||
| 46 | + , _clientId(QUuid::createUuid().toString()) | ||
| 47 | + , _cleanSession(false) | ||
| 48 | + , _connectionState(STATE_INIT) | ||
| 49 | + , _willQos(0) | ||
| 50 | + , _willRetain(false) | ||
| 51 | + , q_ptr(qq_ptr) | ||
| 52 | +{ | ||
| 53 | + setKeepAlive(300); | ||
| 54 | +} | ||
| 55 | + | ||
| 56 | +QMQTT::ClientPrivate::~ClientPrivate() | ||
| 57 | +{ | ||
| 58 | +} | ||
| 59 | + | ||
| 60 | +void QMQTT::ClientPrivate::init(const QHostAddress& host, const quint16 port, NetworkInterface* network) | ||
| 61 | +{ | ||
| 62 | + Q_Q(Client); | ||
| 63 | + _host = host; | ||
| 64 | + _port = port; | ||
| 65 | + if(network == NULL) | ||
| 66 | + { | ||
| 67 | + init(new Network(q)); | ||
| 68 | + } | ||
| 69 | + else | ||
| 70 | + { | ||
| 71 | + init(network); | ||
| 72 | + } | ||
| 73 | +} | ||
| 74 | + | ||
| 75 | +#ifndef QT_NO_SSL | ||
| 76 | +void QMQTT::ClientPrivate::init(const QString& hostName, const quint16 port, | ||
| 77 | + const QSslConfiguration &config, const bool ignoreSelfSigned) | ||
| 78 | +{ | ||
| 79 | + Q_Q(Client); | ||
| 80 | + _hostName = hostName; | ||
| 81 | + _port = port; | ||
| 82 | + _ignoreSelfSigned = ignoreSelfSigned; | ||
| 83 | + init(new Network(config, q)); | ||
| 84 | + QObject::connect(_network.data(), &QMQTT::Network::sslErrors, q, &QMQTT::Client::onSslErrors); | ||
| 85 | +} | ||
| 86 | +#endif // QT_NO_SSL | ||
| 87 | + | ||
| 88 | +void QMQTT::ClientPrivate::init(const QString& hostName, const quint16 port, const bool ssl, | ||
| 89 | + const bool ignoreSelfSigned) | ||
| 90 | +{ | ||
| 91 | + Q_Q(Client); | ||
| 92 | + _hostName = hostName; | ||
| 93 | + _port = port; | ||
| 94 | + if (ssl) | ||
| 95 | + { | ||
| 96 | +#ifndef QT_NO_SSL | ||
| 97 | + QSslConfiguration sslConf = QSslConfiguration::defaultConfiguration(); | ||
| 98 | + QList<QSslCertificate> certs = QSslCertificate::fromPath(QStringLiteral("./cert.crt")); | ||
| 99 | + if (!certs.isEmpty()) | ||
| 100 | + sslConf.setLocalCertificate(certs.first()); | ||
| 101 | + QFile file(QStringLiteral("./cert.key")); | ||
| 102 | + if (file.open(QIODevice::ReadOnly)) { | ||
| 103 | + sslConf.setPrivateKey(QSslKey(file.readAll(), QSsl::Rsa)); | ||
| 104 | + } | ||
| 105 | + sslConf.setPeerVerifyMode(QSslSocket::VerifyNone); | ||
| 106 | + init(hostName, port, sslConf, ignoreSelfSigned); | ||
| 107 | +#else | ||
| 108 | + Q_UNUSED(ignoreSelfSigned) | ||
| 109 | + qCritical() << "SSL not supported in this QT build"; | ||
| 110 | +#endif // QT_NO_SSL | ||
| 111 | + } | ||
| 112 | + else | ||
| 113 | + { | ||
| 114 | + init(new Network(q)); | ||
| 115 | + } | ||
| 116 | +} | ||
| 117 | + | ||
| 118 | +#ifdef QT_WEBSOCKETS_LIB | ||
| 119 | +#ifndef QT_NO_SSL | ||
| 120 | +void QMQTT::ClientPrivate::init(const QString& url, | ||
| 121 | + const QString& origin, | ||
| 122 | + QWebSocketProtocol::Version version, | ||
| 123 | + const QSslConfiguration* sslConfig, | ||
| 124 | + bool ignoreSelfSigned) | ||
| 125 | +{ | ||
| 126 | + Q_Q(Client); | ||
| 127 | + _hostName = url; | ||
| 128 | + _ignoreSelfSigned = ignoreSelfSigned; | ||
| 129 | + init(new Network(origin, version, sslConfig, q)); | ||
| 130 | +} | ||
| 131 | +#endif // QT_NO_SSL | ||
| 132 | + | ||
| 133 | +void QMQTT::ClientPrivate::init(const QString& url, | ||
| 134 | + const QString& origin, | ||
| 135 | + QWebSocketProtocol::Version version) | ||
| 136 | +{ | ||
| 137 | + Q_Q(Client); | ||
| 138 | + _hostName = url; | ||
| 139 | + init(new Network(origin, version, q)); | ||
| 140 | +} | ||
| 141 | +#endif // QT_WEBSOCKETS_LIB | ||
| 142 | + | ||
| 143 | +void QMQTT::ClientPrivate::init(NetworkInterface* network) | ||
| 144 | +{ | ||
| 145 | + Q_Q(Client); | ||
| 146 | + | ||
| 147 | + _network.reset(network); | ||
| 148 | + _timer.setSingleShot(true); | ||
| 149 | + _pingResponseTimer.setSingleShot(true); | ||
| 150 | + | ||
| 151 | + QObject::connect(&_timer, &QTimer::timeout, q, &Client::onTimerPingReq); | ||
| 152 | + QObject::connect(&_pingResponseTimer, &QTimer::timeout, q, &Client::onPingTimeout); | ||
| 153 | + QObject::connect(_network.data(), &Network::connected, | ||
| 154 | + q, &Client::onNetworkConnected); | ||
| 155 | + QObject::connect(_network.data(), &Network::disconnected, | ||
| 156 | + q, &Client::onNetworkDisconnected); | ||
| 157 | + QObject::connect(_network.data(), &Network::received, | ||
| 158 | + q, &Client::onNetworkReceived); | ||
| 159 | + QObject::connect(_network.data(), &Network::error, | ||
| 160 | + q, &Client::onNetworkError); | ||
| 161 | +} | ||
| 162 | + | ||
| 163 | +void QMQTT::ClientPrivate::connectToHost() | ||
| 164 | +{ | ||
| 165 | + _connectionState = ConnectionState::STATE_CONNECTING; | ||
| 166 | + if (_hostName.isEmpty()) | ||
| 167 | + { | ||
| 168 | + _network->connectToHost(_host, _port); | ||
| 169 | + } | ||
| 170 | + else | ||
| 171 | + { | ||
| 172 | + _network->connectToHost(_hostName, _port); | ||
| 173 | + } | ||
| 174 | +} | ||
| 175 | + | ||
| 176 | +void QMQTT::ClientPrivate::onNetworkConnected() | ||
| 177 | +{ | ||
| 178 | + sendConnect(); | ||
| 179 | +} | ||
| 180 | + | ||
| 181 | +void QMQTT::ClientPrivate::sendConnect() | ||
| 182 | +{ | ||
| 183 | + quint8 header = CONNECT; | ||
| 184 | + quint8 flags = 0; | ||
| 185 | + | ||
| 186 | + //header | ||
| 187 | + Frame frame(header); | ||
| 188 | + | ||
| 189 | + //flags | ||
| 190 | + flags = FLAG_CLEANSESS(flags, _cleanSession ? 1 : 0 ); | ||
| 191 | + flags = FLAG_WILL(flags, willTopic().isEmpty() ? 0 : 1); | ||
| 192 | + if (!willTopic().isEmpty()) | ||
| 193 | + { | ||
| 194 | + flags = FLAG_WILLQOS(flags, willQos()); | ||
| 195 | + flags = FLAG_WILLRETAIN(flags, willRetain() ? 1 : 0); | ||
| 196 | + } | ||
| 197 | + if (!username().isEmpty()) | ||
| 198 | + { | ||
| 199 | + flags = FLAG_USERNAME(flags, 1); | ||
| 200 | + flags = FLAG_PASSWD(flags, !password().isEmpty() ? 1 : 0); | ||
| 201 | + } | ||
| 202 | + | ||
| 203 | + //payload | ||
| 204 | + if(_version == V3_1_1) | ||
| 205 | + { | ||
| 206 | + frame.writeString(QStringLiteral(PROTOCOL_MAGIC_3_1_1)); | ||
| 207 | + } | ||
| 208 | + else | ||
| 209 | + { | ||
| 210 | + frame.writeString(QStringLiteral(PROTOCOL_MAGIC_3_1_0)); | ||
| 211 | + } | ||
| 212 | + frame.writeChar(_version); | ||
| 213 | + frame.writeChar(flags); | ||
| 214 | + frame.writeInt(keepAlive()); | ||
| 215 | + frame.writeString(_clientId); | ||
| 216 | + if(!willTopic().isEmpty()) | ||
| 217 | + { | ||
| 218 | + frame.writeString(willTopic()); | ||
| 219 | + // According to the specs (http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718031) | ||
| 220 | + // the will message gets always sent together with the topic, also when it is empty which is perfectly valid. | ||
| 221 | + frame.writeByteArray(_willMessage); | ||
| 222 | + } | ||
| 223 | + if (!_username.isEmpty()) | ||
| 224 | + { | ||
| 225 | + frame.writeString(_username); | ||
| 226 | + if (!_password.isEmpty()) | ||
| 227 | + { | ||
| 228 | + frame.writeByteArray(_password); | ||
| 229 | + } | ||
| 230 | + } | ||
| 231 | + sendFrame(frame); | ||
| 232 | +} | ||
| 233 | + | ||
| 234 | +quint16 QMQTT::ClientPrivate::sendPublish(const Message &message) | ||
| 235 | +{ | ||
| 236 | + quint16 msgid = message.id(); | ||
| 237 | + | ||
| 238 | + quint8 header = PUBLISH; | ||
| 239 | + header = SETRETAIN(header, message.retain() ? 1 : 0); | ||
| 240 | + header = SETQOS(header, message.qos()); | ||
| 241 | + header = SETDUP(header, message.dup() ? 1 : 0); | ||
| 242 | + Frame frame(header); | ||
| 243 | + frame.writeString(message.topic()); | ||
| 244 | + if(message.qos() > QOS0) { | ||
| 245 | + if (msgid == 0) | ||
| 246 | + msgid = nextmid(); | ||
| 247 | + frame.writeInt(msgid); | ||
| 248 | + } | ||
| 249 | + if(!message.payload().isEmpty()) { | ||
| 250 | + frame.writeRawData(message.payload()); | ||
| 251 | + } | ||
| 252 | + sendFrame(frame); | ||
| 253 | + return msgid; | ||
| 254 | +} | ||
| 255 | + | ||
| 256 | +void QMQTT::ClientPrivate::sendPuback(const quint8 type, const quint16 mid) | ||
| 257 | +{ | ||
| 258 | + Frame frame(type); | ||
| 259 | + frame.writeInt(mid); | ||
| 260 | + sendFrame(frame); | ||
| 261 | +} | ||
| 262 | + | ||
| 263 | +quint16 QMQTT::ClientPrivate::sendSubscribe(const QString & topic, const quint8 qos) | ||
| 264 | +{ | ||
| 265 | + quint16 mid = nextmid(); | ||
| 266 | + Frame frame(SETQOS(SUBSCRIBE, QOS1)); | ||
| 267 | + frame.writeInt(mid); | ||
| 268 | + frame.writeString(topic); | ||
| 269 | + frame.writeChar(qos); | ||
| 270 | + sendFrame(frame); | ||
| 271 | + return mid; | ||
| 272 | +} | ||
| 273 | + | ||
| 274 | +quint16 QMQTT::ClientPrivate::sendUnsubscribe(const QString &topic) | ||
| 275 | +{ | ||
| 276 | + quint16 mid = nextmid(); | ||
| 277 | + Frame frame(SETQOS(UNSUBSCRIBE, QOS1)); | ||
| 278 | + frame.writeInt(mid); | ||
| 279 | + frame.writeString(topic); | ||
| 280 | + sendFrame(frame); | ||
| 281 | + return mid; | ||
| 282 | +} | ||
| 283 | + | ||
| 284 | +void QMQTT::ClientPrivate::onTimerPingReq() | ||
| 285 | +{ | ||
| 286 | + if (!isConnectedToHost()) | ||
| 287 | + return; | ||
| 288 | + Frame frame(PINGREQ); | ||
| 289 | + sendFrame(frame); | ||
| 290 | + _pingResponseTimer.start(); | ||
| 291 | +} | ||
| 292 | + | ||
| 293 | +void QMQTT::ClientPrivate::onPingTimeout() | ||
| 294 | +{ | ||
| 295 | + Q_Q(Client); | ||
| 296 | + emit q->error(MqttNoPingResponse); | ||
| 297 | + disconnectFromHost(); | ||
| 298 | +} | ||
| 299 | + | ||
| 300 | +void QMQTT::ClientPrivate::disconnectFromHost() | ||
| 301 | +{ | ||
| 302 | + _connectionState = ConnectionState::STATE_DISCONNECTED; | ||
| 303 | + sendDisconnect(); | ||
| 304 | + _network->disconnectFromHost(); | ||
| 305 | +} | ||
| 306 | + | ||
| 307 | +void QMQTT::ClientPrivate::sendDisconnect() | ||
| 308 | +{ | ||
| 309 | + Frame frame(DISCONNECT); | ||
| 310 | + sendFrame(frame); | ||
| 311 | +} | ||
| 312 | + | ||
| 313 | +void QMQTT::ClientPrivate::sendFrame(const Frame &frame) | ||
| 314 | +{ | ||
| 315 | + _network->sendFrame(frame); | ||
| 316 | + _timer.start(); | ||
| 317 | +} | ||
| 318 | + | ||
| 319 | +void QMQTT::ClientPrivate::stopKeepAlive() | ||
| 320 | +{ | ||
| 321 | + _timer.stop(); | ||
| 322 | + _pingResponseTimer.stop(); | ||
| 323 | +} | ||
| 324 | + | ||
| 325 | +quint16 QMQTT::ClientPrivate::nextmid() | ||
| 326 | +{ | ||
| 327 | + return _gmid++; | ||
| 328 | +} | ||
| 329 | + | ||
| 330 | +quint16 QMQTT::ClientPrivate::publish(const Message& message) | ||
| 331 | +{ | ||
| 332 | + Q_Q(Client); | ||
| 333 | + quint16 msgid = sendPublish(message); | ||
| 334 | + | ||
| 335 | + // Emit published only at QOS0 | ||
| 336 | + if (message.qos() == QOS0) | ||
| 337 | + emit q->published(message, msgid); | ||
| 338 | + else | ||
| 339 | + _midToMessage[msgid] = message; | ||
| 340 | + | ||
| 341 | + return msgid; | ||
| 342 | +} | ||
| 343 | + | ||
| 344 | +void QMQTT::ClientPrivate::puback(const quint8 type, const quint16 msgid) | ||
| 345 | +{ | ||
| 346 | + sendPuback(type, msgid); | ||
| 347 | +} | ||
| 348 | + | ||
| 349 | +void QMQTT::ClientPrivate::subscribe(const QString& topic, const quint8 qos) | ||
| 350 | +{ | ||
| 351 | + quint16 msgid = sendSubscribe(topic, qos); | ||
| 352 | + _midToTopic[msgid] = topic; | ||
| 353 | +} | ||
| 354 | + | ||
| 355 | +void QMQTT::ClientPrivate::unsubscribe(const QString& topic) | ||
| 356 | +{ | ||
| 357 | + quint16 msgid = sendUnsubscribe(topic); | ||
| 358 | + _midToTopic[msgid] = topic; | ||
| 359 | +} | ||
| 360 | + | ||
| 361 | +void QMQTT::ClientPrivate::onNetworkDisconnected() | ||
| 362 | +{ | ||
| 363 | + Q_Q(Client); | ||
| 364 | + | ||
| 365 | + stopKeepAlive(); | ||
| 366 | + _midToTopic.clear(); | ||
| 367 | + _midToMessage.clear(); | ||
| 368 | + emit q->disconnected(); | ||
| 369 | +} | ||
| 370 | + | ||
| 371 | +void QMQTT::ClientPrivate::onNetworkReceived(const QMQTT::Frame& frm) | ||
| 372 | +{ | ||
| 373 | + QMQTT::Frame frame(frm); | ||
| 374 | + quint8 qos = 0; | ||
| 375 | + bool retain, dup; | ||
| 376 | + QString topic; | ||
| 377 | + quint16 mid = 0; | ||
| 378 | + quint8 header = frame.header(); | ||
| 379 | + quint8 type = GETTYPE(header); | ||
| 380 | + | ||
| 381 | + switch(type) | ||
| 382 | + { | ||
| 383 | + case CONNACK: | ||
| 384 | + frame.readChar(); | ||
| 385 | + handleConnack(frame.readChar()); | ||
| 386 | + break; | ||
| 387 | + case PUBLISH: | ||
| 388 | + qos = GETQOS(header); | ||
| 389 | + retain = GETRETAIN(header); | ||
| 390 | + dup = GETDUP(header); | ||
| 391 | + topic = frame.readString(); | ||
| 392 | + if( qos > QOS0) { | ||
| 393 | + mid = frame.readInt(); | ||
| 394 | + } | ||
| 395 | + handlePublish(Message(mid, topic, frame.data(), qos, retain, dup)); | ||
| 396 | + break; | ||
| 397 | + case PUBACK: | ||
| 398 | + case PUBREC: | ||
| 399 | + case PUBREL: | ||
| 400 | + case PUBCOMP: | ||
| 401 | + mid = frame.readInt(); | ||
| 402 | + handlePuback(type, mid); | ||
| 403 | + break; | ||
| 404 | + case SUBACK: | ||
| 405 | + mid = frame.readInt(); | ||
| 406 | + topic = _midToTopic.take(mid); | ||
| 407 | + qos = frame.readChar(); | ||
| 408 | + handleSuback(topic, qos); | ||
| 409 | + break; | ||
| 410 | + case UNSUBACK: | ||
| 411 | + mid = frame.readInt(); | ||
| 412 | + topic = _midToTopic.take(mid); | ||
| 413 | + handleUnsuback(topic); | ||
| 414 | + break; | ||
| 415 | + case PINGRESP: | ||
| 416 | + handlePingresp(); | ||
| 417 | + break; | ||
| 418 | + default: | ||
| 419 | + break; | ||
| 420 | + } | ||
| 421 | +} | ||
| 422 | + | ||
| 423 | +void QMQTT::ClientPrivate::handleConnack(const quint8 ack) | ||
| 424 | +{ | ||
| 425 | + Q_Q(Client); | ||
| 426 | + | ||
| 427 | + switch (ack) | ||
| 428 | + { | ||
| 429 | + case 0: | ||
| 430 | + _connectionState = ConnectionState::STATE_CONNECTED; | ||
| 431 | + emit q->connected(); | ||
| 432 | + break; | ||
| 433 | + case 1: | ||
| 434 | + emit q->error(MqttUnacceptableProtocolVersionError); | ||
| 435 | + break; | ||
| 436 | + case 2: | ||
| 437 | + emit q->error(MqttIdentifierRejectedError); | ||
| 438 | + break; | ||
| 439 | + case 3: | ||
| 440 | + emit q->error(MqttServerUnavailableError); | ||
| 441 | + break; | ||
| 442 | + case 4: | ||
| 443 | + emit q->error(MqttBadUserNameOrPasswordError); | ||
| 444 | + break; | ||
| 445 | + case 5: | ||
| 446 | + emit q->error(MqttNotAuthorizedError); | ||
| 447 | + break; | ||
| 448 | + default: | ||
| 449 | + emit q->error(UnknownError); | ||
| 450 | + break; | ||
| 451 | + } | ||
| 452 | +} | ||
| 453 | + | ||
| 454 | +void QMQTT::ClientPrivate::handlePublish(const Message& message) | ||
| 455 | +{ | ||
| 456 | + Q_Q(Client); | ||
| 457 | + | ||
| 458 | + if(message.qos() == QOS1) | ||
| 459 | + { | ||
| 460 | + sendPuback(PUBACK, message.id()); | ||
| 461 | + } | ||
| 462 | + else if(message.qos() == QOS2) | ||
| 463 | + { | ||
| 464 | + sendPuback(PUBREC, message.id()); | ||
| 465 | + } | ||
| 466 | + emit q->received(message); | ||
| 467 | +} | ||
| 468 | + | ||
| 469 | +void QMQTT::ClientPrivate::handlePuback(const quint8 type, const quint16 msgid) | ||
| 470 | +{ | ||
| 471 | + Q_Q(Client); | ||
| 472 | + | ||
| 473 | + switch (type) | ||
| 474 | + { | ||
| 475 | + case PUBREC: | ||
| 476 | + sendPuback(SETQOS(PUBREL, QOS1), msgid); | ||
| 477 | + break; | ||
| 478 | + case PUBREL: | ||
| 479 | + sendPuback(PUBCOMP, msgid); | ||
| 480 | + break; | ||
| 481 | + case PUBACK: | ||
| 482 | + case PUBCOMP: | ||
| 483 | + // Emit published on PUBACK at QOS1 and on PUBCOMP at QOS2 | ||
| 484 | + emit q->published(_midToMessage.take(msgid), msgid); | ||
| 485 | + break; | ||
| 486 | + } | ||
| 487 | +} | ||
| 488 | + | ||
| 489 | +void QMQTT::ClientPrivate::handlePingresp() | ||
| 490 | +{ | ||
| 491 | + // Stop the ping response timer to prevent disconnection. It will be restarted when the next | ||
| 492 | + // ping request has been sent. | ||
| 493 | + _pingResponseTimer.stop(); | ||
| 494 | + Q_Q(Client); | ||
| 495 | + emit q->pingresp(); | ||
| 496 | +} | ||
| 497 | + | ||
| 498 | +void QMQTT::ClientPrivate::handleSuback(const QString &topic, const quint8 qos) | ||
| 499 | +{ | ||
| 500 | + Q_Q(Client); | ||
| 501 | + emit q->subscribed(topic, qos); | ||
| 502 | +} | ||
| 503 | + | ||
| 504 | +void QMQTT::ClientPrivate::handleUnsuback(const QString &topic) { | ||
| 505 | + Q_Q(Client); | ||
| 506 | + emit q->unsubscribed(topic); | ||
| 507 | +} | ||
| 508 | + | ||
| 509 | +bool QMQTT::ClientPrivate::autoReconnect() const | ||
| 510 | +{ | ||
| 511 | + return _network->autoReconnect(); | ||
| 512 | +} | ||
| 513 | + | ||
| 514 | +void QMQTT::ClientPrivate::setAutoReconnect(const bool autoReconnect) | ||
| 515 | +{ | ||
| 516 | + _network->setAutoReconnect(autoReconnect); | ||
| 517 | +} | ||
| 518 | + | ||
| 519 | +int QMQTT::ClientPrivate::autoReconnectInterval() const | ||
| 520 | +{ | ||
| 521 | + return _network->autoReconnectInterval(); | ||
| 522 | +} | ||
| 523 | + | ||
| 524 | +void QMQTT::ClientPrivate::setAutoReconnectInterval(const int autoReconnectInterval) | ||
| 525 | +{ | ||
| 526 | + _network->setAutoReconnectInterval(autoReconnectInterval); | ||
| 527 | +} | ||
| 528 | + | ||
| 529 | +bool QMQTT::ClientPrivate::isConnectedToHost() const | ||
| 530 | +{ | ||
| 531 | + return _network->isConnectedToHost(); | ||
| 532 | +} | ||
| 533 | + | ||
| 534 | +QMQTT::ConnectionState QMQTT::ClientPrivate::connectionState() const | ||
| 535 | +{ | ||
| 536 | + return _connectionState; | ||
| 537 | +} | ||
| 538 | + | ||
| 539 | +void QMQTT::ClientPrivate::setCleanSession(const bool cleanSession) | ||
| 540 | +{ | ||
| 541 | + _cleanSession = cleanSession; | ||
| 542 | +} | ||
| 543 | + | ||
| 544 | +bool QMQTT::ClientPrivate::cleanSession() const | ||
| 545 | +{ | ||
| 546 | + return _cleanSession; | ||
| 547 | +} | ||
| 548 | + | ||
| 549 | +void QMQTT::ClientPrivate::setKeepAlive(const quint16 keepAlive) | ||
| 550 | +{ | ||
| 551 | + // _timer will be started when a message is sent. | ||
| 552 | + _timer.setInterval(keepAlive*1000); | ||
| 553 | + // The MQTT specification does not mention a timeout value in this case, so we use 10% of the | ||
| 554 | + // keep alive interval. | ||
| 555 | + _pingResponseTimer.setInterval(qBound(keepAlive * 100, 10000, keepAlive * 1000)); | ||
| 556 | +} | ||
| 557 | + | ||
| 558 | +quint16 QMQTT::ClientPrivate::keepAlive() const | ||
| 559 | +{ | ||
| 560 | + return _timer.interval() / 1000; | ||
| 561 | +} | ||
| 562 | + | ||
| 563 | +void QMQTT::ClientPrivate::setPassword(const QByteArray& password) | ||
| 564 | +{ | ||
| 565 | + _password = password; | ||
| 566 | +} | ||
| 567 | + | ||
| 568 | +QByteArray QMQTT::ClientPrivate::password() const | ||
| 569 | +{ | ||
| 570 | + return _password; | ||
| 571 | +} | ||
| 572 | + | ||
| 573 | +void QMQTT::ClientPrivate::setUsername(const QString& username) | ||
| 574 | +{ | ||
| 575 | + _username = username; | ||
| 576 | +} | ||
| 577 | + | ||
| 578 | +QString QMQTT::ClientPrivate::username() const | ||
| 579 | +{ | ||
| 580 | + return _username; | ||
| 581 | +} | ||
| 582 | + | ||
| 583 | +void QMQTT::ClientPrivate::setVersion(const MQTTVersion version) | ||
| 584 | +{ | ||
| 585 | + _version = version; | ||
| 586 | +} | ||
| 587 | + | ||
| 588 | +QMQTT::MQTTVersion QMQTT::ClientPrivate::version() const | ||
| 589 | +{ | ||
| 590 | + return _version; | ||
| 591 | +} | ||
| 592 | + | ||
| 593 | +void QMQTT::ClientPrivate::setClientId(const QString& clientId) | ||
| 594 | +{ | ||
| 595 | + if(clientId.isEmpty()) | ||
| 596 | + { | ||
| 597 | + _clientId = QUuid::createUuid().toString(); | ||
| 598 | + } | ||
| 599 | + else | ||
| 600 | + { | ||
| 601 | + _clientId = clientId; | ||
| 602 | + } | ||
| 603 | +} | ||
| 604 | + | ||
| 605 | +QString QMQTT::ClientPrivate::clientId() const | ||
| 606 | +{ | ||
| 607 | + return _clientId; | ||
| 608 | +} | ||
| 609 | + | ||
| 610 | +void QMQTT::ClientPrivate::setPort(const quint16 port) | ||
| 611 | +{ | ||
| 612 | + _port = port; | ||
| 613 | +} | ||
| 614 | + | ||
| 615 | +quint16 QMQTT::ClientPrivate::port() const | ||
| 616 | +{ | ||
| 617 | + return _port; | ||
| 618 | +} | ||
| 619 | + | ||
| 620 | +void QMQTT::ClientPrivate::setHost(const QHostAddress& host) | ||
| 621 | +{ | ||
| 622 | + _host = host; | ||
| 623 | +} | ||
| 624 | + | ||
| 625 | +QHostAddress QMQTT::ClientPrivate::host() const | ||
| 626 | +{ | ||
| 627 | + return _host; | ||
| 628 | +} | ||
| 629 | + | ||
| 630 | +void QMQTT::ClientPrivate::setHostName(const QString& hostName) | ||
| 631 | +{ | ||
| 632 | + _hostName = hostName; | ||
| 633 | +} | ||
| 634 | + | ||
| 635 | +QString QMQTT::ClientPrivate::hostName() const | ||
| 636 | +{ | ||
| 637 | + return _hostName; | ||
| 638 | +} | ||
| 639 | + | ||
| 640 | +QString QMQTT::ClientPrivate::willTopic() const | ||
| 641 | +{ | ||
| 642 | + return _willTopic; | ||
| 643 | +} | ||
| 644 | + | ||
| 645 | +void QMQTT::ClientPrivate::setWillTopic(const QString& willTopic) | ||
| 646 | +{ | ||
| 647 | + _willTopic = willTopic; | ||
| 648 | +} | ||
| 649 | + | ||
| 650 | +quint8 QMQTT::ClientPrivate::willQos() const | ||
| 651 | +{ | ||
| 652 | + return _willQos; | ||
| 653 | +} | ||
| 654 | + | ||
| 655 | +void QMQTT::ClientPrivate::setWillQos(const quint8 willQos) | ||
| 656 | +{ | ||
| 657 | + _willQos = willQos; | ||
| 658 | +} | ||
| 659 | + | ||
| 660 | +bool QMQTT::ClientPrivate::willRetain() const | ||
| 661 | +{ | ||
| 662 | + return _willRetain; | ||
| 663 | +} | ||
| 664 | + | ||
| 665 | +void QMQTT::ClientPrivate::setWillRetain(const bool willRetain) | ||
| 666 | +{ | ||
| 667 | + _willRetain = willRetain; | ||
| 668 | +} | ||
| 669 | + | ||
| 670 | +QByteArray QMQTT::ClientPrivate::willMessage() const | ||
| 671 | +{ | ||
| 672 | + return _willMessage; | ||
| 673 | +} | ||
| 674 | + | ||
| 675 | +void QMQTT::ClientPrivate::setWillMessage(const QByteArray& willMessage) | ||
| 676 | +{ | ||
| 677 | + _willMessage = willMessage; | ||
| 678 | +} | ||
| 679 | + | ||
| 680 | +void QMQTT::ClientPrivate::onNetworkError(QAbstractSocket::SocketError socketError) | ||
| 681 | +{ | ||
| 682 | + Q_Q(Client); | ||
| 683 | + | ||
| 684 | + switch (socketError) | ||
| 685 | + { | ||
| 686 | + case QAbstractSocket::ConnectionRefusedError: | ||
| 687 | + emit q->error(SocketConnectionRefusedError); | ||
| 688 | + break; | ||
| 689 | + case QAbstractSocket::RemoteHostClosedError: | ||
| 690 | + emit q->error(SocketRemoteHostClosedError); | ||
| 691 | + break; | ||
| 692 | + case QAbstractSocket::HostNotFoundError: | ||
| 693 | + emit q->error(SocketHostNotFoundError); | ||
| 694 | + break; | ||
| 695 | + case QAbstractSocket::SocketAccessError: | ||
| 696 | + emit q->error(SocketAccessError); | ||
| 697 | + break; | ||
| 698 | + case QAbstractSocket::SocketResourceError: | ||
| 699 | + emit q->error(SocketResourceError); | ||
| 700 | + break; | ||
| 701 | + case QAbstractSocket::SocketTimeoutError: | ||
| 702 | + emit q->error(SocketTimeoutError); | ||
| 703 | + break; | ||
| 704 | + case QAbstractSocket::DatagramTooLargeError: | ||
| 705 | + emit q->error(SocketDatagramTooLargeError); | ||
| 706 | + break; | ||
| 707 | + case QAbstractSocket::NetworkError: | ||
| 708 | + emit q->error(SocketNetworkError); | ||
| 709 | + break; | ||
| 710 | + case QAbstractSocket::AddressInUseError: | ||
| 711 | + emit q->error(SocketAddressInUseError); | ||
| 712 | + break; | ||
| 713 | + case QAbstractSocket::SocketAddressNotAvailableError: | ||
| 714 | + emit q->error(SocketAddressNotAvailableError); | ||
| 715 | + break; | ||
| 716 | + case QAbstractSocket::UnsupportedSocketOperationError: | ||
| 717 | + emit q->error(SocketUnsupportedSocketOperationError); | ||
| 718 | + break; | ||
| 719 | + case QAbstractSocket::UnfinishedSocketOperationError: | ||
| 720 | + emit q->error(SocketUnfinishedSocketOperationError); | ||
| 721 | + break; | ||
| 722 | + case QAbstractSocket::ProxyAuthenticationRequiredError: | ||
| 723 | + emit q->error(SocketProxyAuthenticationRequiredError); | ||
| 724 | + break; | ||
| 725 | + case QAbstractSocket::SslHandshakeFailedError: | ||
| 726 | + emit q->error(SocketSslHandshakeFailedError); | ||
| 727 | + break; | ||
| 728 | + case QAbstractSocket::ProxyConnectionRefusedError: | ||
| 729 | + emit q->error(SocketProxyConnectionRefusedError); | ||
| 730 | + break; | ||
| 731 | + case QAbstractSocket::ProxyConnectionClosedError: | ||
| 732 | + emit q->error(SocketProxyConnectionClosedError); | ||
| 733 | + break; | ||
| 734 | + case QAbstractSocket::ProxyConnectionTimeoutError: | ||
| 735 | + emit q->error(SocketProxyConnectionTimeoutError); | ||
| 736 | + break; | ||
| 737 | + case QAbstractSocket::ProxyNotFoundError: | ||
| 738 | + emit q->error(SocketProxyNotFoundError); | ||
| 739 | + break; | ||
| 740 | + case QAbstractSocket::ProxyProtocolError: | ||
| 741 | + emit q->error(SocketProxyProtocolError); | ||
| 742 | + break; | ||
| 743 | + case QAbstractSocket::OperationError: | ||
| 744 | + emit q->error(SocketOperationError); | ||
| 745 | + break; | ||
| 746 | + case QAbstractSocket::SslInternalError: | ||
| 747 | + emit q->error(SocketSslInternalError); | ||
| 748 | + break; | ||
| 749 | + case QAbstractSocket::SslInvalidUserDataError: | ||
| 750 | + emit q->error(SocketSslInvalidUserDataError); | ||
| 751 | + break; | ||
| 752 | + case QAbstractSocket::TemporaryError: | ||
| 753 | + emit q->error(SocketTemporaryError); | ||
| 754 | + break; | ||
| 755 | + default: | ||
| 756 | + emit q->error(UnknownError); | ||
| 757 | + break; | ||
| 758 | + } | ||
| 759 | +} | ||
| 760 | + | ||
| 761 | +#ifndef QT_NO_SSL | ||
| 762 | +void QMQTT::ClientPrivate::ignoreSslErrors() | ||
| 763 | +{ | ||
| 764 | + _network->ignoreSslErrors(); | ||
| 765 | +} | ||
| 766 | + | ||
| 767 | +void QMQTT::ClientPrivate::ignoreSslErrors(const QList<QSslError>& errors) | ||
| 768 | +{ | ||
| 769 | + _network->ignoreSslErrors(errors); | ||
| 770 | +} | ||
| 771 | + | ||
| 772 | +QSslConfiguration QMQTT::ClientPrivate::sslConfiguration() const | ||
| 773 | +{ | ||
| 774 | + return _network->sslConfiguration(); | ||
| 775 | +} | ||
| 776 | + | ||
| 777 | +void QMQTT::ClientPrivate::setSslConfiguration(const QSslConfiguration& config) | ||
| 778 | +{ | ||
| 779 | + _network->setSslConfiguration(config); | ||
| 780 | +} | ||
| 781 | + | ||
| 782 | +void QMQTT::ClientPrivate::onSslErrors(const QList<QSslError>& errors) | ||
| 783 | +{ | ||
| 784 | + Q_Q(Client); | ||
| 785 | + | ||
| 786 | + emit q->sslErrors(errors); | ||
| 787 | + | ||
| 788 | + if (!_ignoreSelfSigned) | ||
| 789 | + return; | ||
| 790 | + foreach (QSslError error, errors) | ||
| 791 | + { | ||
| 792 | + if (error.error() != QSslError::SelfSignedCertificate && | ||
| 793 | + error.error() != QSslError::SelfSignedCertificateInChain) | ||
| 794 | + { | ||
| 795 | + return; | ||
| 796 | + } | ||
| 797 | + } | ||
| 798 | + ignoreSslErrors(); | ||
| 799 | +} | ||
| 800 | +#endif // QT_NO_SSL |
src/qmqtt_client_p.h
0 → 100644
| 1 | +++ a/src/qmqtt_client_p.h | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifndef QMQTT_CLIENT_P_H | ||
| 23 | +#define QMQTT_CLIENT_P_H | ||
| 24 | + | ||
| 25 | +#include "qmqtt_client.h" | ||
| 26 | + | ||
| 27 | +#include <QHostAddress> | ||
| 28 | +#include <QString> | ||
| 29 | +#include <QByteArray> | ||
| 30 | +#include <QHash> | ||
| 31 | +#include <QTimer> | ||
| 32 | +#include <QAbstractSocket> | ||
| 33 | + | ||
| 34 | +#ifdef QT_WEBSOCKETS_LIB | ||
| 35 | +#include <QWebSocket> | ||
| 36 | +#endif // QT_WEBSOCKETS_LIB | ||
| 37 | + | ||
| 38 | +#ifndef QT_NO_SSL | ||
| 39 | +#include <QSslConfiguration> | ||
| 40 | +QT_FORWARD_DECLARE_CLASS(QSslError) | ||
| 41 | +#endif // QT_NO_SSL | ||
| 42 | + | ||
| 43 | +namespace QMQTT { | ||
| 44 | + | ||
| 45 | +class NetworkInterface; | ||
| 46 | + | ||
| 47 | +class ClientPrivate | ||
| 48 | +{ | ||
| 49 | +public: | ||
| 50 | + ClientPrivate(Client* qq_ptr); | ||
| 51 | + ~ClientPrivate(); | ||
| 52 | + | ||
| 53 | + /// Deleted copy-constructor | ||
| 54 | + ClientPrivate(const ClientPrivate&) = delete; | ||
| 55 | + /// Deleted assignment operator | ||
| 56 | + ClientPrivate& operator=(const ClientPrivate&) = delete; | ||
| 57 | + /// Deleted move-constructor | ||
| 58 | + ClientPrivate(const ClientPrivate&&) = delete; | ||
| 59 | + /// Deleted move-operator | ||
| 60 | + ClientPrivate& operator=(const ClientPrivate&&) = delete; | ||
| 61 | + | ||
| 62 | + void init(const QHostAddress& host, const quint16 port, NetworkInterface* network = NULL); | ||
| 63 | +#ifndef QT_NO_SSL | ||
| 64 | + void init(const QString& hostName, const quint16 port, const QSslConfiguration& config, | ||
| 65 | + const bool ignoreSelfSigned=false); | ||
| 66 | +#endif // QT_NO_SSL | ||
| 67 | + void init(const QString& hostName, const quint16 port, const bool ssl, const bool ignoreSelfSigned); | ||
| 68 | +#ifdef QT_WEBSOCKETS_LIB | ||
| 69 | +#ifndef QT_NO_SSL | ||
| 70 | + void init(const QString& url, | ||
| 71 | + const QString& origin, | ||
| 72 | + QWebSocketProtocol::Version version, | ||
| 73 | + const QSslConfiguration* sslConfig, | ||
| 74 | + bool ignoreSelfSigned); | ||
| 75 | +#endif // QT_NO_SSL | ||
| 76 | + void init(const QString& url, | ||
| 77 | + const QString& origin, | ||
| 78 | + QWebSocketProtocol::Version version); | ||
| 79 | +#endif // QT_WEBSOCKETS_LIB | ||
| 80 | + void init(NetworkInterface* network); | ||
| 81 | + | ||
| 82 | + QHostAddress _host; | ||
| 83 | + QString _hostName; | ||
| 84 | + quint16 _port; | ||
| 85 | +#ifdef QT_WEBSOCKETS_LIB | ||
| 86 | + QWebSocketProtocol::Version _webSocketVersion; | ||
| 87 | +#endif // QT_WEBSOCKETS_LIB | ||
| 88 | +#ifndef QT_NO_SSL | ||
| 89 | + bool _ignoreSelfSigned; | ||
| 90 | +#endif // QT_NO_SSL | ||
| 91 | + quint16 _gmid; | ||
| 92 | + MQTTVersion _version; | ||
| 93 | + QString _clientId; | ||
| 94 | + QString _username; | ||
| 95 | + QByteArray _password; | ||
| 96 | + bool _cleanSession; | ||
| 97 | + ConnectionState _connectionState; | ||
| 98 | + QScopedPointer<NetworkInterface> _network; | ||
| 99 | + QTimer _timer; | ||
| 100 | + QTimer _pingResponseTimer; | ||
| 101 | + QString _willTopic; | ||
| 102 | + quint8 _willQos; | ||
| 103 | + bool _willRetain; | ||
| 104 | + QByteArray _willMessage; | ||
| 105 | + QHash<quint16, QString> _midToTopic; | ||
| 106 | + QHash<quint16, Message> _midToMessage; | ||
| 107 | + | ||
| 108 | + Client* const q_ptr; | ||
| 109 | + | ||
| 110 | + quint16 nextmid(); | ||
| 111 | + void connectToHost(); | ||
| 112 | + void sendConnect(); | ||
| 113 | + void onTimerPingReq(); | ||
| 114 | + void onPingTimeout(); | ||
| 115 | + quint16 sendUnsubscribe(const QString &topic); | ||
| 116 | + quint16 sendSubscribe(const QString &topic, const quint8 qos); | ||
| 117 | + quint16 sendPublish(const Message &message); | ||
| 118 | + void sendPuback(const quint8 type, const quint16 mid); | ||
| 119 | + void sendDisconnect(); | ||
| 120 | + void sendFrame(const Frame &frame); | ||
| 121 | + void disconnectFromHost(); | ||
| 122 | + void stopKeepAlive(); | ||
| 123 | + void onNetworkConnected(); | ||
| 124 | + void onNetworkDisconnected(); | ||
| 125 | + quint16 publish(const Message& message); | ||
| 126 | + void puback(const quint8 type, const quint16 msgid); | ||
| 127 | + void subscribe(const QString& topic, const quint8 qos); | ||
| 128 | + void unsubscribe(const QString& topic); | ||
| 129 | + void onNetworkReceived(const QMQTT::Frame& frame); | ||
| 130 | + void handleConnack(const quint8 ack); | ||
| 131 | + void handlePublish(const Message& message); | ||
| 132 | + void handlePuback(const quint8 type, const quint16 msgid); | ||
| 133 | + void handleSuback(const QString& topic, const quint8 qos); | ||
| 134 | + void handleUnsuback(const QString& topic); | ||
| 135 | + void handlePingresp(); | ||
| 136 | + bool autoReconnect() const; | ||
| 137 | + void setAutoReconnect(const bool autoReconnect); | ||
| 138 | + int autoReconnectInterval() const; | ||
| 139 | + void setAutoReconnectInterval(const int autoReconnectInterval); | ||
| 140 | + bool isConnectedToHost() const; | ||
| 141 | + QMQTT::ConnectionState connectionState() const; | ||
| 142 | + void setCleanSession(const bool cleanSession); | ||
| 143 | + bool cleanSession() const; | ||
| 144 | + void setKeepAlive(const quint16 keepAlive); | ||
| 145 | + quint16 keepAlive() const; | ||
| 146 | + void setPassword(const QByteArray& password); | ||
| 147 | + QByteArray password() const; | ||
| 148 | + void setUsername(const QString& username); | ||
| 149 | + QString username() const; | ||
| 150 | + void setVersion(const MQTTVersion); | ||
| 151 | + MQTTVersion version() const; | ||
| 152 | + void setClientId(const QString& clientId); | ||
| 153 | + QString clientId() const; | ||
| 154 | + void setPort(const quint16 port); | ||
| 155 | + quint16 port() const; | ||
| 156 | + void setHost(const QHostAddress& host); | ||
| 157 | + QHostAddress host() const; | ||
| 158 | + void setHostName(const QString& hostName); | ||
| 159 | + QString hostName() const; | ||
| 160 | + void setWillTopic(const QString& willTopic); | ||
| 161 | + void setWillQos(const quint8 willQos); | ||
| 162 | + void setWillRetain(const bool willRetain); | ||
| 163 | + void setWillMessage(const QByteArray& willMessage); | ||
| 164 | + QString willTopic() const; | ||
| 165 | + quint8 willQos() const; | ||
| 166 | + bool willRetain() const; | ||
| 167 | + QByteArray willMessage() const; | ||
| 168 | + void onNetworkError(QAbstractSocket::SocketError error); | ||
| 169 | +#ifndef QT_NO_SSL | ||
| 170 | + void ignoreSslErrors(); | ||
| 171 | + void ignoreSslErrors(const QList<QSslError>& errors); | ||
| 172 | + QSslConfiguration sslConfiguration() const; | ||
| 173 | + void setSslConfiguration(const QSslConfiguration& config); | ||
| 174 | + void onSslErrors(const QList<QSslError>& errors); | ||
| 175 | +#endif // QT_NO_SSL | ||
| 176 | + | ||
| 177 | + Q_DECLARE_PUBLIC(Client) | ||
| 178 | +}; | ||
| 179 | + | ||
| 180 | +} // namespace QMQTT | ||
| 181 | + | ||
| 182 | +#endif // QMQTT_CLIENT_P_H |
src/qmqtt_configsettings.cpp
0 → 100644
| 1 | +++ a/src/qmqtt_configsettings.cpp | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#include "qmqtt_configsettings.h" | ||
| 23 | +#include "log.h" | ||
| 24 | + | ||
| 25 | +using namespace osdev::components; | ||
| 26 | + | ||
| 27 | +void QMqttConfigSettings::setHostAddress( const QHostAddress &host ) | ||
| 28 | +{ | ||
| 29 | + m_host_address = host; | ||
| 30 | +} | ||
| 31 | + | ||
| 32 | +QHostAddress QMqttConfigSettings::getHostAddress() const | ||
| 33 | +{ | ||
| 34 | + return m_host_address; | ||
| 35 | +} | ||
| 36 | + | ||
| 37 | +void QMqttConfigSettings::setHostName( const QString& host_name ) | ||
| 38 | +{ | ||
| 39 | + m_host_name = host_name; | ||
| 40 | + QHostInfo host_info = QHostInfo::fromName( host_name ); | ||
| 41 | + if( !host_info.addresses().isEmpty() ) | ||
| 42 | + { | ||
| 43 | + m_host_address = host_info.addresses().first(); | ||
| 44 | + } | ||
| 45 | + else | ||
| 46 | + { | ||
| 47 | + LogError( "[QMqttConfigSettings::setHostName]", QString( "Hostname : %1 failed to resolve to an ip-address." ).arg( host_name ) ); | ||
| 48 | + } | ||
| 49 | +} | ||
| 50 | + | ||
| 51 | +QString QMqttConfigSettings::getHostName() const | ||
| 52 | +{ | ||
| 53 | + return m_host_name; | ||
| 54 | +} | ||
| 55 | + | ||
| 56 | +void QMqttConfigSettings::setPortNumber( const quint16 port ) | ||
| 57 | +{ | ||
| 58 | + m_host_port = port; | ||
| 59 | +} | ||
| 60 | + | ||
| 61 | +quint16 QMqttConfigSettings::getPortNumber() const | ||
| 62 | +{ | ||
| 63 | + return m_host_port; | ||
| 64 | +} | ||
| 65 | + | ||
| 66 | +void QMqttConfigSettings::setClientId( const QString& clientId ) | ||
| 67 | +{ | ||
| 68 | + m_client_id = clientId; | ||
| 69 | +} | ||
| 70 | + | ||
| 71 | +QString QMqttConfigSettings::getClientId() const | ||
| 72 | +{ | ||
| 73 | + return m_client_id; | ||
| 74 | +} | ||
| 75 | + | ||
| 76 | +void QMqttConfigSettings::setUserName( const QString& user_name ) | ||
| 77 | +{ | ||
| 78 | + m_user_name = user_name; | ||
| 79 | +} | ||
| 80 | + | ||
| 81 | +QString QMqttConfigSettings::getUserName() const | ||
| 82 | +{ | ||
| 83 | + return m_user_name; | ||
| 84 | +} | ||
| 85 | + | ||
| 86 | +void QMqttConfigSettings::setPassword( const QByteArray& pass_word ) | ||
| 87 | +{ | ||
| 88 | + m_password = pass_word; | ||
| 89 | +} | ||
| 90 | + | ||
| 91 | +QByteArray QMqttConfigSettings::getPassword() const | ||
| 92 | +{ | ||
| 93 | + return m_password; | ||
| 94 | +} | ||
| 95 | + | ||
| 96 | +void QMqttConfigSettings::setKeepAlive( const quint16 keep_alive ) | ||
| 97 | +{ | ||
| 98 | + m_keep_alive = keep_alive; | ||
| 99 | +} | ||
| 100 | + | ||
| 101 | +quint16 QMqttConfigSettings::getKeepAlive() const | ||
| 102 | +{ | ||
| 103 | + return m_keep_alive; | ||
| 104 | +} | ||
| 105 | + | ||
| 106 | +void QMqttConfigSettings::setCleanSession( bool clean_session ) | ||
| 107 | +{ | ||
| 108 | + m_clean_session = clean_session; | ||
| 109 | +} | ||
| 110 | + | ||
| 111 | +bool QMqttConfigSettings::getCleanSession() const | ||
| 112 | +{ | ||
| 113 | + return m_clean_session; | ||
| 114 | +} | ||
| 115 | + | ||
| 116 | +void QMqttConfigSettings::setAutoReconnect( bool reconnect ) | ||
| 117 | +{ | ||
| 118 | + m_auto_reconnect = reconnect; | ||
| 119 | +} | ||
| 120 | + | ||
| 121 | +bool QMqttConfigSettings::getAutoReconnect() const | ||
| 122 | +{ | ||
| 123 | + return m_auto_reconnect; | ||
| 124 | +} | ||
| 125 | + | ||
| 126 | +void QMqttConfigSettings::setAutoReconnectInterval( const int auto_reconnect_interval ) | ||
| 127 | +{ | ||
| 128 | + m_auto_reconnect_interval = auto_reconnect_interval; | ||
| 129 | +} | ||
| 130 | + | ||
| 131 | +int QMqttConfigSettings::getAutoReconnectInterval() const | ||
| 132 | +{ | ||
| 133 | + return m_auto_reconnect_interval; | ||
| 134 | +} |
src/qmqtt_configsettings.h
0 → 100644
| 1 | +++ a/src/qmqtt_configsettings.h | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifndef OSDEV_COMPONENTS_QMQTT_CONFIGSETTINGS_H | ||
| 23 | +#define OSDEV_COMPONENTS_QMQTT_CONFIGSETTINGS_H | ||
| 24 | + | ||
| 25 | +#include <QHostAddress> | ||
| 26 | +#include <QHostInfo> | ||
| 27 | +#include <QString> | ||
| 28 | +#include <QByteArray> | ||
| 29 | +#include <QUuid> | ||
| 30 | + | ||
| 31 | +namespace osdev { | ||
| 32 | +namespace components { | ||
| 33 | + | ||
| 34 | +class QMqttConfigSettings | ||
| 35 | +{ | ||
| 36 | +public: | ||
| 37 | + QMqttConfigSettings() | ||
| 38 | + : m_host_address( QHostAddress::LocalHost ) | ||
| 39 | + , m_host_name( "localhost" ) | ||
| 40 | + , m_host_port( 1883 ) | ||
| 41 | + , m_client_id( QUuid::createUuid().toString() ) | ||
| 42 | + , m_user_name( QString() ) | ||
| 43 | + , m_password( QByteArray() ) | ||
| 44 | + , m_keep_alive( 10 ) | ||
| 45 | + , m_clean_session( false ) | ||
| 46 | + , m_auto_reconnect( true ) | ||
| 47 | + , m_auto_reconnect_interval( 60 ) | ||
| 48 | + {} | ||
| 49 | + QMqttConfigSettings(const QHostAddress& host, const quint16 port ) | ||
| 50 | + : m_host_address( host ) | ||
| 51 | + , m_host_name( host.toString() ) | ||
| 52 | + , m_host_port( port ) | ||
| 53 | + , m_client_id( QUuid::createUuid().toString() ) | ||
| 54 | + , m_user_name( QString() ) | ||
| 55 | + , m_password( QByteArray() ) | ||
| 56 | + , m_keep_alive( 10 ) | ||
| 57 | + , m_clean_session( false ) | ||
| 58 | + , m_auto_reconnect( true ) | ||
| 59 | + , m_auto_reconnect_interval( 60 ) | ||
| 60 | + {} | ||
| 61 | + | ||
| 62 | + virtual ~QMqttConfigSettings(){} | ||
| 63 | + | ||
| 64 | + // All Getters. Setters are handled in the implementation. | ||
| 65 | + void setHostAddress( const QHostAddress &host ); | ||
| 66 | + QHostAddress getHostAddress() const; | ||
| 67 | + | ||
| 68 | + void setHostName( const QString& host_name ); | ||
| 69 | + QString getHostName() const; | ||
| 70 | + | ||
| 71 | + void setPortNumber( const quint16 port ); | ||
| 72 | + quint16 getPortNumber() const; | ||
| 73 | + | ||
| 74 | + void setClientId( const QString& clientId ); | ||
| 75 | + QString getClientId() const; | ||
| 76 | + | ||
| 77 | + void setUserName( const QString& user_name ); | ||
| 78 | + QString getUserName() const; | ||
| 79 | + | ||
| 80 | + void setPassword( const QByteArray& pass_word ); | ||
| 81 | + QByteArray getPassword() const; | ||
| 82 | + | ||
| 83 | + void setKeepAlive( const quint16 keep_alive ); | ||
| 84 | + quint16 getKeepAlive() const; | ||
| 85 | + | ||
| 86 | + void setCleanSession( bool clean_session ); | ||
| 87 | + bool getCleanSession() const; | ||
| 88 | + | ||
| 89 | + void setAutoReconnect( bool reconnect ); | ||
| 90 | + bool getAutoReconnect() const; | ||
| 91 | + | ||
| 92 | + void setAutoReconnectInterval( const int auto_reconnect_interval ); | ||
| 93 | + int getAutoReconnectInterval() const; | ||
| 94 | + | ||
| 95 | +private: | ||
| 96 | + QHostAddress m_host_address; | ||
| 97 | + QString m_host_name; | ||
| 98 | + quint16 m_host_port; | ||
| 99 | + QString m_client_id; | ||
| 100 | + QString m_user_name; | ||
| 101 | + QByteArray m_password; | ||
| 102 | + quint16 m_keep_alive; | ||
| 103 | + bool m_clean_session; | ||
| 104 | + bool m_auto_reconnect; | ||
| 105 | + int m_auto_reconnect_interval; | ||
| 106 | +}; | ||
| 107 | + | ||
| 108 | +} /* End namespace components */ | ||
| 109 | +} /* End namespace osdev */ | ||
| 110 | + | ||
| 111 | +#endif /* OSDEV_COMPONENTS_QMQTT_CONFIGSETTINGS_H */ |
src/qmqtt_frame.cpp
0 → 100644
| 1 | +++ a/src/qmqtt_frame.cpp | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#include "qmqtt_frame.h" | ||
| 23 | + | ||
| 24 | +#include <QLoggingCategory> | ||
| 25 | +#include <QDataStream> | ||
| 26 | + | ||
| 27 | +namespace QMQTT { | ||
| 28 | + | ||
| 29 | +Q_LOGGING_CATEGORY(frame, "qmqtt.frame") | ||
| 30 | + | ||
| 31 | +Frame::Frame() | ||
| 32 | + : _header(0) | ||
| 33 | + , _data(QByteArray()) | ||
| 34 | +{ | ||
| 35 | +} | ||
| 36 | + | ||
| 37 | +Frame::Frame(const quint8 header) | ||
| 38 | + : _header(header) | ||
| 39 | + , _data(QByteArray()) | ||
| 40 | +{ | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | +Frame::Frame(const quint8 header, const QByteArray &data) | ||
| 44 | + : _header(header) | ||
| 45 | + , _data(data) | ||
| 46 | +{ | ||
| 47 | +} | ||
| 48 | + | ||
| 49 | +Frame::Frame(const Frame& other) | ||
| 50 | +{ | ||
| 51 | + _header = other._header; | ||
| 52 | + _data = other._data; | ||
| 53 | +} | ||
| 54 | + | ||
| 55 | +Frame& Frame::operator=(const Frame& other) | ||
| 56 | +{ | ||
| 57 | + _header = other._header; | ||
| 58 | + _data = other._data; | ||
| 59 | + return *this; | ||
| 60 | +} | ||
| 61 | + | ||
| 62 | +bool Frame::operator==(const Frame& other) const | ||
| 63 | +{ | ||
| 64 | + return _header == other._header | ||
| 65 | + && _data == other._data; | ||
| 66 | +} | ||
| 67 | + | ||
| 68 | + | ||
| 69 | +Frame::~Frame() | ||
| 70 | +{ | ||
| 71 | +} | ||
| 72 | + | ||
| 73 | +quint8 Frame::header() const | ||
| 74 | +{ | ||
| 75 | + return _header; | ||
| 76 | +} | ||
| 77 | + | ||
| 78 | +QByteArray Frame::data() const | ||
| 79 | +{ | ||
| 80 | + return _data; | ||
| 81 | +} | ||
| 82 | + | ||
| 83 | +quint8 Frame::readChar() | ||
| 84 | +{ | ||
| 85 | + char c = _data.at(0); | ||
| 86 | + _data.remove(0, 1); | ||
| 87 | + return c; | ||
| 88 | +} | ||
| 89 | + | ||
| 90 | +quint16 Frame::readInt() | ||
| 91 | +{ | ||
| 92 | + quint8 msb = static_cast<quint8>(_data.at(0)); | ||
| 93 | + quint8 lsb = static_cast<quint8>(_data.at(1)); | ||
| 94 | + _data.remove(0, 2); | ||
| 95 | + return (msb << 8) | lsb; | ||
| 96 | +} | ||
| 97 | + | ||
| 98 | +QByteArray Frame::readByteArray() | ||
| 99 | +{ | ||
| 100 | + quint16 len = readInt(); | ||
| 101 | + QByteArray data = _data.left(len); | ||
| 102 | + _data.remove(0, len); | ||
| 103 | + return data; | ||
| 104 | +} | ||
| 105 | + | ||
| 106 | +QString Frame::readString() | ||
| 107 | +{ | ||
| 108 | + quint16 len = readInt(); | ||
| 109 | + QString s = QString::fromUtf8(_data.left(len)); | ||
| 110 | + _data.remove(0, len); | ||
| 111 | + return s; | ||
| 112 | +} | ||
| 113 | + | ||
| 114 | +void Frame::writeInt(const quint16 i) | ||
| 115 | +{ | ||
| 116 | + _data.append(MSB(i)); | ||
| 117 | + _data.append(LSB(i)); | ||
| 118 | +} | ||
| 119 | + | ||
| 120 | +void Frame::writeByteArray(const QByteArray &data) | ||
| 121 | +{ | ||
| 122 | + if (data.size() > (int)USHRT_MAX) | ||
| 123 | + { | ||
| 124 | + qCritical("qmqtt: Binary data size bigger than %u bytes, truncate it!", USHRT_MAX); | ||
| 125 | + writeInt(USHRT_MAX); | ||
| 126 | + _data.append(data.left(USHRT_MAX)); | ||
| 127 | + return; | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + writeInt(data.size()); | ||
| 131 | + _data.append(data); | ||
| 132 | +} | ||
| 133 | + | ||
| 134 | +void Frame::writeString(const QString &string) | ||
| 135 | +{ | ||
| 136 | + QByteArray data = string.toUtf8(); | ||
| 137 | + if (data.size() > (int)USHRT_MAX) | ||
| 138 | + { | ||
| 139 | + qCritical("qmqtt: String size bigger than %u bytes, truncate it!", USHRT_MAX); | ||
| 140 | + data.resize(USHRT_MAX); | ||
| 141 | + } | ||
| 142 | + writeInt(data.size()); | ||
| 143 | + _data.append(data); | ||
| 144 | +} | ||
| 145 | + | ||
| 146 | +void Frame::writeChar(const quint8 c) | ||
| 147 | +{ | ||
| 148 | + _data.append(c); | ||
| 149 | +} | ||
| 150 | + | ||
| 151 | +void Frame::writeRawData(const QByteArray &data) | ||
| 152 | +{ | ||
| 153 | + _data.append(data); | ||
| 154 | +} | ||
| 155 | + | ||
| 156 | +void Frame::write(QDataStream &stream) const | ||
| 157 | +{ | ||
| 158 | + QByteArray lenbuf; | ||
| 159 | + | ||
| 160 | + if (!encodeLength(lenbuf, _data.size())) | ||
| 161 | + { | ||
| 162 | + qCritical("qmqtt: Control packet bigger than 256 MB, dropped!"); | ||
| 163 | + return; | ||
| 164 | + } | ||
| 165 | + | ||
| 166 | + stream << (quint8)_header; | ||
| 167 | + if(_data.size() == 0) { | ||
| 168 | + stream << (quint8)0; | ||
| 169 | + return; | ||
| 170 | + } | ||
| 171 | + if (stream.writeRawData(lenbuf.data(), lenbuf.size()) != lenbuf.size()) | ||
| 172 | + { | ||
| 173 | + qCritical("qmqtt: Control packet write error!"); | ||
| 174 | + return; | ||
| 175 | + } | ||
| 176 | + if (stream.writeRawData(_data.data(), _data.size()) != _data.size()) | ||
| 177 | + { | ||
| 178 | + qCritical("qmqtt: Control packet write error!"); | ||
| 179 | + } | ||
| 180 | +} | ||
| 181 | + | ||
| 182 | +bool Frame::encodeLength(QByteArray &lenbuf, int length) const | ||
| 183 | +{ | ||
| 184 | + lenbuf.clear(); | ||
| 185 | + quint8 d; | ||
| 186 | + do { | ||
| 187 | + d = length % 128; | ||
| 188 | + length /= 128; | ||
| 189 | + if (length > 0) { | ||
| 190 | + d |= 0x80; | ||
| 191 | + } | ||
| 192 | + lenbuf.append(d); | ||
| 193 | + } while (length > 0); | ||
| 194 | + | ||
| 195 | + return lenbuf.size() <= 4; | ||
| 196 | +} | ||
| 197 | + | ||
| 198 | +} // namespace QMQTT |
src/qmqtt_frame.h
0 → 100644
| 1 | +++ a/src/qmqtt_frame.h | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifndef QMQTT_FRAME_H | ||
| 23 | +#define QMQTT_FRAME_H | ||
| 24 | + | ||
| 25 | +#include "qmqtt_global.h" | ||
| 26 | + | ||
| 27 | +#include <QMetaType> | ||
| 28 | +#include <QByteArray> | ||
| 29 | +#include <QString> | ||
| 30 | + | ||
| 31 | +QT_FORWARD_DECLARE_CLASS(QDataStream) | ||
| 32 | + | ||
| 33 | +#define PROTOCOL_MAGIC_3_1_0 "MQIsdp" | ||
| 34 | +#define PROTOCOL_MAGIC_3_1_1 "MQTT" | ||
| 35 | + | ||
| 36 | +#define RANDOM_CLIENT_PREFIX "QMQTT-" | ||
| 37 | + | ||
| 38 | +#define CONNECT 0x10 | ||
| 39 | +#define CONNACK 0x20 | ||
| 40 | +#define PUBLISH 0x30 | ||
| 41 | +#define PUBACK 0x40 | ||
| 42 | +#define PUBREC 0x50 | ||
| 43 | +#define PUBREL 0x60 | ||
| 44 | +#define PUBCOMP 0x70 | ||
| 45 | +#define SUBSCRIBE 0x80 | ||
| 46 | +#define SUBACK 0x90 | ||
| 47 | +#define UNSUBSCRIBE 0xA0 | ||
| 48 | +#define UNSUBACK 0xB0 | ||
| 49 | +#define PINGREQ 0xC0 | ||
| 50 | +#define PINGRESP 0xD0 | ||
| 51 | +#define DISCONNECT 0xE0 | ||
| 52 | + | ||
| 53 | +#define LSB(A) quint8(A & 0x00FF) | ||
| 54 | +#define MSB(A) quint8((A & 0xFF00) >> 8) | ||
| 55 | + | ||
| 56 | +/* | ||
| 57 | +|-------------------------------------- | ||
| 58 | +| 7 6 5 4 | 3 | 2 1 | 0 | | ||
| 59 | +| Type | DUP flag | QoS | RETAIN | | ||
| 60 | +|-------------------------------------- | ||
| 61 | +*/ | ||
| 62 | +#define GETTYPE(HDR) (HDR & 0xF0) | ||
| 63 | +#define SETQOS(HDR, Q) (HDR | ((Q) << 1)) | ||
| 64 | +#define GETQOS(HDR) ((HDR & 0x06) >> 1) | ||
| 65 | +#define SETDUP(HDR, D) (HDR | ((D) << 3)) | ||
| 66 | +#define GETDUP(HDR) ((HDR & 0x08) >> 3) | ||
| 67 | +#define SETRETAIN(HDR, R) (HDR | (R)) | ||
| 68 | +#define GETRETAIN(HDR) (HDR & 0x01) | ||
| 69 | + | ||
| 70 | +/* | ||
| 71 | +|---------------------------------------------------------------------------------- | ||
| 72 | +| 7 | 6 | 5 | 4 3 | 2 | 1 | 0 | | ||
| 73 | +| username | password | willretain | willqos | willflag | cleansession | reserved | | ||
| 74 | +|---------------------------------------------------------------------------------- | ||
| 75 | +*/ | ||
| 76 | +#define FLAG_CLEANSESS(F, C) (F | ((C) << 1)) | ||
| 77 | +#define FLAG_WILL(F, W) (F | ((W) << 2)) | ||
| 78 | +#define FLAG_WILLQOS(F, Q) (F | ((Q) << 3)) | ||
| 79 | +#define FLAG_WILLRETAIN(F, R) (F | ((R) << 5)) | ||
| 80 | +#define FLAG_PASSWD(F, P) (F | ((P) << 6)) | ||
| 81 | +#define FLAG_USERNAME(F, U) (F | ((U) << 7)) | ||
| 82 | + | ||
| 83 | +namespace QMQTT { | ||
| 84 | + | ||
| 85 | +class Q_MQTT_EXPORT Frame | ||
| 86 | +{ | ||
| 87 | +public: | ||
| 88 | + explicit Frame(); | ||
| 89 | + explicit Frame(const quint8 header); | ||
| 90 | + explicit Frame(const quint8 header, const QByteArray &data); | ||
| 91 | + virtual ~Frame(); | ||
| 92 | + | ||
| 93 | + Frame(const Frame& other); | ||
| 94 | + Frame& operator=(const Frame& other); | ||
| 95 | + | ||
| 96 | + bool operator==(const Frame& other) const; | ||
| 97 | + inline bool operator!=(const Frame& other) const | ||
| 98 | + { return !operator==(other); } | ||
| 99 | + | ||
| 100 | + quint8 header() const; | ||
| 101 | + QByteArray data() const; | ||
| 102 | + | ||
| 103 | + quint16 readInt(); | ||
| 104 | + quint8 readChar(); | ||
| 105 | + QByteArray readByteArray(); | ||
| 106 | + QString readString(); | ||
| 107 | + | ||
| 108 | + void writeInt(const quint16 i); | ||
| 109 | + void writeChar(const quint8 c); | ||
| 110 | + void writeByteArray(const QByteArray &data); | ||
| 111 | + void writeString(const QString &string); | ||
| 112 | + void writeRawData(const QByteArray &data); | ||
| 113 | + | ||
| 114 | + //TODO: FIXME LATER | ||
| 115 | + void write(QDataStream &stream) const; | ||
| 116 | + bool encodeLength(QByteArray &lenbuf, int length) const; | ||
| 117 | + | ||
| 118 | +private: | ||
| 119 | + quint8 _header; | ||
| 120 | + QByteArray _data; | ||
| 121 | +}; | ||
| 122 | + | ||
| 123 | +} // namespace QMQTT | ||
| 124 | + | ||
| 125 | +Q_DECLARE_METATYPE(QMQTT::Frame) | ||
| 126 | + | ||
| 127 | +#endif // QMQTT_FRAME_H |
src/qmqtt_global.h
0 → 100644
| 1 | +++ a/src/qmqtt_global.h | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifndef QMQTT_GLOBAL_H | ||
| 23 | +#define QMQTT_GLOBAL_H | ||
| 24 | + | ||
| 25 | +#include <QtGlobal> | ||
| 26 | + | ||
| 27 | +#if !defined(QT_STATIC) && !defined(MQTT_PROJECT_INCLUDE_SRC) | ||
| 28 | +# if defined(QT_BUILD_QMQTT_LIB) | ||
| 29 | +# define Q_MQTT_EXPORT Q_DECL_EXPORT | ||
| 30 | +# else | ||
| 31 | +# define Q_MQTT_EXPORT Q_DECL_IMPORT | ||
| 32 | +# endif | ||
| 33 | +#else | ||
| 34 | +# define Q_MQTT_EXPORT | ||
| 35 | +#endif | ||
| 36 | + | ||
| 37 | +#endif // QMQTT_GLOBAL_H | ||
| 38 | + |
src/qmqtt_message.cpp
0 → 100644
| 1 | +++ a/src/qmqtt_message.cpp | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#include "qmqtt_message.h" | ||
| 23 | +#include "qmqtt_message_p.h" | ||
| 24 | + | ||
| 25 | +namespace QMQTT { | ||
| 26 | + | ||
| 27 | +Message::Message() | ||
| 28 | + : d(new MessagePrivate) | ||
| 29 | +{ | ||
| 30 | +} | ||
| 31 | + | ||
| 32 | +Message::Message(const quint16 id, const QString &topic, const QByteArray &payload, | ||
| 33 | + const quint8 qos, const bool retain, const bool dup) | ||
| 34 | + : d(new MessagePrivate(id, topic, payload, qos, retain, dup)) | ||
| 35 | +{ | ||
| 36 | +} | ||
| 37 | + | ||
| 38 | +Message::Message(const Message &other) | ||
| 39 | + : d(other.d) | ||
| 40 | +{ | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | +Message::~Message() | ||
| 44 | +{ | ||
| 45 | +} | ||
| 46 | + | ||
| 47 | +Message &Message::operator=(const Message &other) | ||
| 48 | +{ | ||
| 49 | + d = other.d; | ||
| 50 | + return *this; | ||
| 51 | +} | ||
| 52 | + | ||
| 53 | +bool Message::operator==(const Message &other) const | ||
| 54 | +{ | ||
| 55 | + if (d == other.d) | ||
| 56 | + return true; | ||
| 57 | + return d->id == other.d->id | ||
| 58 | + && d->qos == other.d->qos | ||
| 59 | + && d->retain == other.d->retain | ||
| 60 | + && d->dup == other.d->dup | ||
| 61 | + && d->topic == other.d->topic | ||
| 62 | + && d->payload == other.d->payload; | ||
| 63 | +} | ||
| 64 | + | ||
| 65 | +quint16 Message::id() const | ||
| 66 | +{ | ||
| 67 | + return d->id; | ||
| 68 | +} | ||
| 69 | + | ||
| 70 | +void Message::setId(const quint16 id) | ||
| 71 | +{ | ||
| 72 | + d->id = id; | ||
| 73 | +} | ||
| 74 | + | ||
| 75 | +quint8 Message::qos() const | ||
| 76 | +{ | ||
| 77 | + return d->qos; | ||
| 78 | +} | ||
| 79 | + | ||
| 80 | +void Message::setQos(const quint8 qos) | ||
| 81 | +{ | ||
| 82 | + d->qos = qos; | ||
| 83 | +} | ||
| 84 | + | ||
| 85 | +bool Message::retain() const | ||
| 86 | +{ | ||
| 87 | + return d->retain; | ||
| 88 | +} | ||
| 89 | + | ||
| 90 | +void Message::setRetain(const bool retain) | ||
| 91 | +{ | ||
| 92 | + d->retain = retain; | ||
| 93 | +} | ||
| 94 | + | ||
| 95 | +bool Message::dup() const | ||
| 96 | +{ | ||
| 97 | + return d->dup; | ||
| 98 | +} | ||
| 99 | + | ||
| 100 | +void Message::setDup(const bool dup) | ||
| 101 | +{ | ||
| 102 | + d->dup = dup; | ||
| 103 | +} | ||
| 104 | + | ||
| 105 | +QString Message::topic() const | ||
| 106 | +{ | ||
| 107 | + return d->topic; | ||
| 108 | +} | ||
| 109 | + | ||
| 110 | +void Message::setTopic(const QString &topic) | ||
| 111 | +{ | ||
| 112 | + d->topic = topic; | ||
| 113 | +} | ||
| 114 | + | ||
| 115 | +QByteArray Message::payload() const | ||
| 116 | +{ | ||
| 117 | + return d->payload; | ||
| 118 | +} | ||
| 119 | + | ||
| 120 | +void Message::setPayload(const QByteArray &payload) | ||
| 121 | +{ | ||
| 122 | + d->payload = payload; | ||
| 123 | +} | ||
| 124 | + | ||
| 125 | +} // namespace QMQTT |
src/qmqtt_message.h
0 → 100644
| 1 | +++ a/src/qmqtt_message.h | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifndef QMQTT_MESSAGE_H | ||
| 23 | +#define QMQTT_MESSAGE_H | ||
| 24 | + | ||
| 25 | +#include "qmqtt_global.h" | ||
| 26 | + | ||
| 27 | +#include <QMetaType> | ||
| 28 | +#include <QString> | ||
| 29 | +#include <QByteArray> | ||
| 30 | +#include <QSharedDataPointer> | ||
| 31 | + | ||
| 32 | +namespace QMQTT { | ||
| 33 | + | ||
| 34 | +class MessagePrivate; | ||
| 35 | + | ||
| 36 | +class Q_MQTT_EXPORT Message | ||
| 37 | +{ | ||
| 38 | +public: | ||
| 39 | + Message(); | ||
| 40 | + explicit Message(const quint16 id, const QString &topic, const QByteArray &payload, | ||
| 41 | + const quint8 qos = 0, const bool retain = false, const bool dup = false); | ||
| 42 | + Message(const Message &other); | ||
| 43 | + ~Message(); | ||
| 44 | + | ||
| 45 | + Message &operator=(const Message &other); | ||
| 46 | +#ifdef Q_COMPILER_RVALUE_REFS | ||
| 47 | + inline Message &operator=(Message &&other) Q_DECL_NOTHROW | ||
| 48 | + { swap(other); return *this; } | ||
| 49 | +#endif | ||
| 50 | + | ||
| 51 | + bool operator==(const Message &other) const; | ||
| 52 | + inline bool operator!=(const Message &other) const | ||
| 53 | + { return !operator==(other); } | ||
| 54 | + | ||
| 55 | + inline void swap(Message &other) Q_DECL_NOTHROW | ||
| 56 | + { qSwap(d, other.d); } | ||
| 57 | + | ||
| 58 | + quint16 id() const; | ||
| 59 | + void setId(const quint16 id); | ||
| 60 | + | ||
| 61 | + quint8 qos() const; | ||
| 62 | + void setQos(const quint8 qos); | ||
| 63 | + | ||
| 64 | + bool retain() const; | ||
| 65 | + void setRetain(const bool retain); | ||
| 66 | + | ||
| 67 | + bool dup() const; | ||
| 68 | + void setDup(const bool dup); | ||
| 69 | + | ||
| 70 | + QString topic() const; | ||
| 71 | + void setTopic(const QString &topic); | ||
| 72 | + | ||
| 73 | + QByteArray payload() const; | ||
| 74 | + void setPayload(const QByteArray &payload); | ||
| 75 | + | ||
| 76 | +private: | ||
| 77 | + QSharedDataPointer<MessagePrivate> d; | ||
| 78 | +}; | ||
| 79 | + | ||
| 80 | +} // namespace QMQTT | ||
| 81 | + | ||
| 82 | +Q_DECLARE_SHARED(QMQTT::Message) | ||
| 83 | + | ||
| 84 | +Q_DECLARE_METATYPE(QMQTT::Message) | ||
| 85 | + | ||
| 86 | +#endif // QMQTT_MESSAGE_H |
src/qmqtt_message_p.h
0 → 100644
| 1 | +++ a/src/qmqtt_message_p.h | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifndef QMQTT_MESSAGE_P_H | ||
| 23 | +#define QMQTT_MESSAGE_P_H | ||
| 24 | + | ||
| 25 | +#include <QSharedData> | ||
| 26 | +#include <QString> | ||
| 27 | +#include <QByteArray> | ||
| 28 | + | ||
| 29 | +namespace QMQTT { | ||
| 30 | + | ||
| 31 | +class MessagePrivate : public QSharedData | ||
| 32 | +{ | ||
| 33 | +public: | ||
| 34 | + inline MessagePrivate() | ||
| 35 | + : QSharedData(), | ||
| 36 | + id(0), | ||
| 37 | + qos(0), | ||
| 38 | + retain(false), | ||
| 39 | + dup(false) | ||
| 40 | + {} | ||
| 41 | + | ||
| 42 | + inline MessagePrivate(const MessagePrivate &other) | ||
| 43 | + : QSharedData(other), | ||
| 44 | + id(other.id), | ||
| 45 | + qos(other.qos), | ||
| 46 | + retain(other.retain), | ||
| 47 | + dup(other.dup), | ||
| 48 | + topic(other.topic), | ||
| 49 | + payload(other.payload) | ||
| 50 | + {} | ||
| 51 | + | ||
| 52 | + inline MessagePrivate(quint16 id, const QString &topic, const QByteArray &payload, | ||
| 53 | + quint8 qos, bool retain, bool dup) | ||
| 54 | + : QSharedData(), | ||
| 55 | + id(id), | ||
| 56 | + qos(qos), | ||
| 57 | + retain(retain), | ||
| 58 | + dup(dup), | ||
| 59 | + topic(topic), | ||
| 60 | + payload(payload) | ||
| 61 | + {} | ||
| 62 | + | ||
| 63 | + quint16 id; | ||
| 64 | + quint8 qos : 2; | ||
| 65 | + quint8 retain: 1; | ||
| 66 | + quint8 dup: 1; | ||
| 67 | + QString topic; | ||
| 68 | + QByteArray payload; | ||
| 69 | +}; | ||
| 70 | + | ||
| 71 | +} // namespace QMQTT | ||
| 72 | + | ||
| 73 | +#endif // QMQTT_MESSAGE_P_H |
src/qmqtt_network.cpp
0 → 100644
| 1 | +++ a/src/qmqtt_network.cpp | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#include "qmqtt_network_p.h" | ||
| 23 | +#include "qmqtt_socket_p.h" | ||
| 24 | +#include "qmqtt_ssl_socket_p.h" | ||
| 25 | +#include "qmqtt_timer_p.h" | ||
| 26 | +#include "qmqtt_websocket_p.h" | ||
| 27 | +#include "qmqtt_frame.h" | ||
| 28 | + | ||
| 29 | +#include <QDataStream> | ||
| 30 | + | ||
| 31 | +const quint16 DEFAULT_PORT = 1883; | ||
| 32 | +const quint16 DEFAULT_SSL_PORT = 8883; | ||
| 33 | +const bool DEFAULT_AUTORECONNECT = false; | ||
| 34 | +const int DEFAULT_AUTORECONNECT_INTERVAL_MS = 5000; | ||
| 35 | + | ||
| 36 | +QMQTT::Network::Network(QObject* parent) | ||
| 37 | + : NetworkInterface(parent) | ||
| 38 | + , _port(DEFAULT_PORT) | ||
| 39 | + , _autoReconnect(DEFAULT_AUTORECONNECT) | ||
| 40 | + , _autoReconnectInterval(DEFAULT_AUTORECONNECT_INTERVAL_MS) | ||
| 41 | + , _socket(new QMQTT::Socket) | ||
| 42 | + , _autoReconnectTimer(new QMQTT::Timer) | ||
| 43 | + , _readState(Header) | ||
| 44 | +{ | ||
| 45 | + initialize(); | ||
| 46 | +} | ||
| 47 | + | ||
| 48 | +#ifndef QT_NO_SSL | ||
| 49 | +QMQTT::Network::Network(const QSslConfiguration& config, QObject *parent) | ||
| 50 | + : NetworkInterface(parent) | ||
| 51 | + , _port(DEFAULT_SSL_PORT) | ||
| 52 | + , _autoReconnect(DEFAULT_AUTORECONNECT) | ||
| 53 | + , _autoReconnectInterval(DEFAULT_AUTORECONNECT_INTERVAL_MS) | ||
| 54 | + , _socket(new QMQTT::SslSocket(config)) | ||
| 55 | + , _autoReconnectTimer(new QMQTT::Timer) | ||
| 56 | + , _readState(Header) | ||
| 57 | +{ | ||
| 58 | + initialize(); | ||
| 59 | + connect(_socket, &QMQTT::SslSocket::sslErrors, this, &QMQTT::Network::sslErrors); | ||
| 60 | +} | ||
| 61 | +#endif // QT_NO_SSL | ||
| 62 | + | ||
| 63 | +#ifdef QT_WEBSOCKETS_LIB | ||
| 64 | +#ifndef QT_NO_SSL | ||
| 65 | +QMQTT::Network::Network(const QString& origin, | ||
| 66 | + QWebSocketProtocol::Version version, | ||
| 67 | + const QSslConfiguration* sslConfig, | ||
| 68 | + QObject* parent) | ||
| 69 | + : NetworkInterface(parent) | ||
| 70 | + , _port(DEFAULT_SSL_PORT) | ||
| 71 | + , _autoReconnect(DEFAULT_AUTORECONNECT) | ||
| 72 | + , _autoReconnectInterval(DEFAULT_AUTORECONNECT_INTERVAL_MS) | ||
| 73 | + , _socket(new QMQTT::WebSocket(origin, version, sslConfig)) | ||
| 74 | + , _autoReconnectTimer(new QMQTT::Timer) | ||
| 75 | + , _readState(Header) | ||
| 76 | +{ | ||
| 77 | + initialize(); | ||
| 78 | +} | ||
| 79 | +#endif // QT_NO_SSL | ||
| 80 | + | ||
| 81 | +QMQTT::Network::Network(const QString& origin, | ||
| 82 | + QWebSocketProtocol::Version version, | ||
| 83 | + QObject* parent) | ||
| 84 | + : NetworkInterface(parent) | ||
| 85 | + , _port(DEFAULT_PORT) | ||
| 86 | + , _autoReconnect(DEFAULT_AUTORECONNECT) | ||
| 87 | + , _autoReconnectInterval(DEFAULT_AUTORECONNECT_INTERVAL_MS) | ||
| 88 | + , _socket(new QMQTT::WebSocket(origin, version)) | ||
| 89 | + , _autoReconnectTimer(new QMQTT::Timer) | ||
| 90 | + , _readState(Header) | ||
| 91 | +{ | ||
| 92 | + initialize(); | ||
| 93 | +} | ||
| 94 | +#endif // QT_WEBSOCKETS_LIB | ||
| 95 | + | ||
| 96 | +QMQTT::Network::Network(SocketInterface* socketInterface, TimerInterface* timerInterface, | ||
| 97 | + QObject* parent) | ||
| 98 | + : NetworkInterface(parent) | ||
| 99 | + , _port(DEFAULT_PORT) | ||
| 100 | + , _autoReconnect(DEFAULT_AUTORECONNECT) | ||
| 101 | + , _autoReconnectInterval(DEFAULT_AUTORECONNECT_INTERVAL_MS) | ||
| 102 | + , _socket(socketInterface) | ||
| 103 | + , _autoReconnectTimer(timerInterface) | ||
| 104 | + , _readState(Header) | ||
| 105 | +{ | ||
| 106 | + initialize(); | ||
| 107 | +} | ||
| 108 | + | ||
| 109 | +void QMQTT::Network::initialize() | ||
| 110 | +{ | ||
| 111 | + _socket->setParent(this); | ||
| 112 | + _autoReconnectTimer->setParent(this); | ||
| 113 | + _autoReconnectTimer->setSingleShot(true); | ||
| 114 | + _autoReconnectTimer->setInterval(_autoReconnectInterval); | ||
| 115 | + | ||
| 116 | + QObject::connect(_socket, &SocketInterface::connected, this, &Network::connected); | ||
| 117 | + QObject::connect(_socket, &SocketInterface::disconnected, this, &Network::onDisconnected); | ||
| 118 | + QObject::connect(_socket->ioDevice(), &QIODevice::readyRead, this, &Network::onSocketReadReady); | ||
| 119 | + QObject::connect( | ||
| 120 | + _autoReconnectTimer, &TimerInterface::timeout, | ||
| 121 | + this, static_cast<void (Network::*)()>(&Network::connectToHost)); | ||
| 122 | + QObject::connect(_socket, | ||
| 123 | + static_cast<void (SocketInterface::*)(QAbstractSocket::SocketError)>(&SocketInterface::error), | ||
| 124 | + this, &Network::onSocketError); | ||
| 125 | +} | ||
| 126 | + | ||
| 127 | +QMQTT::Network::~Network() | ||
| 128 | +{ | ||
| 129 | +} | ||
| 130 | + | ||
| 131 | +bool QMQTT::Network::isConnectedToHost() const | ||
| 132 | +{ | ||
| 133 | + return _socket->state() == QAbstractSocket::ConnectedState; | ||
| 134 | +} | ||
| 135 | + | ||
| 136 | +void QMQTT::Network::connectToHost(const QHostAddress& host, const quint16 port) | ||
| 137 | +{ | ||
| 138 | + // Reset the hostname, because if it is not empty connectToHost() will use it instead of _host. | ||
| 139 | + _hostName.clear(); | ||
| 140 | + _host = host; | ||
| 141 | + _port = port; | ||
| 142 | + connectToHost(); | ||
| 143 | +} | ||
| 144 | + | ||
| 145 | +void QMQTT::Network::connectToHost(const QString& hostName, const quint16 port) | ||
| 146 | +{ | ||
| 147 | + _hostName = hostName; | ||
| 148 | + _port = port; | ||
| 149 | + connectToHost(); | ||
| 150 | +} | ||
| 151 | + | ||
| 152 | +void QMQTT::Network::connectToHost() | ||
| 153 | +{ | ||
| 154 | + _readState = Header; | ||
| 155 | + if (_hostName.isEmpty()) | ||
| 156 | + { | ||
| 157 | + _socket->connectToHost(_host, _port); | ||
| 158 | + } | ||
| 159 | + else | ||
| 160 | + { | ||
| 161 | + _socket->connectToHost(_hostName, _port); | ||
| 162 | + } | ||
| 163 | +} | ||
| 164 | + | ||
| 165 | +void QMQTT::Network::onSocketError(QAbstractSocket::SocketError socketError) | ||
| 166 | +{ | ||
| 167 | + emit error(socketError); | ||
| 168 | + if(_autoReconnect) | ||
| 169 | + { | ||
| 170 | + _autoReconnectTimer->start(); | ||
| 171 | + } | ||
| 172 | +} | ||
| 173 | + | ||
| 174 | +void QMQTT::Network::sendFrame(const Frame& frame) | ||
| 175 | +{ | ||
| 176 | + if(_socket->state() == QAbstractSocket::ConnectedState) | ||
| 177 | + { | ||
| 178 | + QDataStream out(_socket->ioDevice()); | ||
| 179 | + frame.write(out); | ||
| 180 | + } | ||
| 181 | +} | ||
| 182 | + | ||
| 183 | +void QMQTT::Network::disconnectFromHost() | ||
| 184 | +{ | ||
| 185 | + _socket->disconnectFromHost(); | ||
| 186 | +} | ||
| 187 | + | ||
| 188 | +QAbstractSocket::SocketState QMQTT::Network::state() const | ||
| 189 | +{ | ||
| 190 | + return _socket->state(); | ||
| 191 | +} | ||
| 192 | + | ||
| 193 | +bool QMQTT::Network::autoReconnect() const | ||
| 194 | +{ | ||
| 195 | + return _autoReconnect; | ||
| 196 | +} | ||
| 197 | + | ||
| 198 | +void QMQTT::Network::setAutoReconnect(const bool autoReconnect) | ||
| 199 | +{ | ||
| 200 | + _autoReconnect = autoReconnect; | ||
| 201 | +} | ||
| 202 | + | ||
| 203 | +int QMQTT::Network::autoReconnectInterval() const | ||
| 204 | +{ | ||
| 205 | + return _autoReconnectInterval; | ||
| 206 | +} | ||
| 207 | + | ||
| 208 | +void QMQTT::Network::setAutoReconnectInterval(const int autoReconnectInterval) | ||
| 209 | +{ | ||
| 210 | + _autoReconnectInterval = autoReconnectInterval; | ||
| 211 | + _autoReconnectTimer->setInterval(_autoReconnectInterval); | ||
| 212 | +} | ||
| 213 | + | ||
| 214 | +void QMQTT::Network::onSocketReadReady() | ||
| 215 | +{ | ||
| 216 | + QIODevice *ioDevice = _socket->ioDevice(); | ||
| 217 | + // Only read the available (cached) bytes, so the read will never block. | ||
| 218 | + QByteArray data = ioDevice->read(ioDevice->bytesAvailable()); | ||
| 219 | + foreach(char byte, data) { | ||
| 220 | + switch (_readState) { | ||
| 221 | + case Header: | ||
| 222 | + _header = static_cast<quint8>(byte); | ||
| 223 | + _readState = Length; | ||
| 224 | + _length = 0; | ||
| 225 | + _shift = 0; | ||
| 226 | + _data.resize(0); // keep allocated buffer | ||
| 227 | + break; | ||
| 228 | + case Length: | ||
| 229 | + _length |= (byte & 0x7F) << _shift; | ||
| 230 | + _shift += 7; | ||
| 231 | + if ((byte & 0x80) != 0) | ||
| 232 | + break; | ||
| 233 | + if (_length == 0) { | ||
| 234 | + _readState = Header; | ||
| 235 | + Frame frame(_header, _data); | ||
| 236 | + emit received(frame); | ||
| 237 | + break; | ||
| 238 | + } | ||
| 239 | + _readState = PayLoad; | ||
| 240 | + _data.reserve(_length); | ||
| 241 | + break; | ||
| 242 | + case PayLoad: | ||
| 243 | + _data.append(byte); | ||
| 244 | + --_length; | ||
| 245 | + if (_length > 0) | ||
| 246 | + break; | ||
| 247 | + _readState = Header; | ||
| 248 | + Frame frame(_header, _data); | ||
| 249 | + emit received(frame); | ||
| 250 | + break; | ||
| 251 | + } | ||
| 252 | + } | ||
| 253 | +} | ||
| 254 | + | ||
| 255 | +void QMQTT::Network::onDisconnected() | ||
| 256 | +{ | ||
| 257 | + emit disconnected(); | ||
| 258 | + if(_autoReconnect) | ||
| 259 | + { | ||
| 260 | + _autoReconnectTimer->start(); | ||
| 261 | + } | ||
| 262 | +} | ||
| 263 | + | ||
| 264 | +#ifndef QT_NO_SSL | ||
| 265 | +void QMQTT::Network::ignoreSslErrors(const QList<QSslError>& errors) | ||
| 266 | +{ | ||
| 267 | + _socket->ignoreSslErrors(errors); | ||
| 268 | +} | ||
| 269 | + | ||
| 270 | +void QMQTT::Network::ignoreSslErrors() | ||
| 271 | +{ | ||
| 272 | + _socket->ignoreSslErrors(); | ||
| 273 | +} | ||
| 274 | + | ||
| 275 | +QSslConfiguration QMQTT::Network::sslConfiguration() const | ||
| 276 | +{ | ||
| 277 | + return _socket->sslConfiguration(); | ||
| 278 | +} | ||
| 279 | + | ||
| 280 | +void QMQTT::Network::setSslConfiguration(const QSslConfiguration& config) | ||
| 281 | +{ | ||
| 282 | + _socket->setSslConfiguration(config); | ||
| 283 | +} | ||
| 284 | +#endif // QT_NO_SSL |
src/qmqtt_network_p.h
0 → 100644
| 1 | +++ a/src/qmqtt_network_p.h | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifndef QMQTT_NETWORK_P_H | ||
| 23 | +#define QMQTT_NETWORK_P_H | ||
| 24 | + | ||
| 25 | +#include "qmqtt_networkinterface.h" | ||
| 26 | + | ||
| 27 | +#include <QObject> | ||
| 28 | +#include <QHostAddress> | ||
| 29 | +#include <QString> | ||
| 30 | +#include <QByteArray> | ||
| 31 | + | ||
| 32 | +#ifdef QT_WEBSOCKETS_LIB | ||
| 33 | +#include <QWebSocket> | ||
| 34 | +#endif // QT_WEBSOCKETS_LIB | ||
| 35 | + | ||
| 36 | +#ifndef QT_NO_SSL | ||
| 37 | +#include <QSslConfiguration> | ||
| 38 | +QT_FORWARD_DECLARE_CLASS(QSslError) | ||
| 39 | +#endif // QT_NO_SSL | ||
| 40 | + | ||
| 41 | +namespace QMQTT { | ||
| 42 | + | ||
| 43 | +class SocketInterface; | ||
| 44 | +class TimerInterface; | ||
| 45 | +class Frame; | ||
| 46 | + | ||
| 47 | +class Network : public NetworkInterface | ||
| 48 | +{ | ||
| 49 | + Q_OBJECT | ||
| 50 | + | ||
| 51 | +public: | ||
| 52 | + Network(QObject* parent = NULL); | ||
| 53 | +#ifndef QT_NO_SSL | ||
| 54 | + Network(const QSslConfiguration& config, QObject* parent = NULL); | ||
| 55 | +#endif // QT_NO_SSL | ||
| 56 | +#ifdef QT_WEBSOCKETS_LIB | ||
| 57 | +#ifndef QT_NO_SSL | ||
| 58 | + Network(const QString& origin, | ||
| 59 | + QWebSocketProtocol::Version version, | ||
| 60 | + const QSslConfiguration* sslConfig, | ||
| 61 | + QObject* parent = NULL); | ||
| 62 | +#endif // QT_NO_SSL | ||
| 63 | + Network(const QString& origin, | ||
| 64 | + QWebSocketProtocol::Version version, | ||
| 65 | + QObject* parent = NULL); | ||
| 66 | +#endif // QT_WEBSOCKETS_LIB | ||
| 67 | + Network(SocketInterface* socketInterface, TimerInterface* timerInterface, | ||
| 68 | + QObject* parent = NULL); | ||
| 69 | + ~Network(); | ||
| 70 | + | ||
| 71 | + void sendFrame(const Frame &frame); | ||
| 72 | + bool isConnectedToHost() const; | ||
| 73 | + bool autoReconnect() const; | ||
| 74 | + void setAutoReconnect(const bool autoReconnect); | ||
| 75 | + QAbstractSocket::SocketState state() const; | ||
| 76 | + int autoReconnectInterval() const; | ||
| 77 | + void setAutoReconnectInterval(const int autoReconnectInterval); | ||
| 78 | +#ifndef QT_NO_SSL | ||
| 79 | + void ignoreSslErrors(const QList<QSslError>& errors); | ||
| 80 | + QSslConfiguration sslConfiguration() const; | ||
| 81 | + void setSslConfiguration(const QSslConfiguration& config); | ||
| 82 | +#endif // QT_NO_SSL | ||
| 83 | + | ||
| 84 | +public slots: | ||
| 85 | + void connectToHost(const QHostAddress& host, const quint16 port); | ||
| 86 | + void connectToHost(const QString& hostName, const quint16 port); | ||
| 87 | + void disconnectFromHost(); | ||
| 88 | +#ifndef QT_NO_SSL | ||
| 89 | + void ignoreSslErrors(); | ||
| 90 | +#endif // QT_NO_SSL | ||
| 91 | + | ||
| 92 | +protected slots: | ||
| 93 | + void onSocketError(QAbstractSocket::SocketError socketError); | ||
| 94 | + | ||
| 95 | +protected: | ||
| 96 | + void initialize(); | ||
| 97 | + | ||
| 98 | + quint16 _port; | ||
| 99 | + QHostAddress _host; | ||
| 100 | + QString _hostName; | ||
| 101 | + bool _autoReconnect; | ||
| 102 | + int _autoReconnectInterval; | ||
| 103 | + SocketInterface* _socket; | ||
| 104 | + TimerInterface* _autoReconnectTimer; | ||
| 105 | + | ||
| 106 | + enum ReadState { | ||
| 107 | + Header, | ||
| 108 | + Length, | ||
| 109 | + PayLoad | ||
| 110 | + }; | ||
| 111 | + | ||
| 112 | + ReadState _readState; | ||
| 113 | + quint8 _header; | ||
| 114 | + int _length; | ||
| 115 | + int _shift; | ||
| 116 | + QByteArray _data; | ||
| 117 | + | ||
| 118 | +protected slots: | ||
| 119 | + void onSocketReadReady(); | ||
| 120 | + void onDisconnected(); | ||
| 121 | + void connectToHost(); | ||
| 122 | + | ||
| 123 | +private: | ||
| 124 | + Q_DISABLE_COPY(Network) | ||
| 125 | +}; | ||
| 126 | + | ||
| 127 | +} // namespace QMQTT | ||
| 128 | + | ||
| 129 | +#endif // QMQTT_NETWORK_P_H |
src/qmqtt_networkinterface.h
0 → 100644
| 1 | +++ a/src/qmqtt_networkinterface.h | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifndef QMQTT_NETWORK_INTERFACE_H | ||
| 23 | +#define QMQTT_NETWORK_INTERFACE_H | ||
| 24 | + | ||
| 25 | +#include "qmqtt_global.h" | ||
| 26 | + | ||
| 27 | +#include <QObject> | ||
| 28 | +#include <QAbstractSocket> | ||
| 29 | +#include <QHostAddress> | ||
| 30 | +#include <QString> | ||
| 31 | +#include <QList> | ||
| 32 | + | ||
| 33 | +#ifndef QT_NO_SSL | ||
| 34 | +#include <QSslConfiguration> | ||
| 35 | +QT_FORWARD_DECLARE_CLASS(QSslError) | ||
| 36 | +#endif // QT_NO_SSL | ||
| 37 | + | ||
| 38 | +namespace QMQTT { | ||
| 39 | + | ||
| 40 | +class Frame; | ||
| 41 | + | ||
| 42 | +class Q_MQTT_EXPORT NetworkInterface : public QObject | ||
| 43 | +{ | ||
| 44 | + Q_OBJECT | ||
| 45 | +public: | ||
| 46 | + explicit NetworkInterface(QObject* parent = NULL) : QObject(parent) {} | ||
| 47 | + virtual ~NetworkInterface() {} | ||
| 48 | + | ||
| 49 | + virtual void sendFrame(const Frame& frame) = 0; | ||
| 50 | + virtual bool isConnectedToHost() const = 0; | ||
| 51 | + virtual bool autoReconnect() const = 0; | ||
| 52 | + virtual void setAutoReconnect(const bool autoReconnect) = 0; | ||
| 53 | + virtual int autoReconnectInterval() const = 0; | ||
| 54 | + virtual void setAutoReconnectInterval(const int autoReconnectInterval) = 0; | ||
| 55 | + virtual QAbstractSocket::SocketState state() const = 0; | ||
| 56 | +#ifndef QT_NO_SSL | ||
| 57 | + virtual void ignoreSslErrors(const QList<QSslError>& errors) = 0; | ||
| 58 | + virtual QSslConfiguration sslConfiguration() const = 0; | ||
| 59 | + virtual void setSslConfiguration(const QSslConfiguration& config) = 0; | ||
| 60 | +#endif // QT_NO_SSL | ||
| 61 | + | ||
| 62 | +public slots: | ||
| 63 | + virtual void connectToHost(const QHostAddress& host, const quint16 port) = 0; | ||
| 64 | + virtual void connectToHost(const QString& hostName, const quint16 port) = 0; | ||
| 65 | + virtual void disconnectFromHost() = 0; | ||
| 66 | +#ifndef QT_NO_SSL | ||
| 67 | + virtual void ignoreSslErrors() = 0; | ||
| 68 | +#endif // QT_NO_SSL | ||
| 69 | + | ||
| 70 | +signals: | ||
| 71 | + void connected(); | ||
| 72 | + void disconnected(); | ||
| 73 | + void received(const QMQTT::Frame& frame); | ||
| 74 | + void error(QAbstractSocket::SocketError error); | ||
| 75 | +#ifndef QT_NO_SSL | ||
| 76 | + void sslErrors(const QList<QSslError>& errors); | ||
| 77 | +#endif // QT_NO_SSL | ||
| 78 | +}; | ||
| 79 | + | ||
| 80 | +} // namespace QMQTT | ||
| 81 | + | ||
| 82 | +#endif // QMQTT_NETWORK_INTERFACE_H |
src/qmqtt_pubsubclient.cpp
0 → 100644
| 1 | +++ a/src/qmqtt_pubsubclient.cpp | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +// osdev::components | ||
| 23 | +#include "qmqtt_pubsubclient.h" | ||
| 24 | +#include "log.h" | ||
| 25 | + | ||
| 26 | +// Qt | ||
| 27 | +#include <QRandomGenerator> | ||
| 28 | + | ||
| 29 | +using namespace osdev::components; | ||
| 30 | + | ||
| 31 | +QMqttPubSubClient::QMqttPubSubClient(const QHostAddress& host, | ||
| 32 | + const quint16 port, | ||
| 33 | + QObject *parent) | ||
| 34 | + : QMQTT::Client(host, port, parent) | ||
| 35 | + , m_mqtt_topic() | ||
| 36 | + , m_current_state(mqtt::E_CLIENT_UNKNOWN) | ||
| 37 | + , m_subTemp() | ||
| 38 | + , m_pubTemp() | ||
| 39 | +{ | ||
| 40 | + this->connectSignalsAndSlots(); | ||
| 41 | + | ||
| 42 | + this->connectToHost(); | ||
| 43 | +} | ||
| 44 | + | ||
| 45 | +QMqttPubSubClient::~QMqttPubSubClient() | ||
| 46 | +{ | ||
| 47 | + | ||
| 48 | +} | ||
| 49 | + | ||
| 50 | +void QMqttPubSubClient::subscribe(const QString& message_topic) | ||
| 51 | +{ | ||
| 52 | + if(m_current_state == mqtt::E_CLIENT_CONNECTED) | ||
| 53 | + { | ||
| 54 | + QMQTT::Client::subscribe(message_topic); | ||
| 55 | + } | ||
| 56 | + else | ||
| 57 | + { | ||
| 58 | + m_subTemp.first = message_topic; | ||
| 59 | + m_subTemp.second = QString(); | ||
| 60 | + } | ||
| 61 | +} | ||
| 62 | + | ||
| 63 | +void QMqttPubSubClient::unsubscribe(const QString& message_topic) | ||
| 64 | +{ | ||
| 65 | + if(m_current_state == mqtt::E_CLIENT_SUBSCRIBED) | ||
| 66 | + { | ||
| 67 | + QMQTT::Client::unsubscribe( message_topic ); | ||
| 68 | + } | ||
| 69 | +} | ||
| 70 | + | ||
| 71 | +void QMqttPubSubClient::publish(const QString& message_topic, const QString& message_payload) | ||
| 72 | +{ | ||
| 73 | + if(m_current_state == mqtt::E_CLIENT_CONNECTED || | ||
| 74 | + m_current_state == mqtt::E_CLIENT_SUBSCRIBED || | ||
| 75 | + m_current_state == mqtt::E_CLIENT_PUBLISHED) | ||
| 76 | + { | ||
| 77 | + QMQTT::Message oMessage( QRandomGenerator::global()->generate(), | ||
| 78 | + message_topic, | ||
| 79 | + QByteArray(message_payload.toStdString().c_str()), | ||
| 80 | + 0, true, false ); | ||
| 81 | + QMQTT::Client::publish(oMessage); | ||
| 82 | + } | ||
| 83 | + else | ||
| 84 | + { | ||
| 85 | + m_pubTemp.first = message_topic; | ||
| 86 | + m_pubTemp.second = message_payload; | ||
| 87 | + } | ||
| 88 | +} | ||
| 89 | + | ||
| 90 | +void QMqttPubSubClient::slotOnConnected() | ||
| 91 | +{ | ||
| 92 | + // Ok. We're connected at the moment. Lets set the state and see what we need to do. | ||
| 93 | + m_current_state = mqtt::E_CLIENT_CONNECTED; | ||
| 94 | + | ||
| 95 | + if(!m_subTemp.first.isEmpty()) | ||
| 96 | + { | ||
| 97 | + this->subscribe( m_subTemp.first ); | ||
| 98 | + } | ||
| 99 | + else if(!m_pubTemp.first.isEmpty()) | ||
| 100 | + { | ||
| 101 | + this->publish( m_pubTemp.first, m_pubTemp.second ); | ||
| 102 | + } | ||
| 103 | +} | ||
| 104 | + | ||
| 105 | +void QMqttPubSubClient::slotOnDisconnected() | ||
| 106 | +{ | ||
| 107 | + m_current_state = mqtt::E_CLIENT_DISCONNECTED; | ||
| 108 | +} | ||
| 109 | + | ||
| 110 | +void QMqttPubSubClient::slotOnError(const QMQTT::ClientError error) | ||
| 111 | +{ | ||
| 112 | + m_current_state = mqtt::E_CLIENT_ERROR; | ||
| 113 | + LogError( "[QMqttPubSubClient::slotOnError]", QString( "An error occured : %1" ).arg( error ) ); | ||
| 114 | + LogError( "[QMqttPubSubClient::slotOnError]", this->getErrorMessage( error ) ); | ||
| 115 | +} | ||
| 116 | + | ||
| 117 | +QString QMqttPubSubClient::getErrorMessage( const QMQTT::ClientError error ) | ||
| 118 | +{ | ||
| 119 | + | ||
| 120 | + QString l_error_message; | ||
| 121 | + | ||
| 122 | + switch( error ) | ||
| 123 | + { | ||
| 124 | + case QMQTT::SocketConnectionRefusedError: | ||
| 125 | + l_error_message = "[Socket] - Connection Refused"; | ||
| 126 | + break; | ||
| 127 | + case QMQTT::SocketRemoteHostClosedError: | ||
| 128 | + l_error_message = "[Socket] - Remote Host Closed"; | ||
| 129 | + emit signalReInitialise(); | ||
| 130 | + break; | ||
| 131 | + case QMQTT::SocketHostNotFoundError: | ||
| 132 | + l_error_message = "[Socket] - Host Not Found."; | ||
| 133 | + break; | ||
| 134 | + case QMQTT::SocketAccessError: | ||
| 135 | + l_error_message = "[Socket] - Access Error."; | ||
| 136 | + break; | ||
| 137 | + case QMQTT::SocketResourceError: | ||
| 138 | + l_error_message = "[Socket] - Resource Error."; | ||
| 139 | + break; | ||
| 140 | + case QMQTT::SocketTimeoutError: | ||
| 141 | + l_error_message = "[Socket] - Timeout."; | ||
| 142 | + break; | ||
| 143 | + case QMQTT::SocketDatagramTooLargeError: | ||
| 144 | + l_error_message = "[Socket] - Datagram Too Large."; | ||
| 145 | + break; | ||
| 146 | + case QMQTT::SocketNetworkError: | ||
| 147 | + l_error_message = "[Socket] - Network Error."; | ||
| 148 | + break; | ||
| 149 | + case QMQTT::SocketAddressInUseError: | ||
| 150 | + l_error_message = "[Socket] - Address In Use."; | ||
| 151 | + break; | ||
| 152 | + case QMQTT::SocketAddressNotAvailableError: | ||
| 153 | + l_error_message = "[Socket] - Address Not Available."; | ||
| 154 | + break; | ||
| 155 | + case QMQTT::SocketUnsupportedSocketOperationError: | ||
| 156 | + l_error_message = "[Socket] - Unsupported Socket Operation."; | ||
| 157 | + break; | ||
| 158 | + case QMQTT::SocketUnfinishedSocketOperationError: | ||
| 159 | + l_error_message = "[Socket] - Unfinished Socket Operation."; | ||
| 160 | + break; | ||
| 161 | + case QMQTT::SocketProxyAuthenticationRequiredError: | ||
| 162 | + l_error_message = "[Socket] - Proxy Authentication Required."; | ||
| 163 | + break; | ||
| 164 | + case QMQTT::SocketSslHandshakeFailedError: | ||
| 165 | + l_error_message = "[Socket] - SSL Handshake Failed."; | ||
| 166 | + break; | ||
| 167 | + case QMQTT::SocketProxyConnectionRefusedError: | ||
| 168 | + l_error_message = "[Socket] - Proxy Connection Refused."; | ||
| 169 | + break; | ||
| 170 | + case QMQTT::SocketProxyConnectionClosedError: | ||
| 171 | + l_error_message = "[Socket] - Proxy Connection Closed."; | ||
| 172 | + break; | ||
| 173 | + case QMQTT::SocketProxyConnectionTimeoutError: | ||
| 174 | + l_error_message = "[Socket] - Proxy Connection Closed."; | ||
| 175 | + break; | ||
| 176 | + case QMQTT::SocketProxyNotFoundError: | ||
| 177 | + l_error_message = "[Socket] - Proxy Not Found."; | ||
| 178 | + break; | ||
| 179 | + case QMQTT::SocketProxyProtocolError: | ||
| 180 | + l_error_message = "[Socket] - Proxy Protocol Error."; | ||
| 181 | + break; | ||
| 182 | + case QMQTT::SocketOperationError: | ||
| 183 | + l_error_message = "[Socket] - Operation Error."; | ||
| 184 | + break; | ||
| 185 | + case QMQTT::SocketSslInternalError: | ||
| 186 | + l_error_message = "[Socket] - SSL Internal Error."; | ||
| 187 | + break; | ||
| 188 | + case QMQTT::SocketSslInvalidUserDataError: | ||
| 189 | + l_error_message = "[Socket] - SSL Invalid User Data."; | ||
| 190 | + break; | ||
| 191 | + case QMQTT::SocketTemporaryError: | ||
| 192 | + l_error_message = "[Socket] - Temporary Error."; | ||
| 193 | + break; | ||
| 194 | + case QMQTT::MqttUnacceptableProtocolVersionError: | ||
| 195 | + l_error_message = "[MQTT] - Unacceptable Protocol Version."; | ||
| 196 | + break; | ||
| 197 | + case QMQTT::MqttIdentifierRejectedError: | ||
| 198 | + l_error_message = "[MQTT] - Identifier Rejected."; | ||
| 199 | + break; | ||
| 200 | + case QMQTT::MqttServerUnavailableError: | ||
| 201 | + l_error_message = "[MQTT] - Server Unavailable."; | ||
| 202 | + break; | ||
| 203 | + case QMQTT::MqttBadUserNameOrPasswordError: | ||
| 204 | + l_error_message = "[MQTT] - Bad Username Or Password."; | ||
| 205 | + break; | ||
| 206 | + case QMQTT::MqttNotAuthorizedError: | ||
| 207 | + l_error_message = "[MQTT] - Not Authorized."; | ||
| 208 | + break; | ||
| 209 | + case QMQTT::MqttNoPingResponse: | ||
| 210 | + l_error_message = "[MQTT] - No Ping Response"; | ||
| 211 | + break; | ||
| 212 | + case QMQTT::UnknownError: | ||
| 213 | + default: | ||
| 214 | + l_error_message = "An Unknown Error Occurred"; | ||
| 215 | + break; | ||
| 216 | + } | ||
| 217 | + | ||
| 218 | + return l_error_message; | ||
| 219 | +} | ||
| 220 | + | ||
| 221 | +void QMqttPubSubClient::slotOnSubscribed(const QString& topic, const quint8 qos) | ||
| 222 | +{ | ||
| 223 | + Q_UNUSED(qos); | ||
| 224 | + m_current_state = mqtt::E_CLIENT_SUBSCRIBED; | ||
| 225 | + LogInfo("[QMqttPubSubClient::slotOnSubscribed]", QString("Subscribed to topic %1").arg(topic)); | ||
| 226 | +} | ||
| 227 | + | ||
| 228 | +void QMqttPubSubClient::slotOnUnSubscribed(const QString& topic) | ||
| 229 | +{ | ||
| 230 | + m_current_state = mqtt::E_CLIENT_UNSUBSCRIBED; | ||
| 231 | + LogInfo("[QMqttPubSubClient::slotOnUnSubscribed]", QString("Unsubscribed to topic %1").arg(topic)); | ||
| 232 | +} | ||
| 233 | + | ||
| 234 | +void QMqttPubSubClient::slotOnPublished(const QMQTT::Message& message, quint16 msgid) | ||
| 235 | +{ | ||
| 236 | + | ||
| 237 | + m_current_state = mqtt::E_CLIENT_PUBLISHED; | ||
| 238 | + LogInfo("[QMqttPubSubClient::slotOnPublished]", QString("Message %1 published to topic %2 with id %3").arg(message.topic()).arg(message.payload().toStdString().c_str()).arg(msgid)); | ||
| 239 | +} | ||
| 240 | + | ||
| 241 | +void QMqttPubSubClient::slotOnReceived(const QMQTT::Message& message) | ||
| 242 | +{ | ||
| 243 | + LogDebug("[QMqttPubSubClient::slotOnReceived]", QString("Received payload : %1 from topic : %2").arg(message.payload().toStdString().c_str()).arg(message.topic())); | ||
| 244 | + emit signalMessageReceived(message.topic(), message.payload().toStdString().c_str()); | ||
| 245 | +} | ||
| 246 | + | ||
| 247 | +void QMqttPubSubClient::slotOnPingResp() | ||
| 248 | +{ | ||
| 249 | + LogDebug("[QMqttPubSubClient::slotOnPingResp]", QString("Ping Response received.")); | ||
| 250 | +} | ||
| 251 | + | ||
| 252 | +#ifndef QT_NO_SSL | ||
| 253 | +void QMqttPubSubClient::slotSslErrors(const QList<QSslError>& errors) | ||
| 254 | +{ | ||
| 255 | + Q_UNUSED(errors); | ||
| 256 | +} | ||
| 257 | +#endif /* QT_NO_SSL */ | ||
| 258 | + | ||
| 259 | +void QMqttPubSubClient::connectSignalsAndSlots() | ||
| 260 | +{ | ||
| 261 | + connect(this, &QMQTT::Client::connected, this, &QMqttPubSubClient::slotOnConnected); | ||
| 262 | + connect(this, &QMQTT::Client::disconnected, this, &QMqttPubSubClient::slotOnDisconnected); | ||
| 263 | + connect(this, &QMQTT::Client::error, this, &QMqttPubSubClient::slotOnError); | ||
| 264 | + connect(this, &QMQTT::Client::subscribed, this, &QMqttPubSubClient::slotOnSubscribed); | ||
| 265 | + connect(this, &QMQTT::Client::unsubscribed, this, &QMqttPubSubClient::slotOnUnSubscribed); | ||
| 266 | + connect(this, &QMQTT::Client::published, this, &QMqttPubSubClient::slotOnPublished); | ||
| 267 | + connect(this, &QMQTT::Client::received, this, &QMqttPubSubClient::slotOnReceived); | ||
| 268 | + connect(this, &QMQTT::Client::pingresp, this, &QMqttPubSubClient::slotOnPingResp); | ||
| 269 | +#ifndef QT_NO_SSL | ||
| 270 | + connect(this, &QMQTT::Client::sslErrors, this, &QMqttPubSubClient::slotSslErrors); | ||
| 271 | +#endif /* QT_NO_SSL */ | ||
| 272 | +} |
src/qmqtt_pubsubclient.h
0 → 100644
| 1 | +++ a/src/qmqtt_pubsubclient.h | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifndef OSDEV_COMPONENTS_PUBSUBCLIENT_H | ||
| 23 | +#define OSDEV_COMPONENTS_PUBSUBCLIENT_H | ||
| 24 | + | ||
| 25 | +// Qt | ||
| 26 | +#include <QObject> | ||
| 27 | +#include <QPair> | ||
| 28 | +#include <QString> | ||
| 29 | + | ||
| 30 | +// osdev::components | ||
| 31 | +#include "qmqtt_client.h" | ||
| 32 | +#include "qmqtt_states.h" | ||
| 33 | +#include "qmqtt_message.h" | ||
| 34 | +#include "qmqtt_configsettings.h" | ||
| 35 | + | ||
| 36 | +namespace osdev { | ||
| 37 | +namespace components { | ||
| 38 | + | ||
| 39 | +class QMqttPubSubClient : public QMQTT::Client | ||
| 40 | +{ | ||
| 41 | + Q_OBJECT | ||
| 42 | + | ||
| 43 | +public: | ||
| 44 | + explicit QMqttPubSubClient(const QHostAddress& host = QHostAddress::LocalHost, | ||
| 45 | + const quint16 port = 1883, | ||
| 46 | + QObject *parent = nullptr); | ||
| 47 | + | ||
| 48 | + virtual ~QMqttPubSubClient(); | ||
| 49 | + | ||
| 50 | + void subscribe(const QString& message_topic); | ||
| 51 | + void unsubscribe(const QString& message_topic); | ||
| 52 | + void publish(const QString& message_topic, const QString& message_payload); | ||
| 53 | + | ||
| 54 | + QString getErrorMessage( const QMQTT::ClientError error ); | ||
| 55 | + | ||
| 56 | +signals: | ||
| 57 | + void signalMessageReceived(const QString& message_topic, const QString& message_payload); | ||
| 58 | + void signalReInitialise(); | ||
| 59 | + | ||
| 60 | +private slots: | ||
| 61 | + // All status Slots | ||
| 62 | + void slotOnConnected(); | ||
| 63 | + void slotOnDisconnected(); | ||
| 64 | + void slotOnError(const QMQTT::ClientError error); | ||
| 65 | + void slotOnSubscribed(const QString& topic, const quint8 qos); | ||
| 66 | + void slotOnUnSubscribed(const QString& topic); | ||
| 67 | + void slotOnPublished(const QMQTT::Message& message, quint16 msgid); | ||
| 68 | + void slotOnReceived(const QMQTT::Message& message); | ||
| 69 | + void slotOnPingResp(); | ||
| 70 | +#ifndef QT_NO_SSL | ||
| 71 | + void slotSslErrors(const QList<QSslError>& errors); | ||
| 72 | +#endif /* QT_NO_SSL */ | ||
| 73 | + | ||
| 74 | +private: | ||
| 75 | + void connectSignalsAndSlots(); | ||
| 76 | + | ||
| 77 | +private: | ||
| 78 | + QString m_mqtt_topic; | ||
| 79 | + mqtt::E_CLIENT_STATE m_current_state; | ||
| 80 | + QPair<QString, QString> m_subTemp; | ||
| 81 | + QPair<QString, QString> m_pubTemp; | ||
| 82 | + | ||
| 83 | +}; | ||
| 84 | + | ||
| 85 | +} /* End namespace components */ | ||
| 86 | +} /* End namespace osdev */ | ||
| 87 | + | ||
| 88 | +#endif /* OSDEV_COMPONENTS_PUBSUBCLIENT_H */ |
src/qmqtt_routedmessage.h
0 → 100644
| 1 | +++ a/src/qmqtt_routedmessage.h | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifndef QMQTT_ROUTEDMESSAGE_H | ||
| 23 | +#define QMQTT_ROUTEDMESSAGE_H | ||
| 24 | + | ||
| 25 | +#include "qmqtt_message.h" | ||
| 26 | + | ||
| 27 | +#include <QMetaType> | ||
| 28 | +#include <QHash> | ||
| 29 | +#include <QString> | ||
| 30 | + | ||
| 31 | +namespace QMQTT { | ||
| 32 | + | ||
| 33 | +class RouteSubscription; | ||
| 34 | + | ||
| 35 | +class Q_MQTT_EXPORT RoutedMessage | ||
| 36 | +{ | ||
| 37 | +public: | ||
| 38 | + inline RoutedMessage() | ||
| 39 | + {} | ||
| 40 | + inline RoutedMessage(const Message &message) | ||
| 41 | + : _message(message) | ||
| 42 | + {} | ||
| 43 | + | ||
| 44 | + inline const Message &message() const | ||
| 45 | + { return _message; } | ||
| 46 | + inline QHash<QString, QString> parameters() const | ||
| 47 | + { return _parameters; } | ||
| 48 | + | ||
| 49 | +private: | ||
| 50 | + friend class RouteSubscription; | ||
| 51 | + | ||
| 52 | + Message _message; | ||
| 53 | + QHash<QString, QString> _parameters; | ||
| 54 | +}; | ||
| 55 | + | ||
| 56 | +} // namespace QMQTT | ||
| 57 | + | ||
| 58 | +Q_DECLARE_METATYPE(QMQTT::RoutedMessage) | ||
| 59 | + | ||
| 60 | +#endif // QMQTT_ROUTEDMESSAGE_H |
src/qmqtt_router.cpp
0 → 100644
| 1 | +++ a/src/qmqtt_router.cpp | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#include "qmqtt_router.h" | ||
| 23 | +#include "qmqtt_client.h" | ||
| 24 | +#include "qmqtt_routesubscription.h" | ||
| 25 | + | ||
| 26 | +#include <QLoggingCategory> | ||
| 27 | + | ||
| 28 | +namespace QMQTT { | ||
| 29 | + | ||
| 30 | +Q_LOGGING_CATEGORY(router, "qmqtt.router") | ||
| 31 | + | ||
| 32 | +Router::Router(Client *parent) : QObject(parent), _client(parent) | ||
| 33 | +{ | ||
| 34 | +} | ||
| 35 | + | ||
| 36 | +RouteSubscription *Router::subscribe(const QString &route) | ||
| 37 | +{ | ||
| 38 | + RouteSubscription *subscription = new RouteSubscription(this); | ||
| 39 | + subscription->setRoute(route); | ||
| 40 | + connect(_client, &Client::connected, subscription, [this, subscription]() { | ||
| 41 | + _client->subscribe(subscription->_topic, 0); | ||
| 42 | + }); | ||
| 43 | + if (_client->isConnectedToHost()) | ||
| 44 | + _client->subscribe(subscription->_topic, 0); | ||
| 45 | + connect(_client, &Client::received, subscription, &RouteSubscription::routeMessage); | ||
| 46 | + return subscription; | ||
| 47 | +} | ||
| 48 | + | ||
| 49 | +Client *Router::client() const | ||
| 50 | +{ | ||
| 51 | + return _client; | ||
| 52 | +} | ||
| 53 | + | ||
| 54 | +} // namespace QMQTT | ||
| 55 | + |
src/qmqtt_router.h
0 → 100644
| 1 | +++ a/src/qmqtt_router.h | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifndef QMQTT_ROUTER_H | ||
| 23 | +#define QMQTT_ROUTER_H | ||
| 24 | + | ||
| 25 | +#include "qmqtt_global.h" | ||
| 26 | + | ||
| 27 | +#include <QObject> | ||
| 28 | + | ||
| 29 | +namespace QMQTT { | ||
| 30 | + | ||
| 31 | +class Client; | ||
| 32 | +class RouteSubscription; | ||
| 33 | + | ||
| 34 | +class Q_MQTT_EXPORT Router : public QObject | ||
| 35 | +{ | ||
| 36 | + Q_OBJECT | ||
| 37 | +public: | ||
| 38 | + explicit Router(Client *parent = 0); | ||
| 39 | + | ||
| 40 | + RouteSubscription *subscribe(const QString &route); | ||
| 41 | + Client *client() const; | ||
| 42 | + | ||
| 43 | +private: | ||
| 44 | + Client *_client; | ||
| 45 | +}; | ||
| 46 | + | ||
| 47 | +} // namespace QMQTT | ||
| 48 | + | ||
| 49 | +#endif // QMQTT_ROUTER_H |
src/qmqtt_routesubscription.cpp
0 → 100644
| 1 | +++ a/src/qmqtt_routesubscription.cpp | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#include "qmqtt_routesubscription.h" | ||
| 23 | +#include "qmqtt_router.h" | ||
| 24 | +#include "qmqtt_client.h" | ||
| 25 | +#include "qmqtt_routedmessage.h" | ||
| 26 | + | ||
| 27 | +#include <QLoggingCategory> | ||
| 28 | +#include <QLatin1String> | ||
| 29 | +#include <QLatin1Char> | ||
| 30 | +#include <QRegularExpressionMatch> | ||
| 31 | +#include <QStringList> | ||
| 32 | + | ||
| 33 | +namespace QMQTT { | ||
| 34 | + | ||
| 35 | +Q_LOGGING_CATEGORY(routerSubscription, "qmqtt.routersubscription") | ||
| 36 | + | ||
| 37 | +RouteSubscription::RouteSubscription(Router *parent) | ||
| 38 | + : QObject(parent), | ||
| 39 | + _client(parent->client()) | ||
| 40 | +{ | ||
| 41 | + Q_ASSERT(!_client.isNull()); | ||
| 42 | +} | ||
| 43 | + | ||
| 44 | +RouteSubscription::~RouteSubscription() | ||
| 45 | +{ | ||
| 46 | + if (Q_LIKELY(!_client.isNull() && _client->isConnectedToHost())) | ||
| 47 | + _client->unsubscribe(_topic); | ||
| 48 | +} | ||
| 49 | + | ||
| 50 | +QString RouteSubscription::route() const | ||
| 51 | +{ | ||
| 52 | + return _topic; | ||
| 53 | +} | ||
| 54 | + | ||
| 55 | +void RouteSubscription::setRoute(const QString &route) | ||
| 56 | +{ | ||
| 57 | + QRegularExpression parameterNamesRegExp(QStringLiteral("\\:([a-zA-Z0-9]+)")); // note how names must not contain dashes or underscores | ||
| 58 | + | ||
| 59 | + // Remove paramter names to get the actual topic "route" | ||
| 60 | + QString topic = route; | ||
| 61 | + topic.remove(parameterNamesRegExp); | ||
| 62 | + | ||
| 63 | + // Remove the MQTT wildcards to get a regular expression, which matches the parameters | ||
| 64 | + QString parameterRegExp = route; | ||
| 65 | + parameterRegExp | ||
| 66 | + .remove(QLatin1Char('+')) | ||
| 67 | + .replace(parameterNamesRegExp, QStringLiteral("([a-zA-Z0-9_-]+)")) // note how parameter values may contain dashes or underscores | ||
| 68 | + .remove(QLatin1Char('#')) | ||
| 69 | + .replace(QLatin1String("$"), QLatin1String("\\$")); | ||
| 70 | + | ||
| 71 | + // Extract the parameter names | ||
| 72 | + QRegularExpressionMatchIterator it = parameterNamesRegExp.globalMatch(route); | ||
| 73 | + QStringList names; | ||
| 74 | + while(it.hasNext()) { | ||
| 75 | + QRegularExpressionMatch match = it.next(); | ||
| 76 | + QString parameterName = match.captured(1); | ||
| 77 | + names << parameterName; | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + _topic = topic; | ||
| 81 | + _parameterNames = names; | ||
| 82 | + _regularExpression = QRegularExpression(parameterRegExp); | ||
| 83 | +} | ||
| 84 | + | ||
| 85 | +void RouteSubscription::routeMessage(const Message &message) | ||
| 86 | +{ | ||
| 87 | + QString topic = message.topic(); | ||
| 88 | + QRegularExpressionMatch match = _regularExpression.match(topic); | ||
| 89 | + if(!match.hasMatch()) { | ||
| 90 | + return; | ||
| 91 | + } | ||
| 92 | + | ||
| 93 | + RoutedMessage routedMessage(message); | ||
| 94 | + | ||
| 95 | + for(int i = 0, c = _parameterNames.size(); i < c; ++i) { | ||
| 96 | + QString name = _parameterNames.at(i); | ||
| 97 | + QString value = match.captured(i + 1); | ||
| 98 | + | ||
| 99 | + routedMessage._parameters.insert(name, value); | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + emit received(routedMessage); | ||
| 103 | +} | ||
| 104 | + | ||
| 105 | +} // namespace QMQTT |
src/qmqtt_routesubscription.h
0 → 100644
| 1 | +++ a/src/qmqtt_routesubscription.h | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifndef QMQTT_ROUTESUBSCRIPTION_H | ||
| 23 | +#define QMQTT_ROUTESUBSCRIPTION_H | ||
| 24 | + | ||
| 25 | +#include "qmqtt_global.h" | ||
| 26 | + | ||
| 27 | +#include <QObject> | ||
| 28 | +#include <QPointer> | ||
| 29 | +#include <QString> | ||
| 30 | +#include <QRegularExpression> | ||
| 31 | +#include <QStringList> | ||
| 32 | + | ||
| 33 | +namespace QMQTT { | ||
| 34 | + | ||
| 35 | +class Client; | ||
| 36 | +class Message; | ||
| 37 | +class RoutedMessage; | ||
| 38 | +class Router; | ||
| 39 | + | ||
| 40 | +class Q_MQTT_EXPORT RouteSubscription : public QObject | ||
| 41 | +{ | ||
| 42 | + Q_OBJECT | ||
| 43 | +public: | ||
| 44 | + ~RouteSubscription(); | ||
| 45 | + | ||
| 46 | + QString route() const; | ||
| 47 | + | ||
| 48 | +signals: | ||
| 49 | + void received(const RoutedMessage &message); | ||
| 50 | + | ||
| 51 | +private slots: | ||
| 52 | + void routeMessage(const Message &message); | ||
| 53 | + | ||
| 54 | +private: | ||
| 55 | + friend class Router; | ||
| 56 | + | ||
| 57 | + explicit RouteSubscription(Router *parent = 0); | ||
| 58 | + void setRoute(const QString &route); | ||
| 59 | + | ||
| 60 | + QPointer<Client> _client; | ||
| 61 | + QString _topic; | ||
| 62 | + QRegularExpression _regularExpression; | ||
| 63 | + QStringList _parameterNames; | ||
| 64 | +}; | ||
| 65 | + | ||
| 66 | +} // namespace QMQTT | ||
| 67 | + | ||
| 68 | +#endif // QMQTT_ROUTESUBSCRIPTION_H |
src/qmqtt_socket.cpp
0 → 100644
| 1 | +++ a/src/qmqtt_socket.cpp | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#include "qmqtt_socket_p.h" | ||
| 23 | + | ||
| 24 | +#include <QTcpSocket> | ||
| 25 | + | ||
| 26 | +QMQTT::Socket::Socket(QObject* parent) | ||
| 27 | + : SocketInterface(parent) | ||
| 28 | + , _socket(new QTcpSocket(this)) | ||
| 29 | +{ | ||
| 30 | + connect(_socket.data(), &QTcpSocket::connected, this, &SocketInterface::connected); | ||
| 31 | + connect(_socket.data(), &QTcpSocket::disconnected, this, &SocketInterface::disconnected); | ||
| 32 | + connect(_socket.data(), | ||
| 33 | +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) | ||
| 34 | + static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)>(&QTcpSocket::errorOccurred), | ||
| 35 | +#else | ||
| 36 | + static_cast<void (QTcpSocket::*)(QAbstractSocket::SocketError)>(&QTcpSocket::error), | ||
| 37 | +#endif | ||
| 38 | + this, | ||
| 39 | + static_cast<void (SocketInterface::*)(QAbstractSocket::SocketError)>(&SocketInterface::error)); | ||
| 40 | +} | ||
| 41 | + | ||
| 42 | +QMQTT::Socket::~Socket() | ||
| 43 | +{ | ||
| 44 | +} | ||
| 45 | + | ||
| 46 | +QIODevice *QMQTT::Socket::ioDevice() | ||
| 47 | +{ | ||
| 48 | + return _socket.data(); | ||
| 49 | +} | ||
| 50 | + | ||
| 51 | +void QMQTT::Socket::connectToHost(const QHostAddress& address, quint16 port) | ||
| 52 | +{ | ||
| 53 | + _socket->connectToHost(address, port); | ||
| 54 | +} | ||
| 55 | + | ||
| 56 | +void QMQTT::Socket::connectToHost(const QString& hostName, quint16 port) | ||
| 57 | +{ | ||
| 58 | + _socket->connectToHost(hostName, port); | ||
| 59 | +} | ||
| 60 | + | ||
| 61 | +void QMQTT::Socket::disconnectFromHost() | ||
| 62 | +{ | ||
| 63 | + _socket->disconnectFromHost(); | ||
| 64 | +} | ||
| 65 | + | ||
| 66 | +QAbstractSocket::SocketState QMQTT::Socket::state() const | ||
| 67 | +{ | ||
| 68 | + return _socket->state(); | ||
| 69 | +} | ||
| 70 | + | ||
| 71 | +QAbstractSocket::SocketError QMQTT::Socket::error() const | ||
| 72 | +{ | ||
| 73 | + return _socket->error(); | ||
| 74 | +} |
src/qmqtt_socket_p.h
0 → 100644
| 1 | +++ a/src/qmqtt_socket_p.h | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifndef QMQTT_SOCKET_P_H | ||
| 23 | +#define QMQTT_SOCKET_P_H | ||
| 24 | + | ||
| 25 | +#include "qmqtt_socketinterface.h" | ||
| 26 | + | ||
| 27 | +#include <QObject> | ||
| 28 | +#include <QHostAddress> | ||
| 29 | +#include <QString> | ||
| 30 | +#include <QAbstractSocket> | ||
| 31 | +#include <QScopedPointer> | ||
| 32 | + | ||
| 33 | +QT_FORWARD_DECLARE_CLASS(QIODevice) | ||
| 34 | +QT_FORWARD_DECLARE_CLASS(QTcpSocket) | ||
| 35 | + | ||
| 36 | +namespace QMQTT | ||
| 37 | +{ | ||
| 38 | + | ||
| 39 | +class Socket : public SocketInterface | ||
| 40 | +{ | ||
| 41 | + Q_OBJECT | ||
| 42 | +public: | ||
| 43 | + explicit Socket(QObject* parent = NULL); | ||
| 44 | + virtual ~Socket(); | ||
| 45 | + | ||
| 46 | + virtual QIODevice *ioDevice(); | ||
| 47 | + void connectToHost(const QHostAddress& address, quint16 port); | ||
| 48 | + void connectToHost(const QString& hostName, quint16 port); | ||
| 49 | + void disconnectFromHost(); | ||
| 50 | + QAbstractSocket::SocketState state() const; | ||
| 51 | + QAbstractSocket::SocketError error() const; | ||
| 52 | + | ||
| 53 | +protected: | ||
| 54 | + QScopedPointer<QTcpSocket> _socket; | ||
| 55 | +}; | ||
| 56 | + | ||
| 57 | +} | ||
| 58 | + | ||
| 59 | +#endif // QMQTT_SOCKET_P_H |
src/qmqtt_socketinterface.h
0 → 100644
| 1 | +++ a/src/qmqtt_socketinterface.h | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifndef QMQTT_SOCKET_INTERFACE_H | ||
| 23 | +#define QMQTT_SOCKET_INTERFACE_H | ||
| 24 | + | ||
| 25 | +#include "qmqtt_global.h" | ||
| 26 | + | ||
| 27 | +#include <QObject> | ||
| 28 | +#include <QHostAddress> | ||
| 29 | +#include <QString> | ||
| 30 | +#include <QAbstractSocket> | ||
| 31 | +#include <QList> | ||
| 32 | + | ||
| 33 | +#ifndef QT_NO_SSL | ||
| 34 | +#include <QSslConfiguration> | ||
| 35 | +QT_FORWARD_DECLARE_CLASS(QSslError) | ||
| 36 | +#endif // QT_NO_SSL | ||
| 37 | + | ||
| 38 | +QT_FORWARD_DECLARE_CLASS(QIODevice) | ||
| 39 | + | ||
| 40 | +namespace QMQTT | ||
| 41 | +{ | ||
| 42 | + | ||
| 43 | +class Q_MQTT_EXPORT SocketInterface : public QObject | ||
| 44 | +{ | ||
| 45 | + Q_OBJECT | ||
| 46 | +public: | ||
| 47 | + explicit SocketInterface(QObject* parent = NULL) : QObject(parent) {} | ||
| 48 | + virtual ~SocketInterface() {} | ||
| 49 | + | ||
| 50 | + virtual QIODevice* ioDevice() = 0; | ||
| 51 | + virtual void connectToHost(const QHostAddress& address, quint16 port) = 0; | ||
| 52 | + virtual void connectToHost(const QString& hostName, quint16 port) = 0; | ||
| 53 | + virtual void disconnectFromHost() = 0; | ||
| 54 | + virtual QAbstractSocket::SocketState state() const = 0; | ||
| 55 | + virtual QAbstractSocket::SocketError error() const = 0; | ||
| 56 | +#ifndef QT_NO_SSL | ||
| 57 | + virtual void ignoreSslErrors(const QList<QSslError>& errors) { Q_UNUSED(errors); } | ||
| 58 | + virtual void ignoreSslErrors() {} | ||
| 59 | + virtual QSslConfiguration sslConfiguration() const { return QSslConfiguration(); } | ||
| 60 | + virtual void setSslConfiguration(const QSslConfiguration& config) { Q_UNUSED(config); } | ||
| 61 | +#endif // QT_NO_SSL | ||
| 62 | + | ||
| 63 | +signals: | ||
| 64 | + void connected(); | ||
| 65 | + void disconnected(); | ||
| 66 | + void error(QAbstractSocket::SocketError socketError); | ||
| 67 | +#ifndef QT_NO_SSL | ||
| 68 | + void sslErrors(const QList<QSslError>& errors); | ||
| 69 | +#endif // QT_NO_SSL | ||
| 70 | +}; | ||
| 71 | + | ||
| 72 | +} | ||
| 73 | + | ||
| 74 | +#endif // QMQTT_SOCKET_INTERFACE_H |
src/qmqtt_ssl_socket.cpp
0 → 100644
| 1 | +++ a/src/qmqtt_ssl_socket.cpp | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#include "qmqtt_ssl_socket_p.h" | ||
| 23 | + | ||
| 24 | +#ifndef QT_NO_SSL | ||
| 25 | + | ||
| 26 | +#include <QSslSocket> | ||
| 27 | +#include <QSslError> | ||
| 28 | + | ||
| 29 | +QMQTT::SslSocket::SslSocket(const QSslConfiguration& config, QObject* parent) | ||
| 30 | + : SocketInterface(parent) | ||
| 31 | + , _socket(new QSslSocket(this)) | ||
| 32 | +{ | ||
| 33 | + _socket->setSslConfiguration(config); | ||
| 34 | + connect(_socket.data(), &QSslSocket::encrypted, this, &SocketInterface::connected); | ||
| 35 | + connect(_socket.data(), &QSslSocket::disconnected, this, &SocketInterface::disconnected); | ||
| 36 | + connect(_socket.data(), | ||
| 37 | +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) | ||
| 38 | + static_cast<void (QSslSocket::*)(QAbstractSocket::SocketError)>(&QSslSocket::errorOccurred), | ||
| 39 | +#else | ||
| 40 | + static_cast<void (QSslSocket::*)(QAbstractSocket::SocketError)>(&QSslSocket::error), | ||
| 41 | +#endif | ||
| 42 | + this, | ||
| 43 | + static_cast<void (SocketInterface::*)(QAbstractSocket::SocketError)>(&SocketInterface::error)); | ||
| 44 | + connect(_socket.data(), | ||
| 45 | + static_cast<void (QSslSocket::*)(const QList<QSslError>&)>(&QSslSocket::sslErrors), | ||
| 46 | + this, | ||
| 47 | + &SslSocket::sslErrors); | ||
| 48 | +} | ||
| 49 | + | ||
| 50 | +QMQTT::SslSocket::~SslSocket() | ||
| 51 | +{ | ||
| 52 | +} | ||
| 53 | + | ||
| 54 | +QIODevice *QMQTT::SslSocket::ioDevice() | ||
| 55 | +{ | ||
| 56 | + return _socket.data(); | ||
| 57 | +} | ||
| 58 | + | ||
| 59 | +void QMQTT::SslSocket::connectToHost(const QHostAddress& address, quint16 port) | ||
| 60 | +{ | ||
| 61 | + _socket->connectToHostEncrypted(address.toString(), port); | ||
| 62 | +} | ||
| 63 | + | ||
| 64 | +void QMQTT::SslSocket::connectToHost(const QString& hostName, quint16 port) | ||
| 65 | +{ | ||
| 66 | + _socket->connectToHostEncrypted(hostName, port); | ||
| 67 | +} | ||
| 68 | + | ||
| 69 | +void QMQTT::SslSocket::disconnectFromHost() | ||
| 70 | +{ | ||
| 71 | + _socket->disconnectFromHost(); | ||
| 72 | +} | ||
| 73 | + | ||
| 74 | +QAbstractSocket::SocketState QMQTT::SslSocket::state() const | ||
| 75 | +{ | ||
| 76 | + return _socket->state(); | ||
| 77 | +} | ||
| 78 | + | ||
| 79 | +QAbstractSocket::SocketError QMQTT::SslSocket::error() const | ||
| 80 | +{ | ||
| 81 | + return _socket->error(); | ||
| 82 | +} | ||
| 83 | + | ||
| 84 | +void QMQTT::SslSocket::ignoreSslErrors(const QList<QSslError>& errors) | ||
| 85 | +{ | ||
| 86 | + _socket->ignoreSslErrors(errors); | ||
| 87 | +} | ||
| 88 | + | ||
| 89 | +void QMQTT::SslSocket::ignoreSslErrors() | ||
| 90 | +{ | ||
| 91 | + _socket->ignoreSslErrors(); | ||
| 92 | +} | ||
| 93 | + | ||
| 94 | +QSslConfiguration QMQTT::SslSocket::sslConfiguration() const | ||
| 95 | +{ | ||
| 96 | + return _socket->sslConfiguration(); | ||
| 97 | +} | ||
| 98 | + | ||
| 99 | +void QMQTT::SslSocket::setSslConfiguration(const QSslConfiguration& config) | ||
| 100 | +{ | ||
| 101 | + _socket->setSslConfiguration(config); | ||
| 102 | +} | ||
| 103 | + | ||
| 104 | +#endif // QT_NO_SSL |
src/qmqtt_ssl_socket_p.h
0 → 100644
| 1 | +++ a/src/qmqtt_ssl_socket_p.h | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifndef QMQTT_SSL_SOCKET_P_H | ||
| 23 | +#define QMQTT_SSL_SOCKET_P_H | ||
| 24 | + | ||
| 25 | +#ifndef QT_NO_SSL | ||
| 26 | + | ||
| 27 | +#include "qmqtt_socketinterface.h" | ||
| 28 | + | ||
| 29 | +#include <QObject> | ||
| 30 | +#include <QHostAddress> | ||
| 31 | +#include <QString> | ||
| 32 | +#include <QList> | ||
| 33 | +#include <QScopedPointer> | ||
| 34 | + | ||
| 35 | +QT_FORWARD_DECLARE_CLASS(QSslSocket) | ||
| 36 | +QT_FORWARD_DECLARE_CLASS(QSslError) | ||
| 37 | +#include <QSslConfiguration> | ||
| 38 | + | ||
| 39 | +namespace QMQTT | ||
| 40 | +{ | ||
| 41 | + | ||
| 42 | +class SslSocket : public SocketInterface | ||
| 43 | +{ | ||
| 44 | + Q_OBJECT | ||
| 45 | +public: | ||
| 46 | + explicit SslSocket(const QSslConfiguration& config, QObject* parent = NULL); | ||
| 47 | + virtual ~SslSocket(); | ||
| 48 | + | ||
| 49 | + virtual QIODevice *ioDevice(); | ||
| 50 | + void connectToHost(const QHostAddress& address, quint16 port); | ||
| 51 | + void connectToHost(const QString& hostName, quint16 port); | ||
| 52 | + void disconnectFromHost(); | ||
| 53 | + QAbstractSocket::SocketState state() const; | ||
| 54 | + QAbstractSocket::SocketError error() const; | ||
| 55 | + void ignoreSslErrors(const QList<QSslError>& errors); | ||
| 56 | + void ignoreSslErrors(); | ||
| 57 | + QSslConfiguration sslConfiguration() const; | ||
| 58 | + void setSslConfiguration(const QSslConfiguration& config); | ||
| 59 | + | ||
| 60 | +protected: | ||
| 61 | + QScopedPointer<QSslSocket> _socket; | ||
| 62 | +}; | ||
| 63 | + | ||
| 64 | +} | ||
| 65 | + | ||
| 66 | +#endif // QT_NO_SSL | ||
| 67 | + | ||
| 68 | +#endif // QMQTT_SSL_SOCKET_P_H |
src/qmqtt_states.h
0 → 100644
| 1 | +++ a/src/qmqtt_states.h | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifndef OSDEV_COMPONENTS_MQTT_STATES_H | ||
| 23 | +#define OSDEV_COMPONENTS_MQTT_STATES_H | ||
| 24 | + | ||
| 25 | +namespace osdev { | ||
| 26 | +namespace components { | ||
| 27 | +namespace mqtt { | ||
| 28 | +enum E_CLIENT_STATE | ||
| 29 | +{ | ||
| 30 | + E_CLIENT_UNKNOWN = 0, | ||
| 31 | + E_CLIENT_CONNECTED, | ||
| 32 | + E_CLIENT_DISCONNECTED, | ||
| 33 | + E_CLIENT_ERROR, | ||
| 34 | + E_CLIENT_SUBSCRIBED, | ||
| 35 | + E_CLIENT_UNSUBSCRIBED, | ||
| 36 | + E_CLIENT_PUBLISHED, | ||
| 37 | + E_CLIENT_SSL_ERRORS | ||
| 38 | +}; | ||
| 39 | + | ||
| 40 | +} /* End namespace mqtt */ | ||
| 41 | +} /* End namespace components */ | ||
| 42 | +} /* End namespace osdev */ | ||
| 43 | + | ||
| 44 | +#endif /* OSDEV_COMPONENTS_MQTT_STATES_H */ |
src/qmqtt_timer.cpp
0 → 100644
| 1 | +++ a/src/qmqtt_timer.cpp | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#include "qmqtt_timer_p.h" | ||
| 23 | + | ||
| 24 | +QMQTT::Timer::Timer(QObject* parent) | ||
| 25 | + : TimerInterface(parent) | ||
| 26 | +{ | ||
| 27 | + connect(&_timer, &QTimer::timeout, this, &TimerInterface::timeout); | ||
| 28 | +} | ||
| 29 | + | ||
| 30 | +QMQTT::Timer::~Timer() | ||
| 31 | +{ | ||
| 32 | +} | ||
| 33 | + | ||
| 34 | +bool QMQTT::Timer::isSingleShot() const | ||
| 35 | +{ | ||
| 36 | + return _timer.isSingleShot(); | ||
| 37 | +} | ||
| 38 | + | ||
| 39 | +void QMQTT::Timer::setSingleShot(bool singleShot) | ||
| 40 | +{ | ||
| 41 | + _timer.setSingleShot(singleShot); | ||
| 42 | +} | ||
| 43 | + | ||
| 44 | +int QMQTT::Timer::interval() const | ||
| 45 | +{ | ||
| 46 | + return _timer.interval(); | ||
| 47 | +} | ||
| 48 | + | ||
| 49 | +void QMQTT::Timer::setInterval(int msec) | ||
| 50 | +{ | ||
| 51 | + _timer.setInterval(msec); | ||
| 52 | +} | ||
| 53 | + | ||
| 54 | +void QMQTT::Timer::start() | ||
| 55 | +{ | ||
| 56 | + _timer.start(); | ||
| 57 | +} | ||
| 58 | + | ||
| 59 | +void QMQTT::Timer::stop() | ||
| 60 | +{ | ||
| 61 | + _timer.stop(); | ||
| 62 | +} |
src/qmqtt_timer_p.h
0 → 100644
| 1 | +++ a/src/qmqtt_timer_p.h | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifndef QMQTT_TIMER_P_H | ||
| 23 | +#define QMQTT_TIMER_P_H | ||
| 24 | + | ||
| 25 | +#include "qmqtt_timerinterface.h" | ||
| 26 | + | ||
| 27 | +#include <QObject> | ||
| 28 | +#include <QTimer> | ||
| 29 | + | ||
| 30 | +namespace QMQTT { | ||
| 31 | + | ||
| 32 | +class Timer : public TimerInterface | ||
| 33 | +{ | ||
| 34 | + Q_OBJECT | ||
| 35 | +public: | ||
| 36 | + explicit Timer(QObject *parent = 0); | ||
| 37 | + virtual ~Timer(); | ||
| 38 | + | ||
| 39 | + bool isSingleShot() const; | ||
| 40 | + void setSingleShot(bool singleShot); | ||
| 41 | + int interval() const; | ||
| 42 | + void setInterval(int msec); | ||
| 43 | + void start(); | ||
| 44 | + void stop(); | ||
| 45 | + | ||
| 46 | +protected: | ||
| 47 | + QTimer _timer; | ||
| 48 | +}; | ||
| 49 | + | ||
| 50 | +} | ||
| 51 | + | ||
| 52 | +#endif // QMQTT_TIMER_P_H |
src/qmqtt_timerinterface.h
0 → 100644
| 1 | +++ a/src/qmqtt_timerinterface.h | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifndef QMQTT_TIMER_INTERFACE_H | ||
| 23 | +#define QMQTT_TIMER_INTERFACE_H | ||
| 24 | + | ||
| 25 | +#include "qmqtt_global.h" | ||
| 26 | + | ||
| 27 | +#include <QObject> | ||
| 28 | + | ||
| 29 | +namespace QMQTT { | ||
| 30 | + | ||
| 31 | +class Q_MQTT_EXPORT TimerInterface : public QObject | ||
| 32 | +{ | ||
| 33 | + Q_OBJECT | ||
| 34 | +public: | ||
| 35 | + explicit TimerInterface(QObject* parent = NULL) : QObject(parent) {} | ||
| 36 | + virtual ~TimerInterface() {} | ||
| 37 | + | ||
| 38 | + virtual bool isSingleShot() const = 0; | ||
| 39 | + virtual void setSingleShot(bool singleShot) = 0; | ||
| 40 | + virtual int interval() const = 0; | ||
| 41 | + virtual void setInterval(int msec) = 0; | ||
| 42 | + virtual void start() = 0; | ||
| 43 | + virtual void stop() = 0; | ||
| 44 | + | ||
| 45 | +signals: | ||
| 46 | + void timeout(); | ||
| 47 | +}; | ||
| 48 | + | ||
| 49 | +} | ||
| 50 | + | ||
| 51 | +#endif // QMQTT_TIMER_INTERFACE_H | ||
| 52 | + |
src/qmqtt_websocket.cpp
0 → 100644
| 1 | +++ a/src/qmqtt_websocket.cpp | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifdef QT_WEBSOCKETS_LIB | ||
| 23 | + | ||
| 24 | +#include "qmqtt_websocket_p.h" | ||
| 25 | + | ||
| 26 | +#include <QNetworkRequest> | ||
| 27 | +#include <QUrl> | ||
| 28 | +#include <QSslError> | ||
| 29 | + | ||
| 30 | +#ifndef QT_NO_SSL | ||
| 31 | +QMQTT::WebSocket::WebSocket(const QString& origin, | ||
| 32 | + QWebSocketProtocol::Version version, | ||
| 33 | + const QSslConfiguration* sslConfig, | ||
| 34 | + QObject* parent) | ||
| 35 | + : SocketInterface(parent) | ||
| 36 | + , _socket(new QWebSocket(origin, version, this)) | ||
| 37 | + , _ioDevice(new WebSocketIODevice(_socket, this)) | ||
| 38 | +{ | ||
| 39 | + initialize(); | ||
| 40 | + if (sslConfig != NULL) | ||
| 41 | + _socket->setSslConfiguration(*sslConfig); | ||
| 42 | + connect(_socket, &QWebSocket::sslErrors, this, &WebSocket::sslErrors); | ||
| 43 | +} | ||
| 44 | +#endif // QT_NO_SSL | ||
| 45 | + | ||
| 46 | +QMQTT::WebSocket::WebSocket(const QString& origin, | ||
| 47 | + QWebSocketProtocol::Version version, | ||
| 48 | + QObject* parent) | ||
| 49 | + : SocketInterface(parent) | ||
| 50 | + , _socket(new QWebSocket(origin, version, this)) | ||
| 51 | + , _ioDevice(new WebSocketIODevice(_socket, this)) | ||
| 52 | +{ | ||
| 53 | + initialize(); | ||
| 54 | +} | ||
| 55 | + | ||
| 56 | +void QMQTT::WebSocket::initialize() | ||
| 57 | +{ | ||
| 58 | + connect(_socket, &QWebSocket::connected, this, &WebSocket::connected); | ||
| 59 | + connect(_socket, &QWebSocket::disconnected, this, &WebSocket::disconnected); | ||
| 60 | + connect(_socket, | ||
| 61 | + static_cast<void (QWebSocket::*)(QAbstractSocket::SocketError)>(&QWebSocket::error), | ||
| 62 | + this, | ||
| 63 | + static_cast<void (SocketInterface::*)(QAbstractSocket::SocketError)>(&SocketInterface::error)); | ||
| 64 | +} | ||
| 65 | + | ||
| 66 | +QMQTT::WebSocket::~WebSocket() | ||
| 67 | +{ | ||
| 68 | +} | ||
| 69 | + | ||
| 70 | +void QMQTT::WebSocket::connectToHost(const QHostAddress& address, quint16 port) | ||
| 71 | +{ | ||
| 72 | + Q_UNUSED(address) | ||
| 73 | + Q_UNUSED(port) | ||
| 74 | + qFatal("No supported"); | ||
| 75 | +} | ||
| 76 | + | ||
| 77 | +void QMQTT::WebSocket::connectToHost(const QString& hostName, quint16 port) | ||
| 78 | +{ | ||
| 79 | + Q_UNUSED(port) | ||
| 80 | + QUrl url(hostName); | ||
| 81 | + QNetworkRequest request(url); | ||
| 82 | + request.setRawHeader("Sec-WebSocket-Protocol", "mqtt"); | ||
| 83 | + _ioDevice->connectToHost(request); | ||
| 84 | +} | ||
| 85 | + | ||
| 86 | +void QMQTT::WebSocket::disconnectFromHost() | ||
| 87 | +{ | ||
| 88 | + _socket->close(); | ||
| 89 | +} | ||
| 90 | + | ||
| 91 | +QAbstractSocket::SocketState QMQTT::WebSocket::state() const | ||
| 92 | +{ | ||
| 93 | + return _socket->state(); | ||
| 94 | +} | ||
| 95 | + | ||
| 96 | +QAbstractSocket::SocketError QMQTT::WebSocket::error() const | ||
| 97 | +{ | ||
| 98 | + return _socket->error(); | ||
| 99 | +} | ||
| 100 | + | ||
| 101 | +#ifndef QT_NO_SSL | ||
| 102 | +void QMQTT::WebSocket::ignoreSslErrors(const QList<QSslError>& errors) | ||
| 103 | +{ | ||
| 104 | + _socket->ignoreSslErrors(errors); | ||
| 105 | +} | ||
| 106 | + | ||
| 107 | +void QMQTT::WebSocket::ignoreSslErrors() | ||
| 108 | +{ | ||
| 109 | + _socket->ignoreSslErrors(); | ||
| 110 | +} | ||
| 111 | + | ||
| 112 | +QSslConfiguration QMQTT::WebSocket::sslConfiguration() const | ||
| 113 | +{ | ||
| 114 | + return _socket->sslConfiguration(); | ||
| 115 | +} | ||
| 116 | + | ||
| 117 | +void QMQTT::WebSocket::setSslConfiguration(const QSslConfiguration& config) | ||
| 118 | +{ | ||
| 119 | + _socket->setSslConfiguration(config); | ||
| 120 | +} | ||
| 121 | + | ||
| 122 | +#endif // QT_NO_SSL | ||
| 123 | + | ||
| 124 | +#endif // QT_WEBSOCKETS_LIB |
src/qmqtt_websocket_p.h
0 → 100644
| 1 | +++ a/src/qmqtt_websocket_p.h | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifndef QMQTT_WEBSOCKET_H | ||
| 23 | +#define QMQTT_WEBSOCKET_H | ||
| 24 | + | ||
| 25 | +#ifdef QT_WEBSOCKETS_LIB | ||
| 26 | + | ||
| 27 | +#include <qmqtt_socketinterface.h> | ||
| 28 | +#include <qmqtt_websocketiodevice_p.h> | ||
| 29 | + | ||
| 30 | +#include <QObject> | ||
| 31 | +#include <QWebSocket> | ||
| 32 | +#include <QHostAddress> | ||
| 33 | +#include <QString> | ||
| 34 | +#include <QList> | ||
| 35 | +#include <QAbstractSocket> | ||
| 36 | + | ||
| 37 | +QT_FORWARD_DECLARE_CLASS(QIODevice) | ||
| 38 | + | ||
| 39 | +#ifndef QT_NO_SSL | ||
| 40 | +#include <QSslConfiguration> | ||
| 41 | +QT_FORWARD_DECLARE_CLASS(QSslError) | ||
| 42 | +#endif // QT_NO_SSL | ||
| 43 | + | ||
| 44 | +namespace QMQTT | ||
| 45 | +{ | ||
| 46 | + | ||
| 47 | +class WebSocket : public SocketInterface | ||
| 48 | +{ | ||
| 49 | + Q_OBJECT | ||
| 50 | +public: | ||
| 51 | +#ifndef QT_NO_SSL | ||
| 52 | + WebSocket(const QString& origin, | ||
| 53 | + QWebSocketProtocol::Version version, | ||
| 54 | + const QSslConfiguration* sslConfig, | ||
| 55 | + QObject* parent = NULL); | ||
| 56 | +#endif // QT_NO_SSL | ||
| 57 | + | ||
| 58 | + WebSocket(const QString& origin, | ||
| 59 | + QWebSocketProtocol::Version version, | ||
| 60 | + QObject* parent = NULL); | ||
| 61 | + | ||
| 62 | + virtual ~WebSocket(); | ||
| 63 | + | ||
| 64 | + QIODevice *ioDevice() | ||
| 65 | + { | ||
| 66 | + return _ioDevice; | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + void connectToHost(const QHostAddress& address, quint16 port); | ||
| 70 | + void connectToHost(const QString& hostName, quint16 port); | ||
| 71 | + void disconnectFromHost(); | ||
| 72 | + QAbstractSocket::SocketState state() const; | ||
| 73 | + QAbstractSocket::SocketError error() const; | ||
| 74 | +#ifndef QT_NO_SSL | ||
| 75 | + void ignoreSslErrors(const QList<QSslError>& errors); | ||
| 76 | + void ignoreSslErrors(); | ||
| 77 | + QSslConfiguration sslConfiguration() const; | ||
| 78 | + void setSslConfiguration(const QSslConfiguration& config); | ||
| 79 | +#endif // QT_NO_SSL | ||
| 80 | + | ||
| 81 | +private: | ||
| 82 | + void initialize(); | ||
| 83 | + | ||
| 84 | + QWebSocket *_socket; | ||
| 85 | + WebSocketIODevice *_ioDevice; | ||
| 86 | +}; | ||
| 87 | + | ||
| 88 | +} | ||
| 89 | + | ||
| 90 | +#endif // QT_WEBSOCKETS_LIB | ||
| 91 | + | ||
| 92 | +#endif // QMQTT_WEBSOCKET_H |
src/qmqtt_websocketiodevice.cpp
0 → 100644
| 1 | +++ a/src/qmqtt_websocketiodevice.cpp | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifdef QT_WEBSOCKETS_LIB | ||
| 23 | + | ||
| 24 | +#include "qmqtt_websocketiodevice_p.h" | ||
| 25 | + | ||
| 26 | +#include <QWebSocket> | ||
| 27 | + | ||
| 28 | +QMQTT::WebSocketIODevice::WebSocketIODevice(QWebSocket *socket, QObject *parent) | ||
| 29 | + : QIODevice(parent) | ||
| 30 | + , _webSocket(socket) | ||
| 31 | +{ | ||
| 32 | + connect(_webSocket, &QWebSocket::bytesWritten, this, &WebSocketIODevice::bytesWritten); | ||
| 33 | + connect(_webSocket, &QWebSocket::binaryMessageReceived, | ||
| 34 | + this, &WebSocketIODevice::binaryMessageReceived); | ||
| 35 | +} | ||
| 36 | + | ||
| 37 | +bool QMQTT::WebSocketIODevice::connectToHost(const QNetworkRequest &request) | ||
| 38 | +{ | ||
| 39 | + _webSocket->open(request); | ||
| 40 | + return QIODevice::open(QIODevice::ReadWrite); | ||
| 41 | +} | ||
| 42 | + | ||
| 43 | +qint64 QMQTT::WebSocketIODevice::bytesAvailable() const | ||
| 44 | +{ | ||
| 45 | + return _buffer.count(); | ||
| 46 | +} | ||
| 47 | + | ||
| 48 | +void QMQTT::WebSocketIODevice::binaryMessageReceived(const QByteArray &frame) | ||
| 49 | +{ | ||
| 50 | + _buffer.append(frame); | ||
| 51 | + emit readyRead(); | ||
| 52 | +} | ||
| 53 | + | ||
| 54 | +qint64 QMQTT::WebSocketIODevice::readData(char *data, qint64 maxSize) | ||
| 55 | +{ | ||
| 56 | + int size = qMin(static_cast<int>(maxSize), _buffer.count()); | ||
| 57 | + for (int i=0; i<size; ++ i) | ||
| 58 | + data[i] = _buffer[i]; | ||
| 59 | + _buffer.remove(0, size); | ||
| 60 | + return size; | ||
| 61 | +} | ||
| 62 | + | ||
| 63 | +qint64 QMQTT::WebSocketIODevice::writeData(const char *data, qint64 maxSize) | ||
| 64 | +{ | ||
| 65 | + QByteArray d(data, static_cast<int>(maxSize)); | ||
| 66 | + return _webSocket->sendBinaryMessage(d); | ||
| 67 | +} | ||
| 68 | + | ||
| 69 | +#endif // QT_WEBSOCKETS_LIB |
src/qmqtt_websocketiodevice_p.h
0 → 100644
| 1 | +++ a/src/qmqtt_websocketiodevice_p.h | ||
| 1 | +/* **************************************************************************** | ||
| 2 | + * Copyright 2019 Open Systems Development BV * | ||
| 3 | + * * | ||
| 4 | + * Permission is hereby granted, free of charge, to any person obtaining a * | ||
| 5 | + * copy of this software and associated documentation files (the "Software"), * | ||
| 6 | + * to deal in the Software without restriction, including without limitation * | ||
| 7 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, * | ||
| 8 | + * and/or sell copies of the Software, and to permit persons to whom the * | ||
| 9 | + * Software is furnished to do so, subject to the following conditions: * | ||
| 10 | + * * | ||
| 11 | + * The above copyright notice and this permission notice shall be included in * | ||
| 12 | + * all copies or substantial portions of the Software. * | ||
| 13 | + * * | ||
| 14 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * | ||
| 15 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * | ||
| 16 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * | ||
| 17 | + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * | ||
| 18 | + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * | ||
| 19 | + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * | ||
| 20 | + * DEALINGS IN THE SOFTWARE. * | ||
| 21 | + * ***************************************************************************/ | ||
| 22 | +#ifndef QMQTT_WEBSOCKETIODEVICE_H | ||
| 23 | +#define QMQTT_WEBSOCKETIODEVICE_H | ||
| 24 | + | ||
| 25 | +#ifdef QT_WEBSOCKETS_LIB | ||
| 26 | + | ||
| 27 | +#include <QByteArray> | ||
| 28 | +#include <QIODevice> | ||
| 29 | +#include <QList> | ||
| 30 | +#include <QAbstractSocket> | ||
| 31 | + | ||
| 32 | +QT_FORWARD_DECLARE_CLASS(QWebSocket) | ||
| 33 | +QT_FORWARD_DECLARE_CLASS(QNetworkRequest) | ||
| 34 | +QT_FORWARD_DECLARE_CLASS(QSslError) | ||
| 35 | + | ||
| 36 | +namespace QMQTT | ||
| 37 | +{ | ||
| 38 | + | ||
| 39 | +class WebSocketIODevice : public QIODevice | ||
| 40 | +{ | ||
| 41 | + Q_OBJECT | ||
| 42 | +public: | ||
| 43 | + explicit WebSocketIODevice(QWebSocket *socket, QObject *parent = NULL); | ||
| 44 | + | ||
| 45 | + bool connectToHost(const QNetworkRequest &request); | ||
| 46 | + | ||
| 47 | + virtual qint64 bytesAvailable() const; | ||
| 48 | + | ||
| 49 | +signals: | ||
| 50 | + void connected(); | ||
| 51 | + | ||
| 52 | + void disconnected(); | ||
| 53 | + | ||
| 54 | + void error(QAbstractSocket::SocketError error); | ||
| 55 | + | ||
| 56 | + void sslErrors(const QList<QSslError> &errors); | ||
| 57 | + | ||
| 58 | +protected: | ||
| 59 | + virtual qint64 readData(char *data, qint64 maxSize); | ||
| 60 | + | ||
| 61 | + virtual qint64 writeData(const char *data, qint64 maxSize); | ||
| 62 | + | ||
| 63 | +private slots: | ||
| 64 | + void binaryMessageReceived(const QByteArray &frame); | ||
| 65 | + | ||
| 66 | +private: | ||
| 67 | + QByteArray _buffer; | ||
| 68 | + QWebSocket *_webSocket; | ||
| 69 | +}; | ||
| 70 | + | ||
| 71 | +} | ||
| 72 | + | ||
| 73 | +#endif // QT_WEBSOCKETS_LIB | ||
| 74 | + | ||
| 75 | +#endif // QMQTT_WEBSOCKETIODEVICE_H |
tests/CMakeLists.txt
0 → 100644
| 1 | +++ a/tests/CMakeLists.txt | ||
| 1 | +cmake_minimum_required(VERSION 3.0) | ||
| 2 | +LIST(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) | ||
| 3 | + | ||
| 4 | +include(projectheader) | ||
| 5 | +project_header(test_logutils) | ||
| 6 | + | ||
| 7 | +include_directories( SYSTEM | ||
| 8 | + ${CMAKE_CURRENT_SOURCE_DIR}/../../src | ||
| 9 | +) | ||
| 10 | + | ||
| 11 | +include(compiler) | ||
| 12 | +set(SRC_LIST | ||
| 13 | +) | ||
| 14 | + | ||
| 15 | +# add_executable( ${PROJECT_NAME} | ||
| 16 | +# ${SRC_LIST} | ||
| 17 | +# ) | ||
| 18 | + | ||
| 19 | +# target_link_libraries( | ||
| 20 | +# ${PROJECT_NAME} | ||
| 21 | +# ) | ||
| 22 | + | ||
| 23 | +# set_target_properties( ${PROJECT_NAME} PROPERTIES | ||
| 24 | +# RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin | ||
| 25 | +# LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib | ||
| 26 | +# ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/archive | ||
| 27 | +# ) | ||
| 28 | + | ||
| 29 | +# include(installation) | ||
| 30 | +# install_application() |