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() | ... | ... |