├── .github
├── FUNDING.yml
└── workflows
│ ├── c-cpp.yml
│ └── label.yml
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── debian
├── changelog
├── compat
├── control
├── gbp.conf
├── rules
└── source
│ └── options
├── ledindicator.cpp
├── ledindicator.h
├── libqmqtt
├── CMakeLists.txt
├── Makefile.qmqtt
├── qmqtt.h
├── qmqtt.pri
├── qmqtt.pro
├── qmqtt_client.cpp
├── qmqtt_client.h
├── qmqtt_client_p.cpp
├── qmqtt_client_p.h
├── qmqtt_frame.cpp
├── qmqtt_frame.h
├── qmqtt_global.h
├── qmqtt_message.cpp
├── qmqtt_message.h
├── qmqtt_message_p.cpp
├── qmqtt_message_p.h
├── qmqtt_network.cpp
├── qmqtt_network.h
├── qmqtt_networkinterface.h
├── qmqtt_routedmessage.cpp
├── qmqtt_routedmessage.h
├── qmqtt_router.cpp
├── qmqtt_router.h
├── qmqtt_routesubscription.cpp
├── qmqtt_routesubscription.h
├── qmqtt_socket.cpp
├── qmqtt_socket.h
├── qmqtt_socketinterface.h
├── qmqtt_ssl_network.cpp
├── qmqtt_ssl_network.h
├── qmqtt_ssl_socket.cpp
├── qmqtt_ssl_socket.h
├── qmqtt_timer.cpp
├── qmqtt_timer.h
└── qmqtt_timerinterface.h
├── main.cpp
├── main.pro
├── mainwindow.cpp
├── mainwindow.h
├── mainwindow.ui
├── qcustomplot.cpp
├── qcustomplot.h
├── qmqtt-plot.desktop
├── qmqtt-plot.png
├── qmqtt-plot.svg
└── res.qrc
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | custom: 'http://koppi.github.io/'
2 |
--------------------------------------------------------------------------------
/.github/workflows/c-cpp.yml:
--------------------------------------------------------------------------------
1 | name: C/C++ CI
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 |
9 | jobs:
10 | build:
11 |
12 | runs-on: ubuntu-latest
13 |
14 | steps:
15 | - uses: actions/checkout@v2
16 | - name: packages
17 | run: |
18 | sudo apt -y install debhelper pkgconf automake libtool cmake qt5-default qt5-qmake qtbase5-dev qttools5-dev-tools lsb-release
19 | - name: libraries
20 | run: |
21 | cd libqmqtt
22 | qmake
23 | make -j$(nproc)
24 | sudo make install
25 | - name: build
26 | run: |
27 | qmake
28 | make
29 |
--------------------------------------------------------------------------------
/.github/workflows/label.yml:
--------------------------------------------------------------------------------
1 | # This workflow will triage pull requests and apply a label based on the
2 | # paths that are modified in the pull request.
3 | #
4 | # To use this workflow, you will need to set up a .github/labeler.yml
5 | # file with configuration. For more information, see:
6 | # https://github.com/actions/labeler
7 |
8 | name: Labeler
9 | on: [pull_request]
10 |
11 | jobs:
12 | label:
13 |
14 | runs-on: ubuntu-latest
15 | permissions:
16 | contents: read
17 | pull-requests: write
18 |
19 | steps:
20 | - uses: actions/labeler@v2
21 | with:
22 | repo-token: "${{ secrets.GITHUB_TOKEN }}"
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | qmqtt-plot
2 | main.pro.user
3 | debian/*.log
4 | qrc_res.cpp
5 | build-stamp
6 | Makefile
7 | ui_*.h
8 | moc_*.cpp
9 | *.o
10 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: required
2 |
3 | services:
4 | - docker
5 |
6 | script:
7 | - export TRAVIS_DEBIAN_DISTRIBUTION=sid; wget -O- http://travis.debian.net/script.sh | sh -
8 |
9 | branches:
10 | except:
11 | - /^debian\/\d/
12 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### A Qt5 app that plots timestamped MQTT data [](https://github.com/koppi/qmqtt-plot/actions/workflows/c-cpp.yml)
2 |
3 | 
4 |
5 | * Quick Video demos:
6 |
7 | * [MQTT broker latency test with Machinekit + EtherCAT on Raspberry Pi3 ](https://www.youtube.com/watch?v=uFbr7xBjItE)
8 | * [Trajectory generation inside the Mitsubishi RM-501 Movemaster II Robot Simulator](https://www.youtube.com/watch?v=dLeDPIRKhOw)
9 |
10 | #### Build and install qmqtt-plot
11 |
12 | ```bash
13 | gh repo clone koppi/qmqtt-plot
14 | cd qmqtt-plot
15 | cd libqmqtt
16 | qmake
17 | make -j$(nproc)
18 | sudo make install
19 | cd ..
20 | qmake
21 | make
22 | ./qmqtt-plot
23 | ```
24 |
25 | * Enter your MQTT broker's hostname and click connect.
26 |
27 | #### Credits
28 |
29 | Libraries included:
30 |
31 | * [qcustomplot.com](http://qcustomplot.com)
32 | * [qmqtt](https://github.com/emqtt/qmqtt)
33 |
34 | Artwork:
35 |
36 | * [qmqtt-plot.svg](https://openclipart.org/detail/200755/primary-plot) by danny
37 |
--------------------------------------------------------------------------------
/debian/changelog:
--------------------------------------------------------------------------------
1 | qmqtt-plot (0.0.1-1) UNRELEASED; urgency=medium
2 |
3 | * Bump version 0.0.1.
4 |
5 | -- Jakob Flierl Sun, 05 Jun 2016 12:46:03 +0200
6 |
--------------------------------------------------------------------------------
/debian/compat:
--------------------------------------------------------------------------------
1 | 7
2 |
--------------------------------------------------------------------------------
/debian/control:
--------------------------------------------------------------------------------
1 | Source: qmqtt-plot
2 | Section: graphics
3 | Priority: optional
4 | Maintainer: Jakob Flierl
5 | Uploaders: Jakob Flierl
6 | Build-Depends: debhelper (>= 7.0.50~), pkgconf, automake, libtool, cmake, qt5-default, qt5-qmake, qtbase5-dev, qttools5-dev-tools, lsb-release
7 | Standards-Version: 3.9.7
8 | Homepage: https://github.com/koppi/qmqtt-plot
9 | Vcs-Git: git://github.com/koppi/qmqtt-plot.git
10 | Vcs-Browser: https://github.com/koppi/qmqtt-plot
11 |
12 | Package: qmqtt-plot
13 | Architecture: any
14 | Depends: ${shlibs:Depends}, ${misc:Depends}
15 | Description: MQTT plot Qt5 app
16 | A GUI that plots timestamped MQTT data.
17 |
--------------------------------------------------------------------------------
/debian/gbp.conf:
--------------------------------------------------------------------------------
1 | [DEFAULT]
2 | # the default branch for upstream sources:
3 | upstream-branch = master
4 | # the default branch for the debian patch:
5 | debian-branch = master
6 | # the default tag formats used:
7 | upstream-tag = %(version)s
8 | debian-tag = debian/%(version)s
9 | # use pristine-tar:
10 | #pristine-tar = True
11 |
--------------------------------------------------------------------------------
/debian/rules:
--------------------------------------------------------------------------------
1 | #!/usr/bin/make -f
2 |
3 | # Uncomment this to turn on verbose mode.
4 | export DH_VERBOSE=1
5 |
6 | CXXFLAGS = -Wall -g
7 |
8 | ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
9 | CXXFLAGS += -O0
10 | else
11 | CXXFLAGS += -O2
12 | endif
13 | ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
14 | INSTALL_PROGRAM += -s
15 | endif
16 |
17 | QMAKE_AFTER = -after \
18 | 'QMAKE_CXXFLAGS_RELEASE = $(CXXFLAGS)' \
19 | 'QMAKE_POST_LINK ~= s/strip/:'
20 |
21 | build: build-stamp
22 | build-stamp: $(QUILT_STAMPFN)
23 | dh_testdir
24 |
25 | qmake $(QMAKE_AFTER) main.pro && $(MAKE) -j$(nproc)
26 |
27 | touch $@
28 |
29 | clean:
30 | dh_testdir
31 | dh_testroot
32 | rm -f build-stamp
33 | [ ! -f Makefile ] || $(MAKE) clean
34 | dh_clean
35 |
36 | install: build
37 | dh_testdir
38 | dh_testroot
39 | dh_clean -k
40 | dh_installdirs
41 |
42 | $(MAKE) INSTALL_ROOT=$(CURDIR)/debian/qmqtt-plot install
43 | install -d -v -m 0755 $(CURDIR)/debian/qmqtt-plot/usr/share/applications
44 | chmod 664 $(CURDIR)/debian/qmqtt-plot/usr/share/applications/qmqtt-plot.desktop
45 |
46 | install -d -v -m 0755 $(CURDIR)/debian/qmqtt-plot/usr/share/icons/hicolor/scalable/apps
47 | chmod 664 $(CURDIR)/debian/qmqtt-plot/usr/share/icons/hicolor/scalable/apps/qmqtt-plot.svg
48 |
49 | install -d -v -m 0755 $(CURDIR)/debian/qmqtt-plot/usr/bin
50 | install -m 755 -p qmqtt-plot $(CURDIR)/debian/qmqtt-plot/usr/bin/qmqtt-plot
51 |
52 | # Build architecture-independent files here.
53 | binary-indep: build install
54 | dh_testdir
55 | dh_testroot
56 | # dh_installchangelogs ChangeLog
57 | dh_installdocs -i
58 | dh_install -i
59 | dh_installman -i
60 | dh_compress -i --exclude=.cpp --exclude=.pri
61 | dh_fixperms
62 | dh_installdeb
63 | dh_gencontrol
64 | dh_md5sums
65 | dh_builddeb
66 |
67 | # Build architecture-dependent files here.
68 | binary-arch: build install
69 | dh_testdir
70 | dh_testroot
71 | # dh_installchangelogs ChangeLog
72 | dh_installdocs -s README.md
73 | dh_install -s --sourcedir=$(CURDIR)/debian/qmqtt-plot
74 | # dh_installman qmqtt-plot.1
75 | dh_installmime
76 | dh_installmenu
77 | dh_link
78 | dh_strip
79 | dh_compress -s
80 | dh_fixperms
81 | dh_makeshlibs
82 | dh_installdeb
83 | dh_shlibdeps
84 | dh_gencontrol
85 | dh_md5sums
86 | dh_builddeb
87 |
88 | binary: binary-indep binary-arch
89 | .PHONY: build clean binary-indep binary-arch binary install configure
90 |
--------------------------------------------------------------------------------
/debian/source/options:
--------------------------------------------------------------------------------
1 | extend-diff-ignore = "^\.travis\.yml$"
2 |
--------------------------------------------------------------------------------
/ledindicator.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Jakob Flierl
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice,
9 | * this list of conditions and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright
11 | * notice, this list of conditions and the following disclaimer in the
12 | * documentation and/or other materials provided with the distribution.
13 | * * Neither the name of mqttc nor the names of its contributors may be used
14 | * to endorse or promote products derived from this software without
15 | * specific prior written permission.
16 | *
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | * POSSIBILITY OF SUCH DAMAGE.
28 | *
29 | */
30 |
31 | #include
32 |
33 | #include "ledindicator.h"
34 |
35 | QLedIndicator::QLedIndicator(QWidget *parent) : QWidget(parent)
36 | {
37 | setDisconnected(true);
38 | scaledSize = 1000;
39 |
40 | setMinimumSize(24, 24);
41 | setOn(true);
42 | disconnectedColor1 = QColor(50,50,50);
43 | disconnectedColor2 = QColor(30,30,30);
44 | onColor1 = QColor(0,255,0);
45 | onColor2 = QColor(0,192,0);
46 | offColor1 = QColor(0,28,0);
47 | offColor2 = QColor(0,128,0);
48 | }
49 |
50 | void QLedIndicator::resizeEvent(QResizeEvent *event) {
51 | Q_UNUSED(event)
52 | update();
53 | }
54 |
55 | void QLedIndicator::paintEvent(QPaintEvent *event) {
56 | Q_UNUSED(event)
57 | qreal realSize = qMin(width(), height());
58 |
59 | QRadialGradient gradient;
60 | QPainter painter(this);
61 | QPen pen(Qt::black);
62 | pen.setWidth(1);
63 |
64 | // painter.setRenderHint(QPainter::Antialiasing);
65 | painter.translate((width())/2, (height())/2);
66 | painter.scale(realSize/scaledSize, realSize/scaledSize);
67 |
68 | gradient = QRadialGradient (QPointF(-500,-500), 1500, QPointF(-500,-500));
69 | gradient.setColorAt(0, QColor(224,224,224));
70 | gradient.setColorAt(1, QColor(28,28,28));
71 | painter.setPen(pen);
72 | painter.setBrush(QBrush(gradient));
73 | painter.drawEllipse(QPointF(2,2), 500-2, 500-2);
74 |
75 | gradient = QRadialGradient (QPointF(500,500), 1500, QPointF(500,500));
76 | gradient.setColorAt(0, QColor(224,224,224));
77 | gradient.setColorAt(1, QColor(28,28,28));
78 | painter.setPen(pen);
79 | painter.setBrush(QBrush(gradient));
80 | painter.drawEllipse(QPointF(2,2), 450-2, 450-2);
81 |
82 | painter.setPen(pen);
83 |
84 | if (isDisconnected()) {
85 | gradient = QRadialGradient (QPointF(500,500), 1500, QPointF(500,500));
86 | gradient.setColorAt(0, disconnectedColor1);
87 | gradient.setColorAt(1, disconnectedColor2);
88 | } else {
89 | if (isOn()) {
90 | gradient = QRadialGradient (QPointF(-500,-500), 1500, QPointF(-500,-500));
91 | gradient.setColorAt(0, onColor1);
92 | gradient.setColorAt(1, onColor2);
93 | } else {
94 | gradient = QRadialGradient (QPointF(500,500), 1500, QPointF(500,500));
95 | gradient.setColorAt(0, offColor1);
96 | gradient.setColorAt(1, offColor2);
97 | }
98 | }
99 | painter.setBrush(gradient);
100 | painter.drawEllipse(QPointF(2,2), 400-2, 400-2);
101 | }
102 |
--------------------------------------------------------------------------------
/ledindicator.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Jakob Flierl
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice,
9 | * this list of conditions and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright
11 | * notice, this list of conditions and the following disclaimer in the
12 | * documentation and/or other materials provided with the distribution.
13 | * * Neither the name of mqttc nor the names of its contributors may be used
14 | * to endorse or promote products derived from this software without
15 | * specific prior written permission.
16 | *
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | * POSSIBILITY OF SUCH DAMAGE.
28 | *
29 | */
30 |
31 | #ifndef QLEDINDICATOR_H
32 | #define QLEDINDICATOR_H
33 |
34 | #include
35 | #include
36 | #include
37 |
38 | class QLedIndicator : public QWidget
39 | {
40 | Q_PROPERTY(QColor disconnectedColor1 WRITE setDisconnectedColor1 READ getDisconnectedColor1 );
41 | Q_PROPERTY(QColor disconnectedColor2 WRITE setDisconnectedColor2 READ getDisconnectedColor2 );
42 | Q_PROPERTY(QColor onColor1 WRITE setOnColor1 READ getOnColor1 );
43 | Q_PROPERTY(QColor onColor2 WRITE setOnColor2 READ getOnColor2 );
44 | Q_PROPERTY(QColor offColor1 WRITE setOffColor1 READ getOffColor1 );
45 | Q_PROPERTY(QColor offColor2 WRITE setOffColor2 READ getOffColor2 );
46 | Q_PROPERTY(bool disconnected WRITE setDisconnected READ isDisconnected );
47 |
48 | Q_OBJECT
49 | public:
50 | QLedIndicator(QWidget *parent);
51 |
52 | void setDisconnected(bool c) { disconnected = c; update(); }
53 | void setDisconnectedColor1(QColor c) { disconnectedColor1 = c; update(); }
54 | void setDisconnectedColor2(QColor c) { disconnectedColor2 = c; update(); }
55 | void setOnColor1(QColor c) { onColor1 = c; update(); }
56 | void setOffColor1(QColor c) { offColor1 = c; update(); }
57 | void setOnColor2(QColor c) { onColor2 = c; update(); }
58 | void setOffColor2(QColor c) { offColor2 = c; update(); }
59 |
60 | void setOn(bool onoff) { on = onoff; }
61 |
62 | bool isDisconnected(void) { return disconnected; }
63 | QColor getDisconnectedColor1(void) { return disconnectedColor1; }
64 | QColor getDisconnectedColor2(void) { return disconnectedColor2; }
65 | QColor getOnColor1(void) { return onColor1; }
66 | QColor getOffColor1(void) { return offColor1; }
67 | QColor getOnColor2(void) { return onColor2; }
68 | QColor getOffColor2(void) { return offColor2; }
69 |
70 | bool isOn() { return on; }
71 |
72 | protected:
73 | virtual void paintEvent (QPaintEvent *event);
74 | virtual void resizeEvent(QResizeEvent *event);
75 |
76 | private:
77 | qreal scaledSize;
78 | QColor disconnectedColor1, disconnectedColor2;
79 | QColor onColor1, offColor1;
80 | QColor onColor2, offColor2;
81 | QPixmap ledBuffer;
82 | bool disconnected;
83 | bool on;
84 | };
85 |
86 | #endif // QLEDINDICATOR_H
87 |
--------------------------------------------------------------------------------
/libqmqtt/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 2.8.11)
2 |
3 | project(qmqtt)
4 |
5 | set(CMAKE_VERBOSE_MAKEFILE on)
6 | set(CMAKE_INCLUDE_CURRENT_DIR ON)
7 | set(CMAKE_AUTOMOC ON)
8 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
9 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
10 | set(CMAKE_CXX_FLAGS_RELEASE "-O0 -g0")
11 | set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g3")
12 | set(CMAKE_C_FLAGS_RELEASE "-O0 -g0")
13 | set(CMAKE_C_FLAGS_DEBUG "-O0 -g3")
14 |
15 | find_package(Qt5Core REQUIRED)
16 | find_package(Qt5Network REQUIRED)
17 |
18 | file(GLOB srcfiles "*.cpp")
19 | file(GLOB headerfiles "*.h")
20 |
21 | add_library(qmqtt SHARED ${srcfiles} ${headerfiles})
22 | target_link_libraries(qmqtt Qt5::Core Qt5::Network)
23 |
24 | install(TARGETS qmqtt DESTINATION "lib")
25 | install(FILES ${headerfiles} DESTINATION "include")
26 |
27 | add_subdirectory(examples)
28 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt.h:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt.h - qmqtt library heaer
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | *
10 | * * Redistributions of source code must retain the above copyright notice,
11 | * this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above copyright
13 | * notice, this list of conditions and the following disclaimer in the
14 | * documentation and/or other materials provided with the distribution.
15 | * * Neither the name of mqttc nor the names of its contributors may be used
16 | * to endorse or promote products derived from this software without
17 | * specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | * POSSIBILITY OF SUCH DAMAGE.
30 | *
31 | */
32 | #ifndef QMQTT_H
33 | #define QMQTT_H
34 |
35 | #include "qmqtt_message.h"
36 | #include "qmqtt_client.h"
37 |
38 | #endif // QMQTT_H
39 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt.pri:
--------------------------------------------------------------------------------
1 | INCLUDEPATH += $$PWD
2 | DEPENDPATH += $$PWD
3 |
4 | HEADERS += \
5 | $$PWD/qmqtt_client_p.h \
6 | $$PWD/qmqtt_client.h \
7 | $$PWD/qmqtt_frame.h \
8 | $$PWD/qmqtt_global.h \
9 | $$PWD/qmqtt_message.h \
10 | $$PWD/qmqtt_network.h \
11 | $$PWD/qmqtt_ssl_network.h \
12 | $$PWD/qmqtt.h \
13 | $$PWD/qmqtt_routesubscription.h \
14 | $$PWD/qmqtt_routedmessage.h \
15 | $$PWD/qmqtt_router.h \
16 | $$PWD/qmqtt_networkinterface.h \
17 | $$PWD/qmqtt_message_p.h \
18 | $$PWD/qmqtt_socket.h \
19 | $$PWD/qmqtt_ssl_socket.h \
20 | $$PWD/qmqtt_socketinterface.h \
21 | $$PWD/qmqtt_timerinterface.h \
22 | $$PWD/qmqtt_timer.h
23 |
24 | SOURCES += \
25 | $$PWD/qmqtt_client_p.cpp \
26 | $$PWD/qmqtt_client.cpp \
27 | $$PWD/qmqtt_frame.cpp \
28 | $$PWD/qmqtt_message.cpp \
29 | $$PWD/qmqtt_network.cpp \
30 | $$PWD/qmqtt_ssl_network.cpp \
31 | $$PWD/qmqtt_routesubscription.cpp \
32 | $$PWD/qmqtt_routedmessage.cpp \
33 | $$PWD/qmqtt_router.cpp \
34 | $$PWD/qmqtt_message_p.cpp \
35 | $$PWD/qmqtt_socket.cpp \
36 | $$PWD/qmqtt_ssl_socket.cpp \
37 | $$PWD/qmqtt_timer.cpp
38 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt.pro:
--------------------------------------------------------------------------------
1 | QT += network
2 |
3 | QT -= gui
4 |
5 | TARGET = qmqtt
6 | TEMPLATE = lib
7 |
8 | DEFINES += QMQTT_LIBRARY
9 |
10 | SOURCES += qmqtt_client.cpp \
11 | qmqtt_network.cpp \
12 | qmqtt_frame.cpp \
13 | qmqtt_client_p.cpp \
14 | qmqtt_message.cpp \
15 | qmqtt_router.cpp \
16 | qmqtt_routesubscription.cpp \
17 | qmqtt_routedmessage.cpp \
18 | qmqtt_message_p.cpp \
19 | qmqtt_socket.cpp \
20 | qmqtt_timer.cpp \
21 | qmqtt_ssl_socket.cpp \
22 | qmqtt_ssl_network.cpp
23 |
24 | HEADERS += qmqtt_client.h\
25 | qmqtt_global.h \
26 | qmqtt_network.h \
27 | qmqtt_frame.h \
28 | qmqtt_client_p.h \
29 | qmqtt_message.h \
30 | qmqtt_router.h \
31 | qmqtt.h \
32 | qmqtt_routesubscription.h \
33 | qmqtt_routedmessage.h \
34 | qmqtt_networkinterface.h \
35 | qmqtt_message_p.h \
36 | qmqtt_socketinterface.h \
37 | qmqtt_socket.h \
38 | qmqtt_timer.h \
39 | qmqtt_timerinterface.h \
40 | qmqtt_ssl_socket.h \
41 | qmqtt_ssl_network.h
42 |
43 | isEmpty(PREFIX) {
44 | contains(MEEGO_EDITION,harmattan) {
45 | PREFIX = /usr
46 | } else:unix:!symbian {
47 | maemo5 {
48 | PREFIX = /opt/usr
49 | } else {
50 | PREFIX = /usr/local
51 | }
52 | } else {
53 | PREFIX = $$[QT_INSTALL_PREFIX]
54 | }
55 | }
56 |
57 | headers.files = $$HEADERS
58 | headers.path = $$PREFIX/include/qmqtt
59 | target.path = $$PREFIX/lib
60 | INSTALLS += headers target
61 |
62 | OTHER_FILES += \
63 | qmqtt.pri
64 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_client.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_client.cpp - qmqtt client
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | *
10 | * * Redistributions of source code must retain the above copyright notice,
11 | * this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above copyright
13 | * notice, this list of conditions and the following disclaimer in the
14 | * documentation and/or other materials provided with the distribution.
15 | * * Neither the name of mqttc nor the names of its contributors may be used
16 | * to endorse or promote products derived from this software without
17 | * specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | * POSSIBILITY OF SUCH DAMAGE.
30 | *
31 | */
32 |
33 | #include "qmqtt_client.h"
34 | #include "qmqtt_client_p.h"
35 |
36 | QMQTT::Client::Client(const QHostAddress& host,
37 | const quint16 port,
38 | QObject* parent)
39 | : QObject(parent)
40 | , d_ptr(new ClientPrivate(this))
41 | {
42 | Q_D(Client);
43 | d->init(host, port);
44 | }
45 |
46 | QMQTT::Client::Client(const QString &hostName,
47 | const quint16 port,
48 | const bool ssl,
49 | const bool ignoreSelfSigned,
50 | QObject* parent)
51 | : QObject(parent)
52 | , d_ptr(new ClientPrivate(this))
53 | {
54 | Q_D(Client);
55 | d->init(hostName, port, ssl, ignoreSelfSigned);
56 | }
57 |
58 | QMQTT::Client::Client(NetworkInterface* network,
59 | const QHostAddress& host,
60 | const quint16 port,
61 | QObject* parent)
62 | : QObject(parent)
63 | , d_ptr(new ClientPrivate(this))
64 | {
65 | Q_D(Client);
66 | d->init(host, port, network);
67 | }
68 |
69 | QMQTT::Client::~Client()
70 | {
71 | }
72 |
73 | QHostAddress QMQTT::Client::host() const
74 | {
75 | Q_D(const Client);
76 | return d->host();
77 | }
78 |
79 | void QMQTT::Client::setHost(const QHostAddress& host)
80 | {
81 | Q_D(Client);
82 | d->setHost(host);
83 | }
84 |
85 | QString QMQTT::Client::hostName() const
86 | {
87 | Q_D(const Client);
88 | return d->hostName();
89 | }
90 |
91 | void QMQTT::Client::setHostName(const QString &hostName)
92 | {
93 | Q_D(Client);
94 | d->setHostName(hostName);
95 | }
96 |
97 | quint16 QMQTT::Client::port() const
98 | {
99 | Q_D(const Client);
100 | return d->port();
101 | }
102 |
103 | void QMQTT::Client::setPort(const quint16 port)
104 | {
105 | Q_D(Client);
106 | d->setPort(port);
107 | }
108 |
109 | QString QMQTT::Client::clientId() const
110 | {
111 | Q_D(const Client);
112 | return d->clientId();
113 | }
114 |
115 | void QMQTT::Client::setClientId(const QString& clientId)
116 | {
117 | Q_D(Client);
118 | d->setClientId(clientId);
119 | }
120 |
121 | QString QMQTT::Client::username() const
122 | {
123 | Q_D(const Client);
124 | return d->username();
125 | }
126 |
127 | void QMQTT::Client::setUsername(const QString& username)
128 | {
129 | Q_D(Client);
130 | d->setUsername(username);
131 | }
132 |
133 | QString QMQTT::Client::password() const
134 | {
135 | Q_D(const Client);
136 | return d->password();
137 | }
138 |
139 | void QMQTT::Client::setPassword(const QString& password)
140 | {
141 | Q_D(Client);
142 | d->setPassword(password);
143 | }
144 |
145 | quint16 QMQTT::Client::keepAlive() const
146 | {
147 | Q_D(const Client);
148 | return d->keepAlive();
149 | }
150 |
151 | void QMQTT::Client::setKeepAlive(const quint16 keepAlive)
152 | {
153 | Q_D(Client);
154 | d->setKeepAlive(keepAlive);
155 | }
156 |
157 | bool QMQTT::Client::cleanSession() const
158 | {
159 | Q_D(const Client);
160 | return d->cleanSession();
161 | }
162 |
163 | void QMQTT::Client::setCleanSession(const bool cleanSession)
164 | {
165 | Q_D(Client);
166 | d->setCleanSession(cleanSession);
167 | }
168 |
169 | bool QMQTT::Client::autoReconnect() const
170 | {
171 | Q_D(const Client);
172 | return d->autoReconnect();
173 | }
174 |
175 | void QMQTT::Client::setAutoReconnect(const bool value)
176 | {
177 | Q_D(Client);
178 | d->setAutoReconnect(value);
179 | }
180 |
181 | int QMQTT::Client::autoReconnectInterval() const
182 | {
183 | Q_D(const Client);
184 | return d->autoReconnectInterval();
185 | }
186 |
187 | void QMQTT::Client::setAutoReconnectInterval(const int autoReconnectInterval)
188 | {
189 | Q_D(Client);
190 | d->setAutoReconnectInterval(autoReconnectInterval);
191 | }
192 |
193 | QString QMQTT::Client::willTopic() const
194 | {
195 | Q_D(const Client);
196 | return d->willTopic();
197 | }
198 |
199 | void QMQTT::Client::setWillTopic(const QString& willTopic)
200 | {
201 | Q_D(Client);
202 | d->setWillTopic(willTopic);
203 | }
204 |
205 | quint8 QMQTT::Client::willQos() const
206 | {
207 | Q_D(const Client);
208 | return d->willQos();
209 | }
210 |
211 | void QMQTT::Client::setWillQos(const quint8 willQos)
212 | {
213 | Q_D(Client);
214 | d->setWillQos(willQos);
215 | }
216 |
217 | bool QMQTT::Client::willRetain() const
218 | {
219 | Q_D(const Client);
220 | return d->willRetain();
221 | }
222 |
223 | void QMQTT::Client::setWillRetain(const bool willRetain)
224 | {
225 | Q_D(Client);
226 | d->setWillRetain(willRetain);
227 | }
228 |
229 | QString QMQTT::Client::willMessage() const
230 | {
231 | Q_D(const Client);
232 | return d->willMessage();
233 | }
234 |
235 | void QMQTT::Client::setWillMessage(const QString& willMessage)
236 | {
237 | Q_D(Client);
238 | d->setWillMessage(willMessage);
239 | }
240 |
241 | QMQTT::ConnectionState QMQTT::Client::connectionState() const
242 | {
243 | Q_D(const Client);
244 | return d->connectionState();
245 | }
246 |
247 | bool QMQTT::Client::isConnectedToHost() const
248 | {
249 | Q_D(const Client);
250 | return d->isConnectedToHost();
251 | }
252 |
253 | void QMQTT::Client::connectToHost()
254 | {
255 | Q_D(Client);
256 | d->connectToHost();
257 | }
258 |
259 | void QMQTT::Client::onNetworkConnected()
260 | {
261 | Q_D(Client);
262 | d->onNetworkConnected();
263 | }
264 |
265 | quint16 QMQTT::Client::publish(const Message& message)
266 | {
267 | Q_D(Client);
268 | return d->publish(message);
269 | }
270 |
271 | quint16 QMQTT::Client::subscribe(const QString& topic, const quint8 qos)
272 | {
273 | Q_D(Client);
274 | return d->subscribe(topic, qos);
275 | }
276 |
277 | void QMQTT::Client::unsubscribe(const QString& topic)
278 | {
279 | Q_D(Client);
280 | d->unsubscribe(topic);
281 | }
282 |
283 | void QMQTT::Client::onTimerPingReq()
284 | {
285 | Q_D(Client);
286 | d->onTimerPingReq();
287 | }
288 |
289 | void QMQTT::Client::disconnectFromHost()
290 | {
291 | Q_D(Client);
292 | d->disconnectFromHost();
293 | }
294 |
295 | void QMQTT::Client::onNetworkReceived(const QMQTT::Frame& frame)
296 | {
297 | Q_D(Client);
298 | d->onNetworkReceived(frame);
299 | }
300 |
301 | void QMQTT::Client::onNetworkDisconnected()
302 | {
303 | Q_D(Client);
304 | d->onNetworkDisconnected();
305 | }
306 |
307 | void QMQTT::Client::onNetworkError(QAbstractSocket::SocketError error)
308 | {
309 | Q_D(Client);
310 | d->onNetworkError(error);
311 | }
312 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_client.h:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_client.h - qmqtt client header
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | *
10 | * * Redistributions of source code must retain the above copyright notice,
11 | * this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above copyright
13 | * notice, this list of conditions and the following disclaimer in the
14 | * documentation and/or other materials provided with the distribution.
15 | * * Neither the name of mqttc nor the names of its contributors may be used
16 | * to endorse or promote products derived from this software without
17 | * specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | * POSSIBILITY OF SUCH DAMAGE.
30 | *
31 | */
32 | #ifndef QMQTT_CLIENT_H
33 | #define QMQTT_CLIENT_H
34 |
35 | #if defined(QMQTT_LIBRARY)
36 | # define QMQTTSHARED_EXPORT Q_DECL_EXPORT
37 | #else
38 | # define QMQTTSHARED_EXPORT Q_DECL_IMPORT
39 | #endif
40 |
41 | #include
42 | #include
43 | #include
44 | #include
45 |
46 | namespace QMQTT {
47 |
48 | static const quint8 LIBRARY_VERSION_MAJOR = 0;
49 | static const quint8 LIBRARY_VERSION_MINOR = 3;
50 | static const quint8 LIBRARY_VERSION_REVISION = 1;
51 | //static const char* LIBRARY_VERSION = "0.3.1";
52 |
53 | static const quint8 PROTOCOL_VERSION_MAJOR = 3;
54 | static const quint8 PROTOCOL_VERSION_MINOR = 1;
55 | static const quint8 PROTOCOL_VERSION_REVISION = 1;
56 | //static const char* PROTOCOL_VERSION = "MQTT/3.1";
57 |
58 | enum ConnectionState
59 | {
60 | STATE_INIT = 0,
61 | STATE_CONNECTING,
62 | STATE_CONNECTED,
63 | STATE_DISCONNECTED
64 | };
65 |
66 | enum ClientError
67 | {
68 | UnknownError = 0,
69 | SocketConnectionRefusedError,
70 | SocketRemoteHostClosedError,
71 | SocketHostNotFoundError,
72 | SocketAccessError,
73 | SocketResourceError,
74 | SocketTimeoutError,
75 | SocketDatagramTooLargeError,
76 | SocketNetworkError,
77 | SocketAddressInUseError,
78 | SocketAddressNotAvailableError,
79 | SocketUnsupportedSocketOperationError,
80 | SocketUnfinishedSocketOperationError,
81 | SocketProxyAuthenticationRequiredError,
82 | SocketSslHandshakeFailedError,
83 | SocketProxyConnectionRefusedError,
84 | SocketProxyConnectionClosedError,
85 | SocketProxyConnectionTimeoutError,
86 | SocketProxyNotFoundError,
87 | SocketProxyProtocolError,
88 | SocketOperationError,
89 | SocketSslInternalError,
90 | SocketSslInvalidUserDataError,
91 | SocketTemporaryError
92 | };
93 |
94 | class ClientPrivate;
95 | class Message;
96 | class Frame;
97 | class NetworkInterface;
98 |
99 | class QMQTTSHARED_EXPORT Client : public QObject
100 | {
101 | Q_OBJECT
102 | Q_PROPERTY(quint16 _port READ port WRITE setPort)
103 | Q_PROPERTY(QHostAddress _host READ host WRITE setHost)
104 | Q_PROPERTY(QString _hostName READ hostName WRITE setHostName)
105 | Q_PROPERTY(QString _clientId READ clientId WRITE setClientId)
106 | Q_PROPERTY(QString _username READ username WRITE setUsername)
107 | Q_PROPERTY(QString _password READ password WRITE setPassword)
108 | Q_PROPERTY(quint16 _keepAlive READ keepAlive WRITE setKeepAlive)
109 | Q_PROPERTY(bool _autoReconnect READ autoReconnect WRITE setAutoReconnect)
110 | Q_PROPERTY(int _autoReconnectInterval READ autoReconnectInterval WRITE setAutoReconnectInterval)
111 | Q_PROPERTY(bool _cleanSession READ cleanSession WRITE setCleanSession)
112 | Q_PROPERTY(QString _willTopic READ willTopic WRITE setWillTopic)
113 | Q_PROPERTY(quint8 _willQos READ willQos WRITE setWillQos)
114 | Q_PROPERTY(bool _willRetain READ willRetain WRITE setWillRetain)
115 | Q_PROPERTY(QString _willMessage READ willMessage WRITE setWillMessage)
116 | Q_PROPERTY(QString _connectionState READ connectionState)
117 |
118 | public:
119 | Client(const QHostAddress& host = QHostAddress::LocalHost,
120 | const quint16 port = 1883,
121 | QObject* parent = NULL);
122 |
123 | Client(const QString& hostName,
124 | const quint16 port,
125 | const bool ssl,
126 | const bool ignoreSelfSigned,
127 | QObject* parent = NULL);
128 |
129 | // for testing purposes only
130 | Client(NetworkInterface* network,
131 | const QHostAddress& host = QHostAddress::LocalHost,
132 | const quint16 port = 1883,
133 | QObject* parent = NULL);
134 |
135 | virtual ~Client();
136 |
137 | QHostAddress host() const;
138 | QString hostName() const;
139 | quint16 port() const;
140 | QString clientId() const;
141 | QString username() const;
142 | QString password() const;
143 | quint16 keepAlive() const;
144 | bool cleanSession() const;
145 | bool autoReconnect() const;
146 | int autoReconnectInterval() const;
147 | ConnectionState connectionState() const;
148 | QString willTopic() const;
149 | quint8 willQos() const;
150 | bool willRetain() const;
151 | QString willMessage() const;
152 |
153 | bool isConnectedToHost() const;
154 |
155 | public slots:
156 | void setHost(const QHostAddress& host);
157 | void setHostName(const QString& hostName);
158 | void setPort(const quint16 port);
159 | void setClientId(const QString& clientId);
160 | void setUsername(const QString& username);
161 | void setPassword(const QString& password);
162 | void setKeepAlive(const quint16 keepAlive);
163 | void setCleanSession(const bool cleanSession);
164 | void setAutoReconnect(const bool value);
165 | void setAutoReconnectInterval(const int autoReconnectInterval);
166 | void setWillTopic(const QString& willTopic);
167 | void setWillQos(const quint8 willQos);
168 | void setWillRetain(const bool willRetain);
169 | void setWillMessage(const QString& willMessage);
170 |
171 | void connectToHost();
172 | void disconnectFromHost();
173 |
174 | quint16 subscribe(const QString& topic, const quint8 qos);
175 | void unsubscribe(const QString& topic);
176 |
177 | quint16 publish(const Message& message);
178 |
179 | signals:
180 | void connected();
181 | void disconnected();
182 | void error(const QMQTT::ClientError error);
183 |
184 | // todo: should emit on server suback (or is that only at specific QoS levels?)
185 | void subscribed(const QString& topic);
186 | // todo: should emit on server unsuback (or is that only at specific QoS levels?)
187 | void unsubscribed(const QString& topic);
188 | // todo: should emit on server puback (or is that only at specific QoS levels?)
189 | void published(const QMQTT::Message& message);
190 |
191 | void received(const QMQTT::Message& message);
192 |
193 | protected slots:
194 | void onNetworkConnected();
195 | void onNetworkDisconnected();
196 | void onNetworkReceived(const QMQTT::Frame& frame);
197 | void onTimerPingReq();
198 | void onNetworkError(QAbstractSocket::SocketError error);
199 |
200 | protected:
201 | QScopedPointer d_ptr;
202 |
203 | private:
204 | Q_DISABLE_COPY(Client)
205 | Q_DECLARE_PRIVATE(Client)
206 | };
207 |
208 | } // namespace QMQTT
209 |
210 | Q_DECLARE_METATYPE(QMQTT::ClientError);
211 |
212 | #endif // QMQTT_CLIENT_H
213 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_client_p.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_client_p.cpp - qmqtt client private
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | *
10 | * * Redistributions of source code must retain the above copyright notice,
11 | * this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above copyright
13 | * notice, this list of conditions and the following disclaimer in the
14 | * documentation and/or other materials provided with the distribution.
15 | * * Neither the name of mqttc nor the names of its contributors may be used
16 | * to endorse or promote products derived from this software without
17 | * specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | * POSSIBILITY OF SUCH DAMAGE.
30 | *
31 | */
32 |
33 | #include "qmqtt_client_p.h"
34 | #include "qmqtt_message.h"
35 | #include
36 | #include
37 |
38 | Q_LOGGING_CATEGORY(client, "qmqtt.client")
39 |
40 | static const quint8 QOS0 = 0x00;
41 | static const quint8 QOS1 = 0x01;
42 | static const quint8 QOS2 = 0x02;
43 |
44 | QMQTT::ClientPrivate::ClientPrivate(Client* qq_ptr)
45 | : _host(QHostAddress::LocalHost)
46 | , _port(1883)
47 | , _gmid(1)
48 | , _clientId(QUuid::createUuid().toString())
49 | , _cleanSession(false)
50 | , _keepAlive(300)
51 | , _connectionState(STATE_INIT)
52 | , _willQos(0)
53 | , _willRetain(false)
54 | , q_ptr(qq_ptr)
55 | {
56 | }
57 |
58 | QMQTT::ClientPrivate::~ClientPrivate()
59 | {
60 | }
61 |
62 | void QMQTT::ClientPrivate::init(const QHostAddress& host, const quint16 port, NetworkInterface* network)
63 | {
64 | Q_Q(Client);
65 |
66 | _host = host;
67 | _port = port;
68 | if(network == NULL)
69 | {
70 | _network.reset(new Network);
71 | }
72 | else
73 | {
74 | _network.reset(network);
75 | }
76 |
77 | initializeErrorHash();
78 |
79 | QObject::connect(&_timer, &QTimer::timeout, q, &Client::onTimerPingReq);
80 | QObject::connect(_network.data(), &Network::connected,
81 | q, &Client::onNetworkConnected);
82 | QObject::connect(_network.data(), &Network::disconnected,
83 | q, &Client::onNetworkDisconnected);
84 | QObject::connect(_network.data(), &Network::received,
85 | q, &Client::onNetworkReceived);
86 | QObject::connect(_network.data(), &Network::error,
87 | q, &Client::onNetworkError);
88 | }
89 |
90 | void QMQTT::ClientPrivate::init(const QString& hostName, const quint16 port, const bool ssl, const bool ignoreSelfSigned)
91 | {
92 | Q_Q(Client);
93 |
94 | _hostName = hostName;
95 | _port = port;
96 | if (ssl)
97 | {
98 | #ifndef QT_NO_SSL
99 | _network.reset(new SslNetwork(ignoreSelfSigned));
100 | #else
101 | Q_UNUSED(ignoreSelfSigned)
102 | qCritical() << "SSL not supported in this QT build";
103 | #endif // QT_NO_SSL
104 | }
105 | else
106 | {
107 | _network.reset(new Network);
108 | }
109 |
110 | initializeErrorHash();
111 |
112 | QObject::connect(&_timer, &QTimer::timeout, q, &Client::onTimerPingReq);
113 | QObject::connect(_network.data(), &Network::connected,
114 | q, &Client::onNetworkConnected);
115 | QObject::connect(_network.data(), &Network::disconnected,
116 | q, &Client::onNetworkDisconnected);
117 | QObject::connect(_network.data(), &Network::received,
118 | q, &Client::onNetworkReceived);
119 | QObject::connect(_network.data(), &Network::error,
120 | q, &Client::onNetworkError);
121 | }
122 |
123 | void QMQTT::ClientPrivate::initializeErrorHash()
124 | {
125 | _socketErrorHash.insert(QAbstractSocket::ConnectionRefusedError, SocketConnectionRefusedError);
126 | _socketErrorHash.insert(QAbstractSocket::RemoteHostClosedError, SocketRemoteHostClosedError);
127 | _socketErrorHash.insert(QAbstractSocket::HostNotFoundError, SocketHostNotFoundError);
128 | _socketErrorHash.insert(QAbstractSocket::SocketAccessError, SocketAccessError);
129 | _socketErrorHash.insert(QAbstractSocket::SocketResourceError, SocketResourceError);
130 | _socketErrorHash.insert(QAbstractSocket::SocketTimeoutError, SocketTimeoutError);
131 | _socketErrorHash.insert(QAbstractSocket::DatagramTooLargeError, SocketDatagramTooLargeError);
132 | _socketErrorHash.insert(QAbstractSocket::NetworkError, SocketNetworkError);
133 | _socketErrorHash.insert(QAbstractSocket::AddressInUseError, SocketAddressInUseError);
134 | _socketErrorHash.insert(QAbstractSocket::SocketAddressNotAvailableError, SocketAddressNotAvailableError);
135 | _socketErrorHash.insert(QAbstractSocket::UnsupportedSocketOperationError, SocketUnsupportedSocketOperationError);
136 | _socketErrorHash.insert(QAbstractSocket::UnfinishedSocketOperationError, SocketUnfinishedSocketOperationError);
137 | _socketErrorHash.insert(QAbstractSocket::ProxyAuthenticationRequiredError, SocketProxyAuthenticationRequiredError);
138 | _socketErrorHash.insert(QAbstractSocket::SslHandshakeFailedError, SocketSslHandshakeFailedError);
139 | _socketErrorHash.insert(QAbstractSocket::ProxyConnectionRefusedError, SocketProxyConnectionRefusedError);
140 | _socketErrorHash.insert(QAbstractSocket::ProxyConnectionClosedError, SocketProxyConnectionClosedError);
141 | _socketErrorHash.insert(QAbstractSocket::ProxyConnectionTimeoutError, SocketProxyConnectionTimeoutError);
142 | _socketErrorHash.insert(QAbstractSocket::ProxyNotFoundError, SocketProxyNotFoundError);
143 | _socketErrorHash.insert(QAbstractSocket::ProxyProtocolError, SocketProxyProtocolError);
144 | _socketErrorHash.insert(QAbstractSocket::OperationError, SocketOperationError);
145 | _socketErrorHash.insert(QAbstractSocket::SslInternalError, SocketSslInternalError);
146 | _socketErrorHash.insert(QAbstractSocket::SslInvalidUserDataError, SocketSslInvalidUserDataError);
147 | _socketErrorHash.insert(QAbstractSocket::TemporaryError, SocketTemporaryError);
148 | }
149 |
150 | void QMQTT::ClientPrivate::connectToHost()
151 | {
152 | if (_hostName.isEmpty())
153 | {
154 | _network->connectToHost(_host, _port);
155 | }
156 | else
157 | {
158 | _network->connectToHost(_hostName, _port);
159 | }
160 | }
161 |
162 | void QMQTT::ClientPrivate::onNetworkConnected()
163 | {
164 | Q_Q(Client);
165 | sendConnect();
166 | startKeepAlive();
167 | emit q->connected();
168 | }
169 |
170 | void QMQTT::ClientPrivate::sendConnect()
171 | {
172 | quint8 header = CONNECT;
173 | quint8 flags = 0;
174 |
175 | //header
176 | Frame frame(header);
177 |
178 | //flags
179 | flags = FLAG_CLEANSESS(flags, _cleanSession ? 1 : 0 );
180 | flags = FLAG_WILL(flags, willTopic().isEmpty() ? 0 : 1);
181 | if (!willTopic().isEmpty())
182 | {
183 | flags = FLAG_WILLQOS(flags, willQos());
184 | flags = FLAG_WILLRETAIN(flags, willRetain() ? 1 : 0);
185 | }
186 | if (!username().isEmpty())
187 | {
188 | flags = FLAG_USERNAME(flags, 1);
189 | }
190 | if (!password().isEmpty())
191 | {
192 | flags = FLAG_PASSWD(flags, 1);
193 | }
194 |
195 | //payload
196 | frame.writeString(QStringLiteral(PROTOCOL_MAGIC));
197 | frame.writeChar(PROTOCOL_VERSION_MAJOR);
198 | frame.writeChar(flags);
199 | frame.writeInt(_keepAlive);
200 | frame.writeString(_clientId);
201 | if(!willTopic().isEmpty())
202 | {
203 | frame.writeString(willTopic());
204 | if(!willMessage().isEmpty())
205 | {
206 | frame.writeString(willMessage());
207 | }
208 | }
209 | if (!_username.isEmpty())
210 | {
211 | frame.writeString(_username);
212 | }
213 | if (!_password.isEmpty())
214 | {
215 | frame.writeString(_password);
216 | }
217 | _network->sendFrame(frame);
218 | }
219 |
220 | quint16 QMQTT::ClientPrivate::sendPublish(const Message& msg)
221 | {
222 | Message message(msg);
223 |
224 | quint8 header = PUBLISH;
225 | header = SETRETAIN(header, message.retain() ? 1 : 0);
226 | header = SETQOS(header, message.qos());
227 | header = SETDUP(header, message.dup() ? 1 : 0);
228 | Frame frame(header);
229 | frame.writeString(message.topic());
230 | if(message.qos() > QOS0) {
231 | if(message.id() == 0) {
232 | message.setId(nextmid());
233 | }
234 | frame.writeInt(message.id());
235 | }
236 | if(!message.payload().isEmpty()) {
237 | frame.writeRawData(message.payload());
238 | }
239 | _network->sendFrame(frame);
240 | return message.id();
241 | }
242 |
243 | void QMQTT::ClientPrivate::sendPuback(const quint8 type, const quint16 mid)
244 | {
245 | Frame frame(type);
246 | frame.writeInt(mid);
247 | _network->sendFrame(frame);
248 | }
249 |
250 | quint16 QMQTT::ClientPrivate::sendSubscribe(const QString & topic, const quint8 qos)
251 | {
252 | quint16 mid = nextmid();
253 | Frame frame(SETQOS(SUBSCRIBE, QOS1));
254 | frame.writeInt(mid);
255 | frame.writeString(topic);
256 | frame.writeChar(qos);
257 | _network->sendFrame(frame);
258 | return mid;
259 | }
260 |
261 | quint16 QMQTT::ClientPrivate::sendUnsubscribe(const QString &topic)
262 | {
263 | quint16 mid = nextmid();
264 | Frame frame(SETQOS(UNSUBSCRIBE, QOS1));
265 | frame.writeInt(mid);
266 | frame.writeString(topic);
267 | _network->sendFrame(frame);
268 | return mid;
269 | }
270 |
271 | void QMQTT::ClientPrivate::onTimerPingReq()
272 | {
273 | Frame frame(PINGREQ);
274 | _network->sendFrame(frame);
275 | }
276 |
277 | void QMQTT::ClientPrivate::disconnectFromHost()
278 | {
279 | sendDisconnect();
280 | _network->disconnectFromHost();
281 | }
282 |
283 | void QMQTT::ClientPrivate::sendDisconnect()
284 | {
285 | Frame frame(DISCONNECT);
286 | _network->sendFrame(frame);
287 | }
288 |
289 | void QMQTT::ClientPrivate::startKeepAlive()
290 | {
291 | _timer.setInterval(_keepAlive*1000);
292 | _timer.start();
293 | }
294 |
295 | void QMQTT::ClientPrivate::stopKeepAlive()
296 | {
297 | _timer.stop();
298 | }
299 |
300 | quint16 QMQTT::ClientPrivate::nextmid()
301 | {
302 | return _gmid++;
303 | }
304 |
305 | quint16 QMQTT::ClientPrivate::publish(const Message& message)
306 | {
307 | Q_Q(Client);
308 | quint16 msgid = sendPublish(message);
309 | emit q->published(message);
310 | return msgid;
311 | }
312 |
313 | void QMQTT::ClientPrivate::puback(const quint8 type, const quint16 msgid)
314 | {
315 | sendPuback(type, msgid);
316 | }
317 |
318 | quint16 QMQTT::ClientPrivate::subscribe(const QString& topic, const quint8 qos)
319 | {
320 | Q_Q(Client);
321 | quint16 msgid = sendSubscribe(topic, qos);
322 | emit q->subscribed(topic);
323 | return msgid;
324 | }
325 |
326 | void QMQTT::ClientPrivate::unsubscribe(const QString& topic)
327 | {
328 | Q_Q(Client);
329 | sendUnsubscribe(topic);
330 | emit q->unsubscribed(topic);
331 | }
332 |
333 | void QMQTT::ClientPrivate::onNetworkDisconnected()
334 | {
335 | Q_Q(Client);
336 |
337 | stopKeepAlive();
338 | emit q->disconnected();
339 | }
340 |
341 | void QMQTT::ClientPrivate::onNetworkReceived(const QMQTT::Frame& frm)
342 | {
343 | QMQTT::Frame frame(frm);
344 | quint8 qos = 0;
345 | bool retain, dup;
346 | QString topic;
347 | quint16 mid = 0;
348 | quint8 header = frame.header();
349 | quint8 type = GETTYPE(header);
350 | Message message;
351 |
352 | switch(type)
353 | {
354 | case CONNACK:
355 | frame.readChar();
356 | handleConnack(frame.readChar());
357 | break;
358 | case PUBLISH:
359 | qos = GETQOS(header);
360 | retain = GETRETAIN(header);
361 | dup = GETDUP(header);
362 | topic = frame.readString();
363 | if( qos > QOS0) {
364 | mid = frame.readInt();
365 | }
366 | message.setId(mid);
367 | message.setTopic(topic);
368 | message.setPayload(frame.data());
369 | message.setQos(qos);
370 | message.setRetain(retain);
371 | message.setDup(dup);
372 | handlePublish(message);
373 | break;
374 | case PUBACK:
375 | case PUBREC:
376 | case PUBREL:
377 | case PUBCOMP:
378 | mid = frame.readInt();
379 | handlePuback(type, mid);
380 | break;
381 | case SUBACK:
382 | mid = frame.readInt();
383 | qos = frame.readChar();
384 | // todo: send a subscribed signal (only in certain cases? mid? qos?)
385 | break;
386 | case UNSUBACK:
387 | // todo: send an unsubscribed signal (only certain cases? mid?)
388 | break;
389 | case PINGRESP:
390 | // todo: I know I'm suppose to do something with this. Look at specifications.
391 | break;
392 | default:
393 | break;
394 | }
395 | }
396 |
397 | void QMQTT::ClientPrivate::handleConnack(const quint8 ack)
398 | {
399 | Q_UNUSED(ack);
400 | // todo: send connected signal
401 | }
402 |
403 | void QMQTT::ClientPrivate::handlePublish(const Message& message)
404 | {
405 | Q_Q(Client);
406 |
407 | if(message.qos() == QOS1)
408 | {
409 | sendPuback(PUBACK, message.id());
410 | }
411 | else if(message.qos() == QOS2)
412 | {
413 | sendPuback(PUBREC, message.id());
414 | }
415 | emit q->received(message);
416 | }
417 |
418 | void QMQTT::ClientPrivate::handlePuback(const quint8 type, const quint16 msgid)
419 | {
420 | if(type == PUBREC)
421 | {
422 | sendPuback(PUBREL, msgid);
423 | }
424 | else if (type == PUBREL)
425 | {
426 | sendPuback(PUBCOMP, msgid);
427 | }
428 | // todo: emit published signal (type? msgid?)
429 | }
430 |
431 | bool QMQTT::ClientPrivate::autoReconnect() const
432 | {
433 | return _network->autoReconnect();
434 | }
435 |
436 | void QMQTT::ClientPrivate::setAutoReconnect(const bool autoReconnect)
437 | {
438 | _network->setAutoReconnect(autoReconnect);
439 | }
440 |
441 | bool QMQTT::ClientPrivate::autoReconnectInterval() const
442 | {
443 | return _network->autoReconnectInterval();
444 | }
445 |
446 | void QMQTT::ClientPrivate::setAutoReconnectInterval(const int autoReconnectInterval)
447 | {
448 | _network->setAutoReconnectInterval(autoReconnectInterval);
449 | }
450 |
451 | bool QMQTT::ClientPrivate::isConnectedToHost() const
452 | {
453 | return _network->isConnectedToHost();
454 | }
455 |
456 | QMQTT::ConnectionState QMQTT::ClientPrivate::connectionState() const
457 | {
458 | return _connectionState;
459 | }
460 |
461 | void QMQTT::ClientPrivate::setCleanSession(const bool cleanSession)
462 | {
463 | _cleanSession = cleanSession;
464 | }
465 |
466 | bool QMQTT::ClientPrivate::cleanSession() const
467 | {
468 | return _cleanSession;
469 | }
470 |
471 | void QMQTT::ClientPrivate::setKeepAlive(const quint16 keepAlive)
472 | {
473 | _keepAlive = keepAlive;
474 | }
475 |
476 | quint16 QMQTT::ClientPrivate::keepAlive() const
477 | {
478 | return _keepAlive;
479 | }
480 |
481 | void QMQTT::ClientPrivate::setPassword(const QString& password)
482 | {
483 | _password = password;
484 | }
485 |
486 | QString QMQTT::ClientPrivate::password() const
487 | {
488 | return _password;
489 | }
490 |
491 | void QMQTT::ClientPrivate::setUsername(const QString& username)
492 | {
493 | _username = username;
494 | }
495 |
496 | QString QMQTT::ClientPrivate::username() const
497 | {
498 | return _username;
499 | }
500 |
501 | void QMQTT::ClientPrivate::setClientId(const QString& clientId)
502 | {
503 | if(clientId.isEmpty())
504 | {
505 | _clientId = QUuid::createUuid().toString();
506 | }
507 | else
508 | {
509 | _clientId = clientId;
510 | }
511 | }
512 |
513 | QString QMQTT::ClientPrivate::clientId() const
514 | {
515 | return _clientId;
516 | }
517 |
518 | void QMQTT::ClientPrivate::setPort(const quint16 port)
519 | {
520 | _port = port;
521 | }
522 |
523 | quint16 QMQTT::ClientPrivate::port() const
524 | {
525 | return _port;
526 | }
527 |
528 | void QMQTT::ClientPrivate::setHost(const QHostAddress& host)
529 | {
530 | _host = host;
531 | }
532 |
533 | QHostAddress QMQTT::ClientPrivate::host() const
534 | {
535 | return _host;
536 | }
537 |
538 | void QMQTT::ClientPrivate::setHostName(const QString& hostName)
539 | {
540 | _hostName = hostName;
541 | }
542 |
543 | QString QMQTT::ClientPrivate::hostName() const
544 | {
545 | return _hostName;
546 | }
547 |
548 | QString QMQTT::ClientPrivate::willTopic() const
549 | {
550 | return _willTopic;
551 | }
552 |
553 | void QMQTT::ClientPrivate::setWillTopic(const QString& willTopic)
554 | {
555 | _willTopic = willTopic;
556 | }
557 |
558 | quint8 QMQTT::ClientPrivate::willQos() const
559 | {
560 | return _willQos;
561 | }
562 |
563 | void QMQTT::ClientPrivate::setWillQos(const quint8 willQos)
564 | {
565 | _willQos = willQos;
566 | }
567 |
568 | bool QMQTT::ClientPrivate::willRetain() const
569 | {
570 | return _willRetain;
571 | }
572 |
573 | void QMQTT::ClientPrivate::setWillRetain(const bool willRetain)
574 | {
575 | _willRetain = willRetain;
576 | }
577 |
578 | QString QMQTT::ClientPrivate::willMessage() const
579 | {
580 | return _willMessage;
581 | }
582 |
583 | void QMQTT::ClientPrivate::setWillMessage(const QString& willMessage)
584 | {
585 | _willMessage = willMessage;
586 | }
587 |
588 | void QMQTT::ClientPrivate::onNetworkError(QAbstractSocket::SocketError socketError)
589 | {
590 | Q_Q(Client);
591 | emit q->error(_socketErrorHash.value(socketError, UnknownError));
592 | }
593 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_client_p.h:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_client_p.h - qmqtt client private header
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | *
10 | * * Redistributions of source code must retain the above copyright notice,
11 | * this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above copyright
13 | * notice, this list of conditions and the following disclaimer in the
14 | * documentation and/or other materials provided with the distribution.
15 | * * Neither the name of mqttc nor the names of its contributors may be used
16 | * to endorse or promote products derived from this software without
17 | * specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | * POSSIBILITY OF SUCH DAMAGE.
30 | *
31 | */
32 | #ifndef QMQTT_CLIENT_P_H
33 | #define QMQTT_CLIENT_P_H
34 |
35 | #include "qmqtt_client.h"
36 | #include "qmqtt_client_p.h"
37 | #include "qmqtt_network.h"
38 | #include "qmqtt_ssl_network.h"
39 | #include
40 |
41 | namespace QMQTT {
42 |
43 | class ClientPrivate
44 | {
45 | public:
46 | ClientPrivate(Client* qq_ptr);
47 | ~ClientPrivate();
48 |
49 | void init(const QHostAddress& host, const quint16 port, NetworkInterface* network = NULL);
50 | void init(const QString& hostName, const quint16 port, const bool ssl, const bool ignoreSelfSigned);
51 |
52 | QHostAddress _host;
53 | QString _hostName;
54 | quint16 _port;
55 | quint16 _gmid;
56 | QString _clientId;
57 | QString _username;
58 | QString _password;
59 | bool _cleanSession;
60 | quint16 _keepAlive;
61 | ConnectionState _connectionState;
62 | QScopedPointer _network;
63 | QTimer _timer;
64 | QString _willTopic;
65 | quint8 _willQos;
66 | bool _willRetain;
67 | QString _willMessage;
68 | QHash _socketErrorHash;
69 |
70 | Client* const q_ptr;
71 |
72 | quint16 nextmid();
73 | void connectToHost();
74 | void sendConnect();
75 | void onTimerPingReq();
76 | quint16 sendUnsubscribe(const QString &topic);
77 | quint16 sendSubscribe(const QString &topic, const quint8 qos);
78 | quint16 sendPublish(const Message &msg);
79 | void sendPuback(const quint8 type, const quint16 mid);
80 | void sendDisconnect();
81 | void disconnectFromHost();
82 | void startKeepAlive();
83 | void stopKeepAlive();
84 | void onNetworkConnected();
85 | void onNetworkDisconnected();
86 | quint16 publish(const Message& message);
87 | void puback(const quint8 type, const quint16 msgid);
88 | quint16 subscribe(const QString& topic, const quint8 qos);
89 | void unsubscribe(const QString& topic);
90 | void onNetworkReceived(const QMQTT::Frame& frame);
91 | void handleConnack(const quint8 ack);
92 | void handlePublish(const Message& message);
93 | void handlePuback(const quint8 type, const quint16 msgid);
94 | bool autoReconnect() const;
95 | void setAutoReconnect(const bool autoReconnect);
96 | bool autoReconnectInterval() const;
97 | void setAutoReconnectInterval(const int autoReconnectInterval);
98 | bool isConnectedToHost() const;
99 | QMQTT::ConnectionState connectionState() const;
100 | void setCleanSession(const bool cleanSession);
101 | bool cleanSession() const;
102 | void setKeepAlive(const quint16 keepAlive);
103 | quint16 keepAlive() const;
104 | void setPassword(const QString& password);
105 | QString password() const;
106 | void setUsername(const QString& username);
107 | QString username() const;
108 | void setClientId(const QString& clientId);
109 | QString clientId() const;
110 | void setPort(const quint16 port);
111 | quint16 port() const;
112 | void setHost(const QHostAddress& host);
113 | QHostAddress host() const;
114 | void setHostName(const QString& hostName);
115 | QString hostName() const;
116 | void setWillTopic(const QString& willTopic);
117 | void setWillQos(const quint8 willQos);
118 | void setWillRetain(const bool willRetain);
119 | void setWillMessage(const QString& willMessage);
120 | QString willTopic() const;
121 | quint8 willQos() const;
122 | bool willRetain() const;
123 | QString willMessage() const;
124 | void initializeErrorHash();
125 | void onNetworkError(QAbstractSocket::SocketError error);
126 |
127 | Q_DECLARE_PUBLIC(Client)
128 | };
129 |
130 | } // namespace QMQTT
131 |
132 | #endif // QMQTT_CLIENT_P_H
133 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_frame.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_frame.cpp - qmqtt frame
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | *
10 | * * Redistributions of source code must retain the above copyright notice,
11 | * this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above copyright
13 | * notice, this list of conditions and the following disclaimer in the
14 | * documentation and/or other materials provided with the distribution.
15 | * * Neither the name of mqttc nor the names of its contributors may be used
16 | * to endorse or promote products derived from this software without
17 | * specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | * POSSIBILITY OF SUCH DAMAGE.
30 | *
31 | */
32 | #include
33 | #include
34 | #include "qmqtt_frame.h"
35 |
36 | namespace QMQTT {
37 |
38 | Q_LOGGING_CATEGORY(frame, "qmqtt.frame")
39 |
40 | Frame::Frame()
41 | : _header(0)
42 | , _data(QByteArray())
43 | {
44 | }
45 |
46 | Frame::Frame(const quint8 header)
47 | : _header(header)
48 | , _data(QByteArray())
49 | {
50 | }
51 |
52 | Frame::Frame(const quint8 header, const QByteArray &data)
53 | : _header(header)
54 | , _data(data)
55 | {
56 | }
57 |
58 | Frame::Frame(const Frame& other)
59 | {
60 | _header = other._header;
61 | _data = other._data;
62 | }
63 |
64 | Frame& Frame::operator=(const Frame& other)
65 | {
66 | _header = other._header;
67 | _data = other._data;
68 | return *this;
69 | }
70 |
71 | bool Frame::operator==(const Frame& other) const
72 | {
73 | return _header == other._header
74 | && _data == other._data;
75 | }
76 |
77 |
78 | Frame::~Frame()
79 | {
80 | }
81 |
82 | quint8 Frame::header() const
83 | {
84 | return _header;
85 | }
86 |
87 | QByteArray Frame::data() const
88 | {
89 | return _data;
90 | }
91 |
92 | quint8 Frame::readChar()
93 | {
94 | char c = _data.at(0);
95 | _data.remove(0, 1);
96 | return c;
97 | }
98 |
99 | quint16 Frame::readInt()
100 | {
101 | char msb = _data.at(0);
102 | char lsb = _data.at(1);
103 | _data.remove(0, 2);
104 | return (msb << 8) + lsb;
105 | }
106 |
107 | QString Frame::readString()
108 | {
109 | quint16 len = readInt();
110 | QString s(_data.left(len));
111 | _data.remove(0, len);
112 | return s;
113 | }
114 |
115 | void Frame::writeInt(const quint16 i)
116 | {
117 | _data.append(MSB(i));
118 | _data.append(LSB(i));
119 | }
120 |
121 | void Frame::writeString(const QString &string)
122 | {
123 | QByteArray data = string.toUtf8();
124 | if (data.size() > (int)USHRT_MAX)
125 | {
126 | qCritical("qmqtt: String size bigger than %u bytes, truncate it!", USHRT_MAX);
127 | data.resize(USHRT_MAX);
128 | }
129 | writeInt(data.size());
130 | _data.append(data);
131 | }
132 |
133 | void Frame::writeChar(const quint8 c)
134 | {
135 | _data.append(c);
136 | }
137 |
138 | void Frame::writeRawData(const QByteArray &data)
139 | {
140 | _data.append(data);
141 | }
142 |
143 | void Frame::write(QDataStream &stream)
144 | {
145 | QByteArray lenbuf;
146 |
147 | if (!encodeLength(lenbuf, _data.size()))
148 | {
149 | qCritical("qmqtt: Control packet bigger than 256 MB, dropped!");
150 | return;
151 | }
152 |
153 | stream << (quint8)_header;
154 | if(_data.size() == 0) {
155 | stream << (quint8)0;
156 | return;
157 | }
158 | if (stream.writeRawData(lenbuf.data(), lenbuf.size()) != lenbuf.size())
159 | {
160 | qCritical("qmqtt: Control packet write error!");
161 | return;
162 | }
163 | if (stream.writeRawData(_data.data(), _data.size()) != _data.size())
164 | {
165 | qCritical("qmqtt: Control packet write error!");
166 | }
167 | }
168 |
169 | bool Frame::encodeLength(QByteArray &lenbuf, int length)
170 | {
171 | lenbuf.clear();
172 | quint8 d;
173 | do {
174 | d = length % 128;
175 | length /= 128;
176 | if (length > 0) {
177 | d |= 0x80;
178 | }
179 | lenbuf.append(d);
180 | } while (length > 0);
181 |
182 | return lenbuf.size() <= 4;
183 | }
184 |
185 | } // namespace QMQTT
186 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_frame.h:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_frame.h - qmqtt frame heaer
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | *
10 | * * Redistributions of source code must retain the above copyright notice,
11 | * this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above copyright
13 | * notice, this list of conditions and the following disclaimer in the
14 | * documentation and/or other materials provided with the distribution.
15 | * * Neither the name of mqttc nor the names of its contributors may be used
16 | * to endorse or promote products derived from this software without
17 | * specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | * POSSIBILITY OF SUCH DAMAGE.
30 | *
31 | */
32 | #ifndef QMQTT_FRAME_H
33 | #define QMQTT_FRAME_H
34 |
35 | #include
36 |
37 | #define PROTOCOL_MAGIC "MQIsdp"
38 | #define RANDOM_CLIENT_PREFIX "QMQTT-"
39 |
40 | #define CONNECT 0x10
41 | #define CONNACK 0x20
42 | #define PUBLISH 0x30
43 | #define PUBACK 0x40
44 | #define PUBREC 0x50
45 | #define PUBREL 0x60
46 | #define PUBCOMP 0x70
47 | #define SUBSCRIBE 0x80
48 | #define SUBACK 0x90
49 | #define UNSUBSCRIBE 0xA0
50 | #define UNSUBACK 0xB0
51 | #define PINGREQ 0xC0
52 | #define PINGRESP 0xD0
53 | #define DISCONNECT 0xE0
54 |
55 | #define LSB(A) (quint8)(A & 0x00FF)
56 | #define MSB(A) (quint8)((A & 0xFF00) >> 8)
57 |
58 | /*
59 | |--------------------------------------
60 | | 7 6 5 4 | 3 | 2 1 | 0 |
61 | | Type | DUP flag | QoS | RETAIN |
62 | |--------------------------------------
63 | */
64 | #define GETTYPE(HDR) (HDR & 0xF0)
65 | #define SETQOS(HDR, Q) (HDR | ((Q) << 1))
66 | #define GETQOS(HDR) ((HDR & 0x06) >> 1)
67 | #define SETDUP(HDR, D) (HDR | ((D) << 3))
68 | #define GETDUP(HDR) ((HDR & 0x08) >> 3)
69 | #define SETRETAIN(HDR, R) (HDR | (R))
70 | #define GETRETAIN(HDR) (HDR & 0x01)
71 |
72 | /*
73 | |----------------------------------------------------------------------------------
74 | | 7 | 6 | 5 | 4 3 | 2 | 1 | 0 |
75 | | username | password | willretain | willqos | willflag | cleansession | reserved |
76 | |----------------------------------------------------------------------------------
77 | */
78 | #define FLAG_CLEANSESS(F, C) (F | ((C) << 1))
79 | #define FLAG_WILL(F, W) (F | ((W) << 2))
80 | #define FLAG_WILLQOS(F, Q) (F | ((Q) << 3))
81 | #define FLAG_WILLRETAIN(F, R) (F | ((R) << 5))
82 | #define FLAG_PASSWD(F, P) (F | ((P) << 6))
83 | #define FLAG_USERNAME(F, U) (F | ((U) << 7))
84 |
85 | namespace QMQTT {
86 |
87 | class Frame
88 | {
89 | public:
90 | explicit Frame();
91 | explicit Frame(const quint8 header);
92 | explicit Frame(const quint8 header, const QByteArray &data);
93 | virtual ~Frame();
94 |
95 | Frame(const Frame& other);
96 | Frame& operator=(const Frame& other);
97 |
98 | bool operator==(const Frame& other) const;
99 |
100 | quint8 header() const;
101 | QByteArray data() const;
102 |
103 | quint16 readInt();
104 | quint8 readChar();
105 | QString readString();
106 |
107 | void writeInt(const quint16 i);
108 | void writeChar(const quint8 c);
109 | void writeString(const QString &string);
110 | void writeRawData(const QByteArray &data);
111 |
112 | //TODO: FIXME LATER
113 | void write(QDataStream &stream);
114 | bool encodeLength(QByteArray &lenbuf, int length);
115 |
116 | private:
117 | quint8 _header;
118 | QByteArray _data;
119 | };
120 |
121 | } // namespace QMQTT
122 |
123 | Q_DECLARE_METATYPE(QMQTT::Frame);
124 |
125 | #endif // QMQTT_FRAME_H
126 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_global.h:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_global.h - qmqtt libray global
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | *
10 | * * Redistributions of source code must retain the above copyright notice,
11 | * this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above copyright
13 | * notice, this list of conditions and the following disclaimer in the
14 | * documentation and/or other materials provided with the distribution.
15 | * * Neither the name of mqttc nor the names of its contributors may be used
16 | * to endorse or promote products derived from this software without
17 | * specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | * POSSIBILITY OF SUCH DAMAGE.
30 | *
31 | */
32 | #ifndef QMQTT_GLOBAL_H
33 | #define QMQTT_GLOBAL_H
34 |
35 | #if defined(QMQTT_LIBRARY)
36 | # define QMQTTSHARED_EXPORT Q_DECL_EXPORT
37 | #else
38 | # define QMQTTSHARED_EXPORT Q_DECL_IMPORT
39 | #endif
40 |
41 | #endif // QMQTT_GLOBAL_H
42 |
43 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_message.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_message.cpp - qmqtt message
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | *
10 | * * Redistributions of source code must retain the above copyright notice,
11 | * this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above copyright
13 | * notice, this list of conditions and the following disclaimer in the
14 | * documentation and/or other materials provided with the distribution.
15 | * * Neither the name of mqttc nor the names of its contributors may be used
16 | * to endorse or promote products derived from this software without
17 | * specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | * POSSIBILITY OF SUCH DAMAGE.
30 | *
31 | */
32 | #include "qmqtt_message.h"
33 | #include "qmqtt_message_p.h"
34 |
35 | QMQTT::Message::Message()
36 | : d_ptr(new MessagePrivate)
37 | {
38 | Q_D(Message);
39 | d->init(0, QString(), QByteArray(), 0, false, false);
40 | }
41 |
42 | QMQTT::Message::Message(const quint16 id, const QString &topic, const QByteArray &payload,
43 | const quint8 qos, const bool retain, const bool dup)
44 | : d_ptr(new MessagePrivate)
45 | {
46 | Q_D(Message);
47 | d->init(id, topic, payload, qos, retain, dup);
48 | }
49 |
50 | QMQTT::Message::~Message()
51 | {
52 | }
53 |
54 | QMQTT::Message::Message(const Message& other)
55 | : d_ptr(new MessagePrivate(*(other.d_ptr)))
56 | {
57 | }
58 |
59 | QMQTT::Message& QMQTT::Message::operator=(const Message& other)
60 | {
61 | Q_D(Message);
62 | *d = *(other.d_ptr);
63 | return *this;
64 | }
65 |
66 | bool QMQTT::Message::operator==(const Message& other) const
67 | {
68 | Q_D(const Message);
69 | return *d == *(other.d_ptr);
70 | }
71 |
72 | quint16 QMQTT::Message::id() const
73 | {
74 | Q_D(const Message);
75 | return d->id();
76 | }
77 |
78 | void QMQTT::Message::setId(const quint16 id)
79 | {
80 | Q_D(Message);
81 | d->setId(id);
82 | }
83 |
84 | quint8 QMQTT::Message::qos() const
85 | {
86 | Q_D(const Message);
87 | return d->qos();
88 | }
89 |
90 | void QMQTT::Message::setQos(const quint8 qos)
91 | {
92 | Q_D(Message);
93 | d->setQos(qos);
94 | }
95 |
96 | bool QMQTT::Message::retain() const
97 | {
98 | Q_D(const Message);
99 | return d->retain();
100 | }
101 |
102 | void QMQTT::Message::setRetain(const bool retain)
103 | {
104 | Q_D(Message);
105 | d->setRetain(retain);
106 | }
107 |
108 | bool QMQTT::Message::dup() const
109 | {
110 | Q_D(const Message);
111 | return d->dup();
112 | }
113 |
114 | void QMQTT::Message::setDup(const bool dup)
115 | {
116 | Q_D(Message);
117 | d->setDup(dup);
118 | }
119 |
120 | QString QMQTT::Message::topic() const
121 | {
122 | Q_D(const Message);
123 | return d->topic();
124 | }
125 |
126 | void QMQTT::Message::setTopic(const QString& topic)
127 | {
128 | Q_D(Message);
129 | d->setTopic(topic);
130 | }
131 |
132 | QByteArray QMQTT::Message::payload() const
133 | {
134 | Q_D(const Message);
135 | return d->payload();
136 | }
137 |
138 | void QMQTT::Message::setPayload(const QByteArray& payload)
139 | {
140 | Q_D(Message);
141 | d->setPayload(payload);
142 | }
143 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_message.h:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_message.h - qmqtt message header
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | *
10 | * * Redistributions of source code must retain the above copyright notice,
11 | * this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above copyright
13 | * notice, this list of conditions and the following disclaimer in the
14 | * documentation and/or other materials provided with the distribution.
15 | * * Neither the name of mqttc nor the names of its contributors may be used
16 | * to endorse or promote products derived from this software without
17 | * specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | * POSSIBILITY OF SUCH DAMAGE.
30 | *
31 | */
32 | #ifndef QMQTT_MESSAGE_H
33 | #define QMQTT_MESSAGE_H
34 |
35 | #if defined(QMQTT_LIBRARY)
36 | # define QMQTTSHARED_EXPORT Q_DECL_EXPORT
37 | #else
38 | # define QMQTTSHARED_EXPORT Q_DECL_IMPORT
39 | #endif
40 |
41 | #include
42 | #include
43 |
44 | namespace QMQTT {
45 |
46 | class MessagePrivate;
47 |
48 | class QMQTTSHARED_EXPORT Message
49 | {
50 | public:
51 | explicit Message();
52 | explicit Message(const quint16 id, const QString &topic, const QByteArray &payload,
53 | const quint8 qos = 0, const bool retain = false, const bool dup = false);
54 | virtual ~Message();
55 |
56 | Message(const Message& other);
57 | Message& operator=(const Message& other);
58 |
59 | bool operator==(const Message& other) const;
60 |
61 | quint16 id() const;
62 | void setId(const quint16 id);
63 |
64 | quint8 qos() const;
65 | void setQos(const quint8 qos);
66 |
67 | bool retain() const;
68 | void setRetain(const bool retain);
69 |
70 | bool dup() const;
71 | void setDup(const bool dup);
72 |
73 | QString topic() const;
74 | void setTopic(const QString &topic);
75 |
76 | QByteArray payload() const;
77 | void setPayload(const QByteArray & payload);
78 |
79 | protected:
80 | QScopedPointer d_ptr;
81 |
82 | private:
83 | Q_DECLARE_PRIVATE(Message)
84 | };
85 |
86 | } // namespace QMQTT
87 |
88 | Q_DECLARE_METATYPE(QMQTT::Message);
89 |
90 | #endif // QMQTT_MESSAGE_H
91 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_message_p.cpp:
--------------------------------------------------------------------------------
1 | #include "qmqtt_message_p.h"
2 |
3 | QMQTT::MessagePrivate::MessagePrivate()
4 | : _id(0)
5 | , _qos(0)
6 | , _retain(false)
7 | , _dup(false)
8 | {
9 | }
10 |
11 | QMQTT::MessagePrivate::~MessagePrivate()
12 | {
13 | }
14 |
15 | void QMQTT::MessagePrivate::init(const quint16 id, const QString& topic,
16 | const QByteArray& payload, const quint8 qos,
17 | const bool retain, const bool dup)
18 | {
19 | _id = id;
20 | _topic = topic;
21 | _payload = payload;
22 | _qos = qos;
23 | _retain = retain;
24 | _dup = dup;
25 | }
26 |
27 | QMQTT::MessagePrivate::MessagePrivate(const MessagePrivate& other)
28 | {
29 | _id = other._id;
30 | _topic = other._topic;
31 | _payload = other._payload;
32 | _qos = other._qos;
33 | _retain = other._retain;
34 | _dup = other._dup;
35 | }
36 |
37 | QMQTT::MessagePrivate& QMQTT::MessagePrivate::operator=(const MessagePrivate& other)
38 | {
39 | if(this != &other)
40 | {
41 | _id = other._id;
42 | _topic = other._topic;
43 | _payload = other._payload;
44 | _qos = other._qos;
45 | _retain = other._retain;
46 | _dup = other._dup;
47 | }
48 | return *this;
49 | }
50 |
51 | bool QMQTT::MessagePrivate::operator==(const MessagePrivate& other) const
52 | {
53 | return _id == other._id
54 | && _topic == other._topic
55 | && _payload == other._payload
56 | && _qos == other._qos
57 | && _retain == other._retain
58 | && _dup == other._dup;
59 | }
60 |
61 | quint16 QMQTT::MessagePrivate::id() const
62 | {
63 | return _id;
64 | }
65 |
66 | void QMQTT::MessagePrivate::setId(const quint16 id)
67 | {
68 | _id = id;
69 | }
70 |
71 | quint8 QMQTT::MessagePrivate::qos() const
72 | {
73 | return _qos;
74 | }
75 |
76 | void QMQTT::MessagePrivate::setQos(const quint8 qos)
77 | {
78 | _qos = qos;
79 | }
80 |
81 | bool QMQTT::MessagePrivate::retain() const
82 | {
83 | return _retain;
84 | }
85 |
86 | void QMQTT::MessagePrivate::setRetain(const bool retain)
87 | {
88 | _retain = retain;
89 | }
90 |
91 | bool QMQTT::MessagePrivate::dup() const
92 | {
93 | return _dup;
94 | }
95 | void QMQTT::MessagePrivate::setDup(const bool dup)
96 | {
97 | _dup =dup;
98 | }
99 |
100 | QString QMQTT::MessagePrivate::topic() const
101 | {
102 | return _topic;
103 | }
104 |
105 | void QMQTT::MessagePrivate::setTopic(const QString& topic)
106 | {
107 | _topic = topic;
108 | }
109 |
110 | QByteArray QMQTT::MessagePrivate::payload() const
111 | {
112 | return _payload;
113 | }
114 |
115 | void QMQTT::MessagePrivate::setPayload(const QByteArray& payload)
116 | {
117 | _payload = payload;
118 | }
119 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_message_p.h:
--------------------------------------------------------------------------------
1 | #ifndef QMQTT_MESSAGE_P_H
2 | #define QMQTT_MESSAGE_P_H
3 |
4 | #include
5 | #include
6 |
7 | namespace QMQTT {
8 |
9 | class MessagePrivate
10 | {
11 | public:
12 | explicit MessagePrivate();
13 | virtual ~MessagePrivate();
14 |
15 | void init(const quint16 id, const QString &topic, const QByteArray &payload,
16 | const quint8 qos, const bool retain, const bool dup);
17 |
18 | MessagePrivate(const MessagePrivate& other);
19 | MessagePrivate& operator=(const MessagePrivate& other);
20 | bool operator==(const MessagePrivate& other) const;
21 |
22 | quint16 id() const;
23 | void setId(const quint16 id);
24 | quint8 qos() const;
25 | void setQos(const quint8 qos);
26 | bool retain() const;
27 | void setRetain(const bool retain);
28 | bool dup() const;
29 | void setDup(const bool dup);
30 | QString topic() const;
31 | void setTopic(const QString& topic);
32 | QByteArray payload() const;
33 | void setPayload(const QByteArray& payload);
34 |
35 | quint16 _id;
36 | QString _topic;
37 | QByteArray _payload;
38 | quint8 _qos;
39 | bool _retain;
40 | bool _dup;
41 | };
42 |
43 | } // namespace QMQTT
44 |
45 | #endif // QMQTT_MESSAGE_P_H
46 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_network.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_network.cpp - qmqtt network
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | *
10 | * * Redistributions of source code must retain the above copyright notice,
11 | * this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above copyright
13 | * notice, this list of conditions and the following disclaimer in the
14 | * documentation and/or other materials provided with the distribution.
15 | * * Neither the name of mqttc nor the names of its contributors may be used
16 | * to endorse or promote products derived from this software without
17 | * specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | * POSSIBILITY OF SUCH DAMAGE.
30 | *
31 | */
32 | #include
33 | #include "qmqtt_network.h"
34 | #include "qmqtt_socket.h"
35 | #include "qmqtt_timer.h"
36 |
37 | const QHostAddress DEFAULT_HOST = QHostAddress::LocalHost;
38 | const quint16 DEFAULT_PORT = 1883;
39 | const bool DEFAULT_AUTORECONNECT = false;
40 | const int DEFAULT_AUTORECONNECT_INTERVAL_MS = 5000;
41 |
42 | QMQTT::Network::Network(QObject* parent)
43 | : NetworkInterface(parent)
44 | , _port(DEFAULT_PORT)
45 | , _host(DEFAULT_HOST)
46 | , _autoReconnect(DEFAULT_AUTORECONNECT)
47 | , _autoReconnectInterval(DEFAULT_AUTORECONNECT_INTERVAL_MS)
48 | , _bytesRemaining(0)
49 | , _socket(new QMQTT::Socket)
50 | , _autoReconnectTimer(new QMQTT::Timer)
51 | {
52 | initialize();
53 | }
54 |
55 | QMQTT::Network::Network(SocketInterface* socketInterface, TimerInterface* timerInterface,
56 | QObject* parent)
57 | : NetworkInterface(parent)
58 | , _port(DEFAULT_PORT)
59 | , _host(DEFAULT_HOST)
60 | , _autoReconnect(DEFAULT_AUTORECONNECT)
61 | , _autoReconnectInterval(DEFAULT_AUTORECONNECT_INTERVAL_MS)
62 | , _bytesRemaining(0)
63 | , _socket(socketInterface)
64 | , _autoReconnectTimer(timerInterface)
65 | {
66 | initialize();
67 | }
68 |
69 | void QMQTT::Network::initialize()
70 | {
71 | _socket->setParent(this);
72 | _autoReconnectTimer->setParent(this);
73 | _autoReconnectTimer->setSingleShot(true);
74 | _autoReconnectTimer->setInterval(_autoReconnectInterval);
75 |
76 | QObject::connect(_socket, &SocketInterface::connected, this, &Network::connected);
77 | QObject::connect(_socket, &SocketInterface::disconnected, this, &Network::onDisconnected);
78 | QObject::connect(_socket->ioDevice(), &QIODevice::readyRead, this, &Network::onSocketReadReady);
79 | QObject::connect(
80 | _autoReconnectTimer, &TimerInterface::timeout,
81 | this, static_cast(&Network::connectToHost));
82 | QObject::connect(_socket,
83 | static_cast(&SocketInterface::error),
84 | this, &Network::onSocketError);
85 | }
86 |
87 | QMQTT::Network::~Network()
88 | {
89 | }
90 |
91 | bool QMQTT::Network::isConnectedToHost() const
92 | {
93 | return _socket->state() == QAbstractSocket::ConnectedState;
94 | }
95 |
96 | void QMQTT::Network::connectToHost(const QHostAddress& host, const quint16 port)
97 | {
98 | _host = host;
99 | _port = port;
100 | connectToHost();
101 | }
102 |
103 | void QMQTT::Network::connectToHost(const QString& hostName, const quint16 port)
104 | {
105 | _hostName = hostName;
106 | _port = port;
107 | connectToHost();
108 | }
109 |
110 | void QMQTT::Network::connectToHost()
111 | {
112 | _bytesRemaining = 0;
113 | if (_hostName.isEmpty())
114 | {
115 | _socket->connectToHost(_host, _port);
116 | }
117 | else
118 | {
119 | _socket->connectToHost(_hostName, _port);
120 | }
121 | }
122 |
123 | void QMQTT::Network::onSocketError(QAbstractSocket::SocketError socketError)
124 | {
125 | emit error(socketError);
126 | if(_autoReconnect)
127 | {
128 | _autoReconnectTimer->start();
129 | }
130 | }
131 |
132 | void QMQTT::Network::sendFrame(Frame& frame)
133 | {
134 | if(_socket->state() == QAbstractSocket::ConnectedState)
135 | {
136 | QDataStream out(_socket->ioDevice());
137 | frame.write(out);
138 | }
139 | }
140 |
141 | void QMQTT::Network::disconnectFromHost()
142 | {
143 | _socket->disconnectFromHost();
144 | }
145 |
146 | QAbstractSocket::SocketState QMQTT::Network::state() const
147 | {
148 | return _socket->state();
149 | }
150 |
151 | bool QMQTT::Network::autoReconnect() const
152 | {
153 | return _autoReconnect;
154 | }
155 |
156 | void QMQTT::Network::setAutoReconnect(const bool autoReconnect)
157 | {
158 | _autoReconnect = autoReconnect;
159 | }
160 |
161 | int QMQTT::Network::autoReconnectInterval() const
162 | {
163 | return _autoReconnectInterval;
164 | }
165 |
166 | void QMQTT::Network::setAutoReconnectInterval(const int autoReconnectInterval)
167 | {
168 | _autoReconnectInterval = autoReconnectInterval;
169 | }
170 |
171 | void QMQTT::Network::onSocketReadReady()
172 | {
173 | QIODevice *ioDevice = _socket->ioDevice();
174 | while(!ioDevice->atEnd())
175 | {
176 | if(_bytesRemaining == 0)
177 | {
178 | if (!ioDevice->getChar(reinterpret_cast(&_header)))
179 | {
180 | // malformed packet
181 | emit error(QAbstractSocket::OperationError);
182 | ioDevice->close();
183 | return;
184 | }
185 |
186 | _bytesRemaining = readRemainingLength();
187 | if (_bytesRemaining < 0)
188 | {
189 | // malformed remaining length
190 | emit error(QAbstractSocket::OperationError);
191 | ioDevice->close();
192 | return;
193 | }
194 | }
195 |
196 | QByteArray data = ioDevice->read(_bytesRemaining);
197 | _buffer.append(data);
198 | _bytesRemaining -= data.size();
199 |
200 | if(_bytesRemaining == 0)
201 | {
202 | Frame frame(_header, _buffer);
203 | _buffer.clear();
204 | emit received(frame);
205 | }
206 | }
207 | }
208 |
209 | int QMQTT::Network::readRemainingLength()
210 | {
211 | quint8 byte = 0;
212 | int length = 0;
213 | int multiplier = 1;
214 | QIODevice *ioDevice = _socket->ioDevice();
215 | do {
216 | if (!ioDevice->getChar(reinterpret_cast(&byte)))
217 | return -1;
218 | length += (byte & 127) * multiplier;
219 | multiplier *= 128;
220 | if (multiplier > 128*128*128)
221 | return -1;
222 | } while ((byte & 128) != 0);
223 |
224 | return length;
225 | }
226 |
227 | void QMQTT::Network::onDisconnected()
228 | {
229 | emit disconnected();
230 | if(_autoReconnect)
231 | {
232 | _autoReconnectTimer->start();
233 | }
234 | }
235 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_network.h:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_network.h - qmqtt network header
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | *
10 | * * Redistributions of source code must retain the above copyright notice,
11 | * this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above copyright
13 | * notice, this list of conditions and the following disclaimer in the
14 | * documentation and/or other materials provided with the distribution.
15 | * * Neither the name of mqttc nor the names of its contributors may be used
16 | * to endorse or promote products derived from this software without
17 | * specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | * POSSIBILITY OF SUCH DAMAGE.
30 | *
31 | */
32 | #ifndef QMQTT_NETWORK_H
33 | #define QMQTT_NETWORK_H
34 |
35 | #include "qmqtt_networkinterface.h"
36 | #include "qmqtt_frame.h"
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 | #include
43 |
44 | namespace QMQTT {
45 |
46 | class SocketInterface;
47 | class TimerInterface;
48 |
49 | class Network : public NetworkInterface
50 | {
51 | Q_OBJECT
52 |
53 | public:
54 | Network(QObject* parent = NULL);
55 | Network(SocketInterface* socketInterface, TimerInterface* timerInterface,
56 | QObject* parent = NULL);
57 | ~Network();
58 |
59 | void sendFrame(Frame& frame);
60 | bool isConnectedToHost() const;
61 | bool autoReconnect() const;
62 | void setAutoReconnect(const bool autoReconnect);
63 | QAbstractSocket::SocketState state() const;
64 | int autoReconnectInterval() const;
65 | void setAutoReconnectInterval(const int autoReconnectInterval);
66 |
67 | public slots:
68 | void connectToHost(const QHostAddress& host, const quint16 port);
69 | void connectToHost(const QString& hostName, const quint16 port);
70 | void disconnectFromHost();
71 |
72 | protected slots:
73 | void onSocketError(QAbstractSocket::SocketError socketError);
74 |
75 | protected:
76 | void initialize();
77 | int readRemainingLength();
78 |
79 | quint16 _port;
80 | QHostAddress _host;
81 | QString _hostName;
82 | QByteArray _buffer;
83 | bool _autoReconnect;
84 | int _autoReconnectInterval;
85 | int _bytesRemaining;
86 | quint8 _header;
87 | SocketInterface* _socket;
88 | TimerInterface* _autoReconnectTimer;
89 |
90 | protected slots:
91 | void onSocketReadReady();
92 | void onDisconnected();
93 | void connectToHost();
94 |
95 | private:
96 | Q_DISABLE_COPY(Network)
97 | };
98 |
99 | } // namespace QMQTT
100 |
101 | #endif // QMQTT_NETWORK_H
102 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_networkinterface.h:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_network.h - qmqtt network header
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | *
10 | * * Redistributions of source code must retain the above copyright notice,
11 | * this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above copyright
13 | * notice, this list of conditions and the following disclaimer in the
14 | * documentation and/or other materials provided with the distribution.
15 | * * Neither the name of mqttc nor the names of its contributors may be used
16 | * to endorse or promote products derived from this software without
17 | * specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | * POSSIBILITY OF SUCH DAMAGE.
30 | *
31 | */
32 | #ifndef QMQTT_NETWORK_INTERFACE_H
33 | #define QMQTT_NETWORK_INTERFACE_H
34 |
35 | #include "qmqtt_frame.h"
36 | #include
37 | #include
38 | #include
39 |
40 | namespace QMQTT {
41 |
42 | class 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(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 |
57 | public slots:
58 | virtual void connectToHost(const QHostAddress& host, const quint16 port) = 0;
59 | virtual void connectToHost(const QString& hostName, const quint16 port) = 0;
60 | virtual void disconnectFromHost() = 0;
61 |
62 | signals:
63 | void connected();
64 | void disconnected();
65 | void received(const QMQTT::Frame& frame);
66 | void error(QAbstractSocket::SocketError error);
67 | };
68 |
69 | } // namespace QMQTT
70 |
71 | #endif // QMQTT_NETWORK_INTERFACE_H
72 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_routedmessage.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_router.cpp - qmqtt router
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * Router added by Niklas Wulf
6 | * All rights reserved.
7 | *
8 | * Redistribution and use in source and binary forms, with or without
9 | * modification, are permitted provided that the following conditions are met:
10 | *
11 | * * Redistributions of source code must retain the above copyright notice,
12 | * this list of conditions and the following disclaimer.
13 | * * Redistributions in binary form must reproduce the above copyright
14 | * notice, this list of conditions and the following disclaimer in the
15 | * documentation and/or other materials provided with the distribution.
16 | * * Neither the name of mqttc nor the names of its contributors may be used
17 | * to endorse or promote products derived from this software without
18 | * specific prior written permission.
19 | *
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 | * POSSIBILITY OF SUCH DAMAGE.
31 | *
32 | */
33 | #include "qmqtt_routedmessage.h"
34 |
35 | namespace QMQTT {
36 |
37 | RoutedMessage::RoutedMessage(const Message &message) : _message(message)
38 | {
39 | }
40 |
41 | const Message &RoutedMessage::message() const
42 | {
43 | return _message;
44 | }
45 |
46 | QHash RoutedMessage::parameters() const
47 | {
48 | return _parameters;
49 | }
50 |
51 | } // namespace QMQTT
52 |
53 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_routedmessage.h:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_router.h - qmqtt router
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * Router added by Niklas Wulf
6 | * All rights reserved.
7 | *
8 | * Redistribution and use in source and binary forms, with or without
9 | * modification, are permitted provided that the following conditions are met:
10 | *
11 | * * Redistributions of source code must retain the above copyright notice,
12 | * this list of conditions and the following disclaimer.
13 | * * Redistributions in binary form must reproduce the above copyright
14 | * notice, this list of conditions and the following disclaimer in the
15 | * documentation and/or other materials provided with the distribution.
16 | * * Neither the name of mqttc nor the names of its contributors may be used
17 | * to endorse or promote products derived from this software without
18 | * specific prior written permission.
19 | *
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 | * POSSIBILITY OF SUCH DAMAGE.
31 | *
32 | */
33 | #ifndef QMQTT_ROUTEDMESSAGE_H
34 | #define QMQTT_ROUTEDMESSAGE_H
35 |
36 | #include
37 | #include
38 | #include "qmqtt_message.h"
39 |
40 | namespace QMQTT {
41 |
42 | class Message;
43 |
44 | class RoutedMessage
45 | {
46 | public:
47 | explicit RoutedMessage(const Message &message);
48 |
49 | const Message &message() const;
50 | QHash parameters() const;
51 |
52 | private:
53 | friend class RouteSubscription;
54 |
55 | Message _message;
56 | QHash _parameters;
57 | };
58 |
59 | } // namespace QMQTT
60 |
61 | #endif // QMQTT_ROUTEDMESSAGE_H
62 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_router.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_router.cpp - qmqtt router
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * Router added by Niklas Wulf
6 | * All rights reserved.
7 | *
8 | * Redistribution and use in source and binary forms, with or without
9 | * modification, are permitted provided that the following conditions are met:
10 | *
11 | * * Redistributions of source code must retain the above copyright notice,
12 | * this list of conditions and the following disclaimer.
13 | * * Redistributions in binary form must reproduce the above copyright
14 | * notice, this list of conditions and the following disclaimer in the
15 | * documentation and/or other materials provided with the distribution.
16 | * * Neither the name of mqttc nor the names of its contributors may be used
17 | * to endorse or promote products derived from this software without
18 | * specific prior written permission.
19 | *
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 | * POSSIBILITY OF SUCH DAMAGE.
31 | *
32 | */
33 | #include "qmqtt_router.h"
34 |
35 | #include "qmqtt_client.h"
36 | #include "qmqtt_routesubscription.h"
37 | #include
38 |
39 | namespace QMQTT {
40 |
41 | Q_LOGGING_CATEGORY(router, "qmqtt.router")
42 |
43 | Router::Router(Client *parent) : QObject(parent), _client(parent)
44 | {
45 | }
46 |
47 | RouteSubscription *Router::subscribe(const QString &route)
48 | {
49 | RouteSubscription *subscription = new RouteSubscription(this);
50 | subscription->setRoute(route);
51 | _client->subscribe(subscription->_topic, 0);
52 | connect(_client, &Client::received, subscription, &RouteSubscription::routeMessage);
53 | return subscription;
54 | }
55 |
56 | } // namespace QMQTT
57 |
58 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_router.h:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_router.h - qmqtt router
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * Router added by Niklas Wulf
6 | * All rights reserved.
7 | *
8 | * Redistribution and use in source and binary forms, with or without
9 | * modification, are permitted provided that the following conditions are met:
10 | *
11 | * * Redistributions of source code must retain the above copyright notice,
12 | * this list of conditions and the following disclaimer.
13 | * * Redistributions in binary form must reproduce the above copyright
14 | * notice, this list of conditions and the following disclaimer in the
15 | * documentation and/or other materials provided with the distribution.
16 | * * Neither the name of mqttc nor the names of its contributors may be used
17 | * to endorse or promote products derived from this software without
18 | * specific prior written permission.
19 | *
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 | * POSSIBILITY OF SUCH DAMAGE.
31 | *
32 | */
33 | #ifndef QMQTT_ROUTER_H
34 | #define QMQTT_ROUTER_H
35 |
36 | #include
37 |
38 | namespace QMQTT {
39 |
40 | class Client;
41 | class RouteSubscription;
42 |
43 | class Router : public QObject
44 | {
45 | Q_OBJECT
46 | public:
47 | explicit Router(Client *parent = 0);
48 |
49 | RouteSubscription *subscribe(const QString &route);
50 |
51 | private:
52 | Client *_client;
53 | };
54 |
55 | } // namespace QMQTT
56 |
57 | #endif // QMQTT_ROUTER_H
58 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_routesubscription.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_router.cpp - qmqtt router
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * Router added by Niklas Wulf
6 | * All rights reserved.
7 | *
8 | * Redistribution and use in source and binary forms, with or without
9 | * modification, are permitted provided that the following conditions are met:
10 | *
11 | * * Redistributions of source code must retain the above copyright notice,
12 | * this list of conditions and the following disclaimer.
13 | * * Redistributions in binary form must reproduce the above copyright
14 | * notice, this list of conditions and the following disclaimer in the
15 | * documentation and/or other materials provided with the distribution.
16 | * * Neither the name of mqttc nor the names of its contributors may be used
17 | * to endorse or promote products derived from this software without
18 | * specific prior written permission.
19 | *
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 | * POSSIBILITY OF SUCH DAMAGE.
31 | *
32 | */
33 | #include "qmqtt_routesubscription.h"
34 |
35 | #include "qmqtt_message.h"
36 | #include "qmqtt_router.h"
37 | #include "qmqtt_routedmessage.h"
38 | #include
39 |
40 | namespace QMQTT {
41 |
42 | Q_LOGGING_CATEGORY(routerSubscription, "qmqtt.routersubscription")
43 |
44 | RouteSubscription::RouteSubscription(Router *parent) : QObject(parent)
45 | {
46 | }
47 |
48 | QString RouteSubscription::route() const
49 | {
50 | return _topic;
51 | }
52 |
53 | void RouteSubscription::setRoute(const QString &route)
54 | {
55 | QRegularExpression parameterNamesRegExp("\\:([a-zA-Z0-9]+)"); // note how names must not contain dashes or underscores
56 |
57 | // Remove paramter names to get the actual topic "route"
58 | QString topic = route;
59 | topic.replace(parameterNamesRegExp, "");
60 |
61 | // Remove the MQTT wildcards to get a regular expression, which matches the parameters
62 | QString parameterRegExp = route;
63 | parameterRegExp
64 | .replace("+", "")
65 | .replace(parameterNamesRegExp, "([a-zA-Z0-9_-]+)") // note how parameter values may contain dashes or underscores
66 | .replace("#", "")
67 | .replace("$", "\\$");
68 |
69 | // Extract the parameter names
70 | QRegularExpressionMatchIterator it = parameterNamesRegExp.globalMatch(route);
71 | QStringList names;
72 | while(it.hasNext()) {
73 | QRegularExpressionMatch match = it.next();
74 | QString parameterName = match.captured(1);
75 | names << parameterName;
76 | }
77 |
78 | _topic = topic;
79 | _parameterNames = names;
80 | _regularExpression = QRegularExpression(parameterRegExp);
81 | }
82 |
83 | void RouteSubscription::routeMessage(const Message &message)
84 | {
85 | QString topic = message.topic();
86 | QRegularExpressionMatch match = _regularExpression.match(topic);
87 | if(!match.hasMatch()) {
88 | return;
89 | }
90 |
91 | RoutedMessage routedMessage(message);
92 |
93 | for(int i = 0, c = _parameterNames.size(); i < c; ++i) {
94 | QString name = _parameterNames.at(i);
95 | QString value = match.captured(i + 1);
96 |
97 | routedMessage._parameters.insert(name, value);
98 | }
99 |
100 | emit received(routedMessage);
101 | }
102 |
103 | } // namespace QMQTT
104 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_routesubscription.h:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_router.h - qmqtt router
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * Router added by Niklas Wulf
6 | * All rights reserved.
7 | *
8 | * Redistribution and use in source and binary forms, with or without
9 | * modification, are permitted provided that the following conditions are met:
10 | *
11 | * * Redistributions of source code must retain the above copyright notice,
12 | * this list of conditions and the following disclaimer.
13 | * * Redistributions in binary form must reproduce the above copyright
14 | * notice, this list of conditions and the following disclaimer in the
15 | * documentation and/or other materials provided with the distribution.
16 | * * Neither the name of mqttc nor the names of its contributors may be used
17 | * to endorse or promote products derived from this software without
18 | * specific prior written permission.
19 | *
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 | * POSSIBILITY OF SUCH DAMAGE.
31 | *
32 | */
33 | #ifndef QMQTT_ROUTESUBSCRIPTION_H
34 | #define QMQTT_ROUTESUBSCRIPTION_H
35 |
36 | #include
37 | #include
38 |
39 | namespace QMQTT {
40 |
41 | class Message;
42 | class RoutedMessage;
43 | class Router;
44 |
45 | class RouteSubscription : public QObject
46 | {
47 | Q_OBJECT
48 | public:
49 | QString route() const;
50 |
51 | signals:
52 | void received(const RoutedMessage &message);
53 |
54 | private slots:
55 | void routeMessage(const Message &message);
56 |
57 | private:
58 | friend class Router;
59 | explicit RouteSubscription(Router *parent = 0);
60 | void setRoute(const QString &route);
61 |
62 | QString _topic;
63 | QRegularExpression _regularExpression;
64 | QStringList _parameterNames;
65 | };
66 |
67 | } // namespace QMQTT
68 |
69 | #endif // QMQTT_ROUTESUBSCRIPTION_H
70 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_socket.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_socket.cpp - qmqtt socket
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | *
10 | * * Redistributions of source code must retain the above copyright notice,
11 | * this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above copyright
13 | * notice, this list of conditions and the following disclaimer in the
14 | * documentation and/or other materials provided with the distribution.
15 | * * Neither the name of mqttc nor the names of its contributors may be used
16 | * to endorse or promote products derived from this software without
17 | * specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | * POSSIBILITY OF SUCH DAMAGE.
30 | *
31 | */
32 | #include "qmqtt_socket.h"
33 | #include
34 |
35 | QMQTT::Socket::Socket(QObject* parent)
36 | : SocketInterface(parent)
37 | , _socket(new QTcpSocket)
38 | {
39 | connect(_socket.data(), &QTcpSocket::connected, this, &SocketInterface::connected);
40 | connect(_socket.data(), &QTcpSocket::disconnected, this, &SocketInterface::disconnected);
41 | connect(_socket.data(),
42 | static_cast(&QTcpSocket::error),
43 | this,
44 | static_cast(&SocketInterface::error));
45 | }
46 |
47 | QMQTT::Socket::~Socket()
48 | {
49 | }
50 |
51 | QIODevice *QMQTT::Socket::ioDevice()
52 | {
53 | return _socket.data();
54 | }
55 |
56 | void QMQTT::Socket::connectToHost(const QHostAddress& address, quint16 port)
57 | {
58 | _socket->connectToHost(address, port);
59 | }
60 |
61 | void QMQTT::Socket::connectToHost(const QString& hostName, quint16 port)
62 | {
63 | _socket->connectToHost(hostName, port);
64 | }
65 |
66 | void QMQTT::Socket::disconnectFromHost()
67 | {
68 | _socket->disconnectFromHost();
69 | }
70 |
71 | QAbstractSocket::SocketState QMQTT::Socket::state() const
72 | {
73 | return _socket->state();
74 | }
75 |
76 | QAbstractSocket::SocketError QMQTT::Socket::error() const
77 | {
78 | return _socket->error();
79 | }
80 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_socket.h:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_socket.h - qmqtt socket header
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | *
10 | * * Redistributions of source code must retain the above copyright notice,
11 | * this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above copyright
13 | * notice, this list of conditions and the following disclaimer in the
14 | * documentation and/or other materials provided with the distribution.
15 | * * Neither the name of mqttc nor the names of its contributors may be used
16 | * to endorse or promote products derived from this software without
17 | * specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | * POSSIBILITY OF SUCH DAMAGE.
30 | *
31 | */
32 | #ifndef QMQTT_SOCKET_H
33 | #define QMQTT_SOCKET_H
34 |
35 | #include "qmqtt_socketinterface.h"
36 | #include
37 | #include
38 |
39 | class QTcpSocket;
40 |
41 | namespace QMQTT
42 | {
43 |
44 | class Socket : public SocketInterface
45 | {
46 | Q_OBJECT
47 | public:
48 | explicit Socket(QObject* parent = NULL);
49 | virtual ~Socket();
50 |
51 | virtual QIODevice *ioDevice();
52 | void connectToHost(const QHostAddress& address, quint16 port);
53 | void connectToHost(const QString& hostName, quint16 port);
54 | void disconnectFromHost();
55 | QAbstractSocket::SocketState state() const;
56 | QAbstractSocket::SocketError error() const;
57 |
58 | protected:
59 | QScopedPointer _socket;
60 | };
61 |
62 | }
63 |
64 | #endif // QMQTT_SOCKET_H
65 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_socketinterface.h:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_socketinterface.h - qmqtt socket interface header
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | *
10 | * * Redistributions of source code must retain the above copyright notice,
11 | * this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above copyright
13 | * notice, this list of conditions and the following disclaimer in the
14 | * documentation and/or other materials provided with the distribution.
15 | * * Neither the name of mqttc nor the names of its contributors may be used
16 | * to endorse or promote products derived from this software without
17 | * specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | * POSSIBILITY OF SUCH DAMAGE.
30 | *
31 | */
32 | #ifndef QMQTT_SOCKET_INTERFACE_H
33 | #define QMQTT_SOCKET_INTERFACE_H
34 |
35 | #include
36 | #include
37 |
38 | namespace QMQTT
39 | {
40 |
41 | class SocketInterface : public QObject
42 | {
43 | Q_OBJECT
44 | public:
45 | explicit SocketInterface(QObject* parent = NULL) : QObject(parent) {}
46 | virtual ~SocketInterface() {}
47 |
48 | virtual QIODevice *ioDevice() = 0;
49 | virtual void connectToHost(const QHostAddress& address, quint16 port) = 0;
50 | virtual void connectToHost(const QString& hostName, quint16 port) = 0;
51 | virtual void disconnectFromHost() = 0;
52 | virtual QAbstractSocket::SocketState state() const = 0;
53 | virtual QAbstractSocket::SocketError error() const = 0;
54 |
55 | signals:
56 | void connected();
57 | void disconnected();
58 | void error(QAbstractSocket::SocketError socketError);
59 | };
60 |
61 | }
62 |
63 | #endif // QMQTT_SOCKET_INTERFACE_H
64 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_ssl_network.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_ssl_network.cpp - qmqtt SSL network
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * Copyright (c) 2016 Matthias Dieter Wallnöfer
6 | * All rights reserved.
7 | *
8 | * Redistribution and use in source and binary forms, with or without
9 | * modification, are permitted provided that the following conditions are met:
10 | *
11 | * * Redistributions of source code must retain the above copyright notice,
12 | * this list of conditions and the following disclaimer.
13 | * * Redistributions in binary form must reproduce the above copyright
14 | * notice, this list of conditions and the following disclaimer in the
15 | * documentation and/or other materials provided with the distribution.
16 | * * Neither the name of mqttc nor the names of its contributors may be used
17 | * to endorse or promote products derived from this software without
18 | * specific prior written permission.
19 | *
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 | * POSSIBILITY OF SUCH DAMAGE.
31 | *
32 | */
33 | #include
34 | #include "qmqtt_ssl_network.h"
35 | #include "qmqtt_ssl_socket.h"
36 | #include "qmqtt_timer.h"
37 |
38 | #ifndef QT_NO_SSL
39 |
40 | const QString DEFAULT_HOST_NAME = QStringLiteral("localhost");
41 | const quint16 DEFAULT_PORT = 8883;
42 | const bool DEFAULT_AUTORECONNECT = false;
43 | const int DEFAULT_AUTORECONNECT_INTERVAL_MS = 5000;
44 |
45 | QMQTT::SslNetwork::SslNetwork(bool ignoreSelfSigned, QObject* parent)
46 | : NetworkInterface(parent)
47 | , _port(DEFAULT_PORT)
48 | , _hostName(DEFAULT_HOST_NAME)
49 | , _autoReconnect(DEFAULT_AUTORECONNECT)
50 | , _autoReconnectInterval(DEFAULT_AUTORECONNECT_INTERVAL_MS)
51 | , _bytesRemaining(0)
52 | , _socket(new QMQTT::SslSocket(ignoreSelfSigned))
53 | , _autoReconnectTimer(new QMQTT::Timer)
54 | {
55 | initialize();
56 | }
57 |
58 | QMQTT::SslNetwork::SslNetwork(SocketInterface* socketInterface, TimerInterface* timerInterface,
59 | QObject* parent)
60 | : NetworkInterface(parent)
61 | , _port(DEFAULT_PORT)
62 | , _hostName(DEFAULT_HOST_NAME)
63 | , _autoReconnect(DEFAULT_AUTORECONNECT)
64 | , _autoReconnectInterval(DEFAULT_AUTORECONNECT_INTERVAL_MS)
65 | , _bytesRemaining(0)
66 | , _socket(socketInterface)
67 | , _autoReconnectTimer(timerInterface)
68 | {
69 | initialize();
70 | }
71 |
72 | void QMQTT::SslNetwork::initialize()
73 | {
74 | _socket->setParent(this);
75 | _autoReconnectTimer->setParent(this);
76 | _autoReconnectTimer->setSingleShot(true);
77 | _autoReconnectTimer->setInterval(_autoReconnectInterval);
78 |
79 | QObject::connect(_socket, &SocketInterface::connected, this, &SslNetwork::connected);
80 | QObject::connect(_socket, &SocketInterface::disconnected, this, &SslNetwork::onDisconnected);
81 | QObject::connect(_socket->ioDevice(), &QIODevice::readyRead, this, &SslNetwork::onSocketReadReady);
82 | QObject::connect(
83 | _autoReconnectTimer, &TimerInterface::timeout,
84 | this, static_cast(&SslNetwork::connectToHost));
85 | QObject::connect(_socket,
86 | static_cast(&SocketInterface::error),
87 | this, &SslNetwork::onSocketError);
88 | }
89 |
90 | QMQTT::SslNetwork::~SslNetwork()
91 | {
92 | }
93 |
94 | bool QMQTT::SslNetwork::isConnectedToHost() const
95 | {
96 | return _socket->state() == QAbstractSocket::ConnectedState;
97 | }
98 |
99 | void QMQTT::SslNetwork::connectToHost(const QHostAddress& host, const quint16 port)
100 | {
101 | Q_UNUSED(host);
102 | Q_UNUSED(port);
103 |
104 | qCritical("qmqtt: SSL does not work with host addresses!");
105 | emit error(QAbstractSocket::ConnectionRefusedError);
106 | }
107 |
108 | void QMQTT::SslNetwork::connectToHost(const QString& hostName, const quint16 port)
109 | {
110 | _hostName = hostName;
111 | _port = port;
112 | connectToHost();
113 | }
114 |
115 | void QMQTT::SslNetwork::connectToHost()
116 | {
117 | _bytesRemaining = 0;
118 | _socket->connectToHost(_hostName, _port);
119 | }
120 |
121 | void QMQTT::SslNetwork::onSocketError(QAbstractSocket::SocketError socketError)
122 | {
123 | emit error(socketError);
124 | if(_autoReconnect)
125 | {
126 | _autoReconnectTimer->start();
127 | }
128 | }
129 |
130 | void QMQTT::SslNetwork::sendFrame(Frame& frame)
131 | {
132 | if(_socket->state() == QAbstractSocket::ConnectedState)
133 | {
134 | QDataStream out(_socket->ioDevice());
135 | frame.write(out);
136 | }
137 | }
138 |
139 | void QMQTT::SslNetwork::disconnectFromHost()
140 | {
141 | _socket->disconnectFromHost();
142 | }
143 |
144 | QAbstractSocket::SocketState QMQTT::SslNetwork::state() const
145 | {
146 | return _socket->state();
147 | }
148 |
149 | bool QMQTT::SslNetwork::autoReconnect() const
150 | {
151 | return _autoReconnect;
152 | }
153 |
154 | void QMQTT::SslNetwork::setAutoReconnect(const bool autoReconnect)
155 | {
156 | _autoReconnect = autoReconnect;
157 | }
158 |
159 | int QMQTT::SslNetwork::autoReconnectInterval() const
160 | {
161 | return _autoReconnectInterval;
162 | }
163 |
164 | void QMQTT::SslNetwork::setAutoReconnectInterval(const int autoReconnectInterval)
165 | {
166 | _autoReconnectInterval = autoReconnectInterval;
167 | }
168 |
169 | void QMQTT::SslNetwork::onSocketReadReady()
170 | {
171 | QIODevice *ioDevice = _socket->ioDevice();
172 | while(!ioDevice->atEnd())
173 | {
174 | if(_bytesRemaining == 0)
175 | {
176 | if (!ioDevice->getChar(reinterpret_cast(&_header)))
177 | {
178 | // malformed packet
179 | emit error(QAbstractSocket::OperationError);
180 | ioDevice->close();
181 | return;
182 | }
183 |
184 | _bytesRemaining = readRemainingLength();
185 | if (_bytesRemaining < 0)
186 | {
187 | // malformed remaining length
188 | emit error(QAbstractSocket::OperationError);
189 | ioDevice->close();
190 | return;
191 | }
192 | }
193 |
194 | QByteArray data = ioDevice->read(_bytesRemaining);
195 | _buffer.append(data);
196 | _bytesRemaining -= data.size();
197 |
198 | if(_bytesRemaining == 0)
199 | {
200 | Frame frame(_header, _buffer);
201 | _buffer.clear();
202 | emit received(frame);
203 | }
204 | }
205 | }
206 |
207 | int QMQTT::SslNetwork::readRemainingLength()
208 | {
209 | quint8 byte = 0;
210 | int length = 0;
211 | int multiplier = 1;
212 | QIODevice *ioDevice = _socket->ioDevice();
213 | do {
214 | if (!ioDevice->getChar(reinterpret_cast(&byte)))
215 | return -1;
216 | length += (byte & 127) * multiplier;
217 | multiplier *= 128;
218 | if (multiplier > 128*128*128)
219 | return -1;
220 | } while ((byte & 128) != 0);
221 |
222 | return length;
223 | }
224 |
225 | void QMQTT::SslNetwork::onDisconnected()
226 | {
227 | emit disconnected();
228 | if(_autoReconnect)
229 | {
230 | _autoReconnectTimer->start();
231 | }
232 | }
233 |
234 | #endif // QT_NO_SSL
235 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_ssl_network.h:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_ssl_network.h - qmqtt SSL network header
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * Copyright (c) 2016 Matthias Dieter Wallnöfer
6 | * All rights reserved.
7 | *
8 | * Redistribution and use in source and binary forms, with or without
9 | * modification, are permitted provided that the following conditions are met:
10 | *
11 | * * Redistributions of source code must retain the above copyright notice,
12 | * this list of conditions and the following disclaimer.
13 | * * Redistributions in binary form must reproduce the above copyright
14 | * notice, this list of conditions and the following disclaimer in the
15 | * documentation and/or other materials provided with the distribution.
16 | * * Neither the name of mqttc nor the names of its contributors may be used
17 | * to endorse or promote products derived from this software without
18 | * specific prior written permission.
19 | *
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 | * POSSIBILITY OF SUCH DAMAGE.
31 | *
32 | */
33 | #ifndef QMQTT_SSL_NETWORK_H
34 | #define QMQTT_SSL_NETWORK_H
35 |
36 | #include "qmqtt_networkinterface.h"
37 | #include "qmqtt_frame.h"
38 | #include
39 | #include
40 | #include
41 | #include
42 | #include
43 | #include
44 |
45 | #ifndef QT_NO_SSL
46 |
47 | namespace QMQTT {
48 |
49 | class SocketInterface;
50 | class TimerInterface;
51 |
52 | class SslNetwork : public NetworkInterface
53 | {
54 | Q_OBJECT
55 |
56 | public:
57 | SslNetwork(bool ignoreSelfSigned, QObject* parent = NULL);
58 | SslNetwork(SocketInterface* socketInterface, TimerInterface* timerInterface,
59 | QObject* parent = NULL);
60 | ~SslNetwork();
61 |
62 | void sendFrame(Frame& frame);
63 | bool isConnectedToHost() const;
64 | bool autoReconnect() const;
65 | void setAutoReconnect(const bool autoReconnect);
66 | QAbstractSocket::SocketState state() const;
67 | int autoReconnectInterval() const;
68 | void setAutoReconnectInterval(const int autoReconnectInterval);
69 |
70 | public slots:
71 | void connectToHost(const QHostAddress& host, const quint16 port);
72 | void connectToHost(const QString& hostName, const quint16 port);
73 | void disconnectFromHost();
74 |
75 | protected slots:
76 | void onSocketError(QAbstractSocket::SocketError socketError);
77 |
78 | protected:
79 | void initialize();
80 | int readRemainingLength();
81 |
82 | quint16 _port;
83 | QString _hostName;
84 | QByteArray _buffer;
85 | bool _autoReconnect;
86 | int _autoReconnectInterval;
87 | int _bytesRemaining;
88 | quint8 _header;
89 | SocketInterface* _socket;
90 | TimerInterface* _autoReconnectTimer;
91 |
92 | protected slots:
93 | void onSocketReadReady();
94 | void onDisconnected();
95 | void connectToHost();
96 |
97 | private:
98 | Q_DISABLE_COPY(SslNetwork)
99 | };
100 |
101 | } // namespace QMQTT
102 |
103 | #endif // QT_NO_SSL
104 |
105 | #endif // QMQTT_SSL_NETWORK_H
106 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_ssl_socket.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_ssl_socket.cpp - qmqtt SSL socket
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * Copyright (c) 2016 Matthias Dieter Wallnöfer
6 | * All rights reserved.
7 | *
8 | * Redistribution and use in source and binary forms, with or without
9 | * modification, are permitted provided that the following conditions are met:
10 | *
11 | * * Redistributions of source code must retain the above copyright notice,
12 | * this list of conditions and the following disclaimer.
13 | * * Redistributions in binary form must reproduce the above copyright
14 | * notice, this list of conditions and the following disclaimer in the
15 | * documentation and/or other materials provided with the distribution.
16 | * * Neither the name of mqttc nor the names of its contributors may be used
17 | * to endorse or promote products derived from this software without
18 | * specific prior written permission.
19 | *
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 | * POSSIBILITY OF SUCH DAMAGE.
31 | *
32 | */
33 | #include "qmqtt_ssl_socket.h"
34 | #include
35 |
36 | #ifndef QT_NO_SSL
37 |
38 | QMQTT::SslSocket::SslSocket(bool ignoreSelfSigned, QObject* parent)
39 | : SocketInterface(parent)
40 | , _socket(new QSslSocket)
41 | , _ignoreSelfSigned(ignoreSelfSigned)
42 | {
43 | connect(_socket.data(), &QSslSocket::encrypted, this, &SocketInterface::connected);
44 | connect(_socket.data(), &QSslSocket::disconnected, this, &SocketInterface::disconnected);
45 | connect(_socket.data(),
46 | static_cast(&QSslSocket::error),
47 | this,
48 | static_cast(&SocketInterface::error));
49 | connect(_socket.data(),
50 | static_cast&)>(&QSslSocket::sslErrors),
51 | this,
52 | &SslSocket::sslErrors);
53 | }
54 |
55 | QMQTT::SslSocket::~SslSocket()
56 | {
57 | }
58 |
59 | QIODevice *QMQTT::SslSocket::ioDevice()
60 | {
61 | return _socket.data();
62 | }
63 |
64 | void QMQTT::SslSocket::connectToHost(const QHostAddress& address, quint16 port)
65 | {
66 | Q_UNUSED(address);
67 | Q_UNUSED(port);
68 |
69 | qCritical("qmqtt: SSL does not work with host addresses!");
70 | emit _socket->error(QAbstractSocket::ConnectionRefusedError);
71 | }
72 |
73 | void QMQTT::SslSocket::connectToHost(const QString& hostName, quint16 port)
74 | {
75 | _socket->connectToHostEncrypted(hostName, port);
76 | if (!_socket->waitForEncrypted())
77 | {
78 | qCritical() << QStringLiteral("qmqtt SSL: ") << _socket->errorString();
79 | }
80 | }
81 |
82 | void QMQTT::SslSocket::disconnectFromHost()
83 | {
84 | _socket->disconnectFromHost();
85 | }
86 |
87 | QAbstractSocket::SocketState QMQTT::SslSocket::state() const
88 | {
89 | return _socket->state();
90 | }
91 |
92 | QAbstractSocket::SocketError QMQTT::SslSocket::error() const
93 | {
94 | return _socket->error();
95 | }
96 |
97 | void QMQTT::SslSocket::sslErrors(const QList &errors)
98 | {
99 | Q_UNUSED(errors);
100 |
101 | if (_ignoreSelfSigned)
102 | {
103 | // allow self-signed certificates
104 | _socket->ignoreSslErrors();
105 | }
106 | }
107 |
108 | #endif // QT_NO_SSL
109 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_ssl_socket.h:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_ssl_socket.h - qmqtt SSL socket header
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * Copyright (c) 2016 Matthias Dieter Wallnöfer
6 | * All rights reserved.
7 | *
8 | * Redistribution and use in source and binary forms, with or without
9 | * modification, are permitted provided that the following conditions are met:
10 | *
11 | * * Redistributions of source code must retain the above copyright notice,
12 | * this list of conditions and the following disclaimer.
13 | * * Redistributions in binary form must reproduce the above copyright
14 | * notice, this list of conditions and the following disclaimer in the
15 | * documentation and/or other materials provided with the distribution.
16 | * * Neither the name of mqttc nor the names of its contributors may be used
17 | * to endorse or promote products derived from this software without
18 | * specific prior written permission.
19 | *
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 | * POSSIBILITY OF SUCH DAMAGE.
31 | *
32 | */
33 | #ifndef QMQTT_SSL_SOCKET_H
34 | #define QMQTT_SSL_SOCKET_H
35 |
36 | #include "qmqtt_socketinterface.h"
37 | #include
38 | #include
39 |
40 | #ifndef QT_NO_SSL
41 |
42 | class QSslSocket;
43 | class QSslError;
44 |
45 | namespace QMQTT
46 | {
47 |
48 | class SslSocket : public SocketInterface
49 | {
50 | Q_OBJECT
51 | public:
52 | explicit SslSocket(bool ignoreSelfSigned, QObject* parent = NULL);
53 | virtual ~SslSocket();
54 |
55 | virtual QIODevice *ioDevice();
56 | void connectToHost(const QHostAddress& address, quint16 port);
57 | void connectToHost(const QString& hostName, quint16 port);
58 | void disconnectFromHost();
59 | QAbstractSocket::SocketState state() const;
60 | QAbstractSocket::SocketError error() const;
61 |
62 | protected slots:
63 | void sslErrors(const QList &errors);
64 |
65 | protected:
66 | QScopedPointer _socket;
67 | bool _ignoreSelfSigned;
68 | };
69 |
70 | }
71 |
72 | #endif // QT_NO_SSL
73 |
74 | #endif // QMQTT_SSL_SOCKET_H
75 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_timer.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_timer.cpp - qmqtt timer
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | *
10 | * * Redistributions of source code must retain the above copyright notice,
11 | * this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above copyright
13 | * notice, this list of conditions and the following disclaimer in the
14 | * documentation and/or other materials provided with the distribution.
15 | * * Neither the name of mqttc nor the names of its contributors may be used
16 | * to endorse or promote products derived from this software without
17 | * specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | * POSSIBILITY OF SUCH DAMAGE.
30 | *
31 | */
32 | #include "qmqtt_timer.h"
33 |
34 | QMQTT::Timer::Timer(QObject* parent)
35 | : TimerInterface(parent)
36 | {
37 | connect(&_timer, &QTimer::timeout, this, &TimerInterface::timeout);
38 | }
39 |
40 | QMQTT::Timer::~Timer()
41 | {
42 | }
43 |
44 | bool QMQTT::Timer::isSingleShot() const
45 | {
46 | return _timer.isSingleShot();
47 | }
48 |
49 | void QMQTT::Timer::setSingleShot(bool singleShot)
50 | {
51 | _timer.setSingleShot(singleShot);
52 | }
53 |
54 | int QMQTT::Timer::interval() const
55 | {
56 | return _timer.interval();
57 | }
58 |
59 | void QMQTT::Timer::setInterval(int msec)
60 | {
61 | _timer.setInterval(msec);
62 | }
63 |
64 | void QMQTT::Timer::start()
65 | {
66 | _timer.start();
67 | }
68 |
69 | void QMQTT::Timer::stop()
70 | {
71 | _timer.stop();
72 | }
73 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_timer.h:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_timer.h - qmqtt timer header
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | *
10 | * * Redistributions of source code must retain the above copyright notice,
11 | * this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above copyright
13 | * notice, this list of conditions and the following disclaimer in the
14 | * documentation and/or other materials provided with the distribution.
15 | * * Neither the name of mqttc nor the names of its contributors may be used
16 | * to endorse or promote products derived from this software without
17 | * specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | * POSSIBILITY OF SUCH DAMAGE.
30 | *
31 | */
32 | #ifndef QMQTT_TIMER_H
33 | #define QMQTT_TIMER_H
34 |
35 | #include "qmqtt_timerinterface.h"
36 | #include
37 |
38 | namespace QMQTT {
39 |
40 | class Timer : public TimerInterface
41 | {
42 | Q_OBJECT
43 | public:
44 | explicit Timer(QObject *parent = 0);
45 | virtual ~Timer();
46 |
47 | bool isSingleShot() const;
48 | void setSingleShot(bool singleShot);
49 | int interval() const;
50 | void setInterval(int msec);
51 | void start();
52 | void stop();
53 |
54 | protected:
55 | QTimer _timer;
56 | };
57 |
58 | }
59 |
60 | #endif // QMQTT_TIMER_H
61 |
--------------------------------------------------------------------------------
/libqmqtt/qmqtt_timerinterface.h:
--------------------------------------------------------------------------------
1 | /*
2 | * qmqtt_timerinterface.h - qmqtt timer interface header
3 | *
4 | * Copyright (c) 2013 Ery Lee
5 | * All rights reserved.
6 | *
7 | * Redistribution and use in source and binary forms, with or without
8 | * modification, are permitted provided that the following conditions are met:
9 | *
10 | * * Redistributions of source code must retain the above copyright notice,
11 | * this list of conditions and the following disclaimer.
12 | * * Redistributions in binary form must reproduce the above copyright
13 | * notice, this list of conditions and the following disclaimer in the
14 | * documentation and/or other materials provided with the distribution.
15 | * * Neither the name of mqttc nor the names of its contributors may be used
16 | * to endorse or promote products derived from this software without
17 | * specific prior written permission.
18 | *
19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | * POSSIBILITY OF SUCH DAMAGE.
30 | *
31 | */
32 | #ifndef QMQTT_TIMER_INTERFACE_H
33 | #define QMQTT_TIMER_INTERFACE_H
34 |
35 | #include
36 |
37 | namespace QMQTT {
38 |
39 | class TimerInterface : public QObject
40 | {
41 | Q_OBJECT
42 | public:
43 | explicit TimerInterface(QObject* parent = NULL) : QObject(parent) {}
44 | virtual ~TimerInterface() {}
45 |
46 | virtual bool isSingleShot() const = 0;
47 | virtual void setSingleShot(bool singleShot) = 0;
48 | virtual int interval() const = 0;
49 | virtual void setInterval(int msec) = 0;
50 | virtual void start() = 0;
51 | virtual void stop() = 0;
52 |
53 | signals:
54 | void timeout();
55 | };
56 |
57 | }
58 |
59 | #endif // QMQTT_TIMER_INTERFACE_H
60 |
61 |
--------------------------------------------------------------------------------
/main.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016-2021 Jakob Flierl
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice,
9 | * this list of conditions and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright
11 | * notice, this list of conditions and the following disclaimer in the
12 | * documentation and/or other materials provided with the distribution.
13 | * * Neither the name of mqttc nor the names of its contributors may be used
14 | * to endorse or promote products derived from this software without
15 | * specific prior written permission.
16 | *
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | * POSSIBILITY OF SUCH DAMAGE.
28 | *
29 | */
30 |
31 | #include
32 |
33 | #include "mainwindow.h"
34 |
35 | int main(int argc, char** argv)
36 | {
37 | QApplication app(argc, argv);
38 |
39 | MainWindow w;
40 | w.show();
41 |
42 | return app.exec();
43 | }
44 |
--------------------------------------------------------------------------------
/main.pro:
--------------------------------------------------------------------------------
1 | TEMPLATE = app
2 |
3 | TARGET = qmqtt-plot
4 |
5 | DEFINES += QMQTT_EXAMPLE
6 |
7 | INCLUDEPATH += libqmqtt
8 |
9 | SOURCES = main.cpp \
10 | mainwindow.cpp ledindicator.cpp qcustomplot.cpp \
11 | \
12 | libqmqtt/qmqtt_client.cpp libqmqtt/qmqtt_network.cpp libqmqtt/qmqtt_ssl_network.cpp \
13 | libqmqtt/qmqtt_client_p.cpp libqmqtt/qmqtt_routedmessage.cpp libqmqtt/qmqtt_ssl_socket.cpp \
14 | libqmqtt/qmqtt_frame.cpp libqmqtt/qmqtt_router.cpp libqmqtt/qmqtt_timer.cpp \
15 | libqmqtt/qmqtt_message.cpp libqmqtt/qmqtt_routesubscription.cpp \
16 | libqmqtt/qmqtt_message_p.cpp libqmqtt/qmqtt_socket.cpp \
17 |
18 | FORMS += \
19 | mainwindow.ui
20 |
21 | HEADERS += \
22 | mainwindow.h ledindicator.h qcustomplot.h \
23 | \
24 | libqmqtt/qmqtt_client.h libqmqtt/qmqtt_message_p.h libqmqtt/qmqtt_socket.h \
25 | libqmqtt/qmqtt_client_p.h libqmqtt/qmqtt_network.h libqmqtt/qmqtt_socketinterface.h \
26 | libqmqtt/qmqtt_frame.h libqmqtt/qmqtt_networkinterface.h libqmqtt/qmqtt_ssl_network.h \
27 | libqmqtt/qmqtt_global.h libqmqtt/qmqtt_routedmessage.h libqmqtt/qmqtt_ssl_socket.h \
28 | libqmqtt/qmqtt.h libqmqtt/qmqtt_router.h libqmqtt/qmqtt_timer.h \
29 | libqmqtt/qmqtt_message.h libqmqtt/qmqtt_routesubscription.h libqmqtt/qmqtt_timerinterface.h \
30 |
31 | win32 {
32 |
33 | } else {
34 | MOC_DIR = .moc
35 | #OBJECTS_DIR = .obj
36 | UI_DIR = .ui
37 | RCC_DIR = .rcc
38 |
39 | CONFIG += link_pkgconfig
40 |
41 | qmqtt-plot-binary.path = /usr/bin
42 | qmqtt-plot-binary.files = qmqtt-plot
43 | qmqtt-plot-deskop.path = /usr/share/applications
44 | qmqtt-plot-deskop.files = qmqtt-plot.desktop
45 | qmqtt-plot-icons.path = /usr/share/icons/hicolor/scalable/apps
46 | qmqtt-plot-icons.files = qmqtt-plot.svg
47 |
48 | INSTALLS += qmqtt-plot-binary qmqtt-plot-deskop qmqtt-plot-icons
49 |
50 | RESOURCES += res.qrc
51 | }
52 |
53 | win32 {
54 | DEFINES += BUILDTIME=\\\"HH:MM\\\"
55 | DEFINES += BUILDDATE=\\\"Y-m-d\\\"
56 | } else {
57 | DEFINES += BUILDTIME=\\\"$$system(date '+%H:%M')\\\"
58 | DEFINES += BUILDDATE=\\\"$$system(date '+%Y-%m-%d')\\\"
59 | }
60 |
61 | QMAKE_CXXFLAGS_RELEASE += -O2
62 | QMAKE_CXXFLAGS_DEBUG += -O0
63 |
64 | CONFIG *= debug_and_release
65 | CONFIG *= qt
66 | CONFIG += warn_on
67 | CONFIG += thread
68 | CONFIG += c++11
69 |
70 | QT += core network gui printsupport widgets
71 |
72 | ICON = qmqtt-plot.svg
73 |
74 | OTHER_FILES += README.md qmqtt-plot.svg qmqtt-plot.desktop
75 |
76 | DIRS_DC = object_script.* .ui .moc .rcc .obj *.pro.user $$TARGET
77 |
78 | unix:QMAKE_DISTCLEAN += -r $$DIRS_DC
79 | win32:QMAKE_DISTCLEAN += /s /f /q $$DIRS_DC && rd /s /q $$DIRS_DC
80 |
--------------------------------------------------------------------------------
/mainwindow.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016-2021 Jakob Flierl
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice,
9 | * this list of conditions and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright
11 | * notice, this list of conditions and the following disclaimer in the
12 | * documentation and/or other materials provided with the distribution.
13 | * * Neither the name of mqttc nor the names of its contributors may be used
14 | * to endorse or promote products derived from this software without
15 | * specific prior written permission.
16 | *
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | * POSSIBILITY OF SUCH DAMAGE.
28 | *
29 | */
30 |
31 | #include
32 | #include
33 | #include
34 | #include
35 | #include
36 |
37 | #include "mainwindow.h"
38 | #include "ui_mainwindow.h"
39 |
40 | MainWindow::MainWindow(QWidget *parent) :
41 | QMainWindow(parent),
42 | ui(new Ui::MainWindow)
43 | {
44 | ui->setupUi(this);
45 |
46 | zoomTime = 1;
47 |
48 | ui->log->setMaximumBlockCount(100);
49 |
50 | QList s; // exit app with ESC or CTRL+Q
51 | s << QKeySequence(Qt::Key_Escape) << QKeySequence(Qt::CTRL + Qt::Key_Q);
52 | ui->action_Quit->setShortcuts(s);
53 |
54 | mqttHost = new QLineEdit();
55 | mqttHost->setMaximumWidth(200);
56 |
57 | ui->toolBar->insertWidget(ui->actionConnect_Disconnect, mqttHost);
58 |
59 | mqttTopic = new QLineEdit();
60 | mqttTopic->setMaximumWidth(200);
61 |
62 | ui->toolBar->insertWidget(ui->actionConnect_Disconnect, mqttTopic);
63 |
64 | led1 = new QLedIndicator(this);
65 | led1->setOn(true);
66 |
67 | lag = new QLabel();
68 | lag->setMinimumWidth(150);
69 | lag->setAlignment(Qt::AlignRight);
70 |
71 | ui->status->addWidget(led1);
72 | ui->statusbar->addWidget(lag, 0);
73 |
74 | for (int i = 0; i < 5; i++) {
75 | ui->plot->addGraph();
76 | ui->plot->legend->setVisible(true);
77 |
78 | //ui->plot->graph(i)->setAntialiased(false);
79 | ui->plot->graph(i)->setAntialiased(true);
80 |
81 | //ui->plot->graph(i)->setLineStyle(QCPGraph::lsNone);
82 | //ui->plot->graph(i)->setLineStyle(QCPGraph::lsStepLeft);
83 | ui->plot->graph(i)->setLineStyle(QCPGraph::lsLine);
84 | QPen pen(Qt::black);
85 | pen.setWidth(2);
86 | pen.setColor(QColor(0,0,0,0x7f));
87 | ui->plot->graph(i)->setPen(pen);
88 | ui->plot->graph(i)->setName(QString("J%1").arg(i+1));
89 |
90 | QCPScatterStyle myScatter;
91 | myScatter.setShape(QCPScatterStyle::ssCircle);
92 | switch(i) {
93 | case 0:
94 | myScatter.setPen(QPen(Qt::red));
95 | break;
96 | case 1:
97 | myScatter.setPen(QPen(Qt::green));
98 | break;
99 | case 2:
100 | myScatter.setPen(QPen(Qt::blue));
101 | break;
102 | case 3:
103 | myScatter.setPen(QPen(Qt::yellow));
104 | break;
105 | case 4:
106 | myScatter.setPen(QPen(Qt::darkYellow));
107 | break;
108 | }
109 | myScatter.setBrush(Qt::black);
110 | myScatter.setSize(3);
111 | ui->plot->graph(i)->setScatterStyle(myScatter);
112 | }
113 |
114 | ui->plot->xAxis->setRange(0,10);
115 | ui->plot->yAxis->setRange(-0.25,1.25);
116 | ui->plot->yAxis->setAutoTickStep(true);
117 | ui->plot->yAxis->setAutoTickCount(7);
118 |
119 | ui->plot->xAxis->setDateTimeFormat("h:mm:ss");
120 | ui->plot->xAxis->setTickLabelType(QCPAxis::ltDateTime);
121 | ui->plot->xAxis->setAutoTickStep(true);
122 | ui->plot->xAxis->setTickStep(1);
123 |
124 | ui->plot->yAxis->rescale(true);
125 | ui->plot->rescaleAxes();
126 |
127 | ui->plot->axisRect()->setupFullAxesBox(true);
128 |
129 | ui->plot->replot();
130 |
131 | ui->tabWidget->setTabText(0, tr("Plot"));
132 | ui->tabWidget->setTabText(1, tr("Log"));
133 | ui->tabWidget->setCurrentIndex(0);
134 |
135 | settings = new QSettings();
136 |
137 | subscriber = new Subscriber(QHostAddress(EXAMPLE_HOST),
138 | EXAMPLE_PORT, this);
139 |
140 | //Publisher publisher;
141 | //publisher.connectToHost();
142 |
143 | timer = new QTimer(this);
144 | timer->setSingleShot(false);
145 |
146 | connect(timer, SIGNAL(timeout()), this, SLOT(updatePlot()));
147 |
148 | connect(subscriber, SIGNAL(signalReceived(QString, QString)), this, SLOT(onReceived(QString, QString)));
149 |
150 | connect(subscriber, SIGNAL(connected()), this, SLOT(onConnected()));
151 | connect(subscriber, SIGNAL(disconnected()), this, SLOT(onDisconnected()));
152 |
153 | connect(ui->actionConnect_Disconnect, SIGNAL(toggled(bool)), this, SLOT(connectDisconnectMQTT(bool)));
154 | connect(mqttTopic, SIGNAL(textChanged(QString)), this, SLOT(updateMQTTSubscription()));
155 |
156 | loadSettings();
157 |
158 | timer->start(1000/120); // fps
159 | }
160 |
161 | void MainWindow::on_action_Zoom_In_triggered() {
162 | zoomTime /= 2;
163 | if (zoomTime > 60) {
164 | ui->plot->xAxis->setTickStep(60);
165 | ui->plot->xAxis->setDateTimeFormat("h:mm");
166 | } else if (zoomTime > 1) {
167 | ui->plot->xAxis->setTickStep(1);
168 | ui->plot->xAxis->setDateTimeFormat("h:mm:ss");
169 | } else {
170 | ui->plot->xAxis->setDateTimeFormat("h:mm:ss:zzz");
171 | ui->plot->xAxis->setTickStep(0.1);
172 | }
173 | }
174 |
175 | void MainWindow::on_action_Zoom_Out_triggered() {
176 | zoomTime *= 2;
177 | if (zoomTime > 60) {
178 | ui->plot->xAxis->setTickStep(60);
179 | ui->plot->xAxis->setDateTimeFormat("h:mm");
180 | } else if (zoomTime > 1) {
181 | ui->plot->xAxis->setTickStep(1);
182 | ui->plot->xAxis->setDateTimeFormat("h:mm:ss");
183 | } else {
184 | ui->plot->xAxis->setDateTimeFormat("h:mm:ss:zzz");
185 | ui->plot->xAxis->setTickStep(0.1);
186 | }
187 | }
188 |
189 | void MainWindow::connectDisconnectMQTT(bool connect) {
190 | if (connect) {
191 | if (!subscriber->connectionState()) {
192 | led1->setDisconnected(true);
193 | subscriber->setHostName(mqttHost->text());
194 | subscriber->connectToHost();
195 | subscriber->setAutoReconnect(true);
196 | ui->statusbar->showMessage(tr("Connecting to %1").arg(mqttHost->text()));
197 | }
198 | } else {
199 | subscriber->setAutoReconnect(false);
200 | subscriber->disconnectFromHost();
201 | subscriber->cleanSession();
202 | led1->setDisconnected(true);
203 | }
204 | }
205 |
206 | void MainWindow::updateMQTTSubscription() {
207 | if (!mqttTopicOld.isEmpty()) {
208 | subscriber->unsubscribe(mqttTopicOld);
209 | }
210 |
211 | subscriber->subscribe(mqttTopic->text(), 0);
212 |
213 | mqttTopicOld = mqttTopic->text();
214 | }
215 |
216 | void MainWindow::onConnected() {
217 | ui->statusbar->showMessage(tr("Connected to %1").arg(subscriber->hostName()), 1000);
218 | log(QString("connected to %1").arg(subscriber->hostName()));
219 | led1->setDisconnected(false);
220 | ui->actionConnect_Disconnect->setChecked(true);
221 | ui->actionConnect_Disconnect->setToolTip(tr("Disconnect"));
222 |
223 | updateMQTTSubscription();
224 | }
225 |
226 | void MainWindow::onDisconnected() {
227 | ui->statusbar->showMessage(tr("Disconnected"), 1000);
228 | log("disconnected");
229 | led1->setDisconnected(true);
230 | ui->actionConnect_Disconnect->setChecked(false);
231 | ui->actionConnect_Disconnect->setToolTip(tr("Connect"));
232 | }
233 |
234 | void MainWindow::onReceived(QString topic, QString msg) {
235 | double tsl = QDateTime::currentMSecsSinceEpoch() / 1000.0;
236 |
237 | log(QString("%1: %2").arg(topic, msg));
238 |
239 | bool ok_ts, ok[6];
240 | double ts = msg.split(" ")[0].toDouble(&ok_ts);
241 | double val[6];
242 |
243 | for (int i = 1; i < 6; i++) {
244 | val[i-1] = msg.split(" ")[i].toDouble(&ok[i-1]);
245 | }
246 |
247 | if (ok_ts && ok[0] && ok[1] && ok[2] && ok[3] && ok[4]) {
248 | //led1->setOn(val[0]);
249 |
250 | for (int i = 0; i < 5; i++) {
251 | ui->plot->graph(i)->addData(ts, val[i]);
252 | ui->plot->graph(i)->removeDataBefore(ts - qMin((int)(zoomTime*10), 600)); // max 10 minutes buffer size
253 | }
254 | // ui->plot->graph(0)->setName(topic);
255 |
256 | double lagt = (tsl - ts) * 1000;
257 | lag->setText(tr("%1%2 msec lag").arg(lagt < 0 ? '-' : ' ').arg(qFabs(lagt),5,'f',2,' '));
258 |
259 | } else {
260 | QString info;
261 | info = QString("%1 %2 %3 %4").arg(QString::number(ts, 'f'),
262 | QString::number(val[0]),
263 | QString::number(ok_ts),
264 | QString::number(ok[0]));
265 |
266 | log(tr("%1: error while converting %1").arg(topic, info));
267 | }
268 | }
269 |
270 | void MainWindow::loadSettings() {
271 | settings->beginGroup("gui");
272 |
273 | restoreGeometry(settings->value("geometry", saveGeometry() ).toByteArray());
274 | restoreState(settings->value("state", saveState() ).toByteArray());
275 | move(settings->value("pos", pos()).toPoint());
276 | resize(settings->value("size", size()).toSize());
277 |
278 | if ( settings->value("fullscreen", isFullScreen() ).toBool()) {
279 | showFullScreen();
280 | } else {
281 | showNormal();
282 | }
283 | if ( settings->value("maximized", isMaximized() ).toBool()) {
284 | showMaximized();
285 | }
286 |
287 | zoomTime = settings->value("zoomTime", 1).toDouble();
288 |
289 | settings->endGroup();
290 |
291 | settings->beginGroup("mqtt");
292 | mqttHost->setText(settings->value("host", "127.0.0.1").toString());
293 | mqttTopic->setText(settings->value("topic", "Robot/Coordinates").toString());
294 | settings->endGroup();
295 | }
296 |
297 | void MainWindow::saveSettings() {
298 | settings->beginGroup("gui");
299 |
300 | settings->setValue("geometry", saveGeometry());
301 | settings->setValue("state", saveState());
302 | settings->setValue("fullscreen", isFullScreen());
303 | settings->setValue("maximized", isMaximized());
304 |
305 | if ( !isMaximized() && !isFullScreen() ) {
306 | settings->setValue("pos", pos());
307 | settings->setValue("size", size());
308 | }
309 |
310 | settings->setValue("zoomTime", zoomTime);
311 |
312 | settings->endGroup();
313 |
314 | settings->beginGroup("mqtt");
315 | settings->setValue("host", mqttHost->text());
316 | settings->setValue("topic", mqttTopic->text());
317 | settings->endGroup();
318 | }
319 |
320 | void MainWindow::closeEvent(QCloseEvent * event) {
321 | saveSettings();
322 | event->accept();
323 | }
324 |
325 | void MainWindow::keyPressEvent(QKeyEvent *e) {
326 | int keyInt = e->key();
327 | Qt::Key key = static_cast(keyInt);
328 |
329 | if (key == Qt::Key_unknown) {
330 | log(tr("Unknown key from a macro probably."));
331 | return;
332 | }
333 | // the user have clicked just and only the special keys Ctrl, Shift, Alt, Meta.
334 | if (key == Qt::Key_Control ||
335 | key == Qt::Key_Shift ||
336 | key == Qt::Key_Alt ||
337 | key == Qt::Key_Meta)
338 | {
339 | // qDebug() << "Single click of special key: Ctrl, Shift, Alt or Meta";
340 | // qDebug() << "New KeySequence:" << QKeySequence(keyInt).toString(QKeySequence::NativeText);
341 | // return;
342 | }
343 |
344 | // check for a combination of user clicks
345 | Qt::KeyboardModifiers modifiers = e->modifiers();
346 | QString keyText = e->text();
347 | // if the keyText is empty than it's a special key like F1, F5, ...
348 | // qDebug() << "Pressed Key:" << keyText;
349 | QList modifiersList;
350 | if (modifiers & Qt::ShiftModifier)
351 | keyInt += Qt::SHIFT;
352 | if (modifiers & Qt::ControlModifier)
353 | keyInt += Qt::CTRL;
354 | if (modifiers & Qt::AltModifier)
355 | keyInt += Qt::ALT;
356 | if (modifiers & Qt::MetaModifier)
357 | keyInt += Qt::META;
358 |
359 | QString seq = QKeySequence(keyInt).toString(QKeySequence::NativeText);
360 | // qDebug() << "KeySequence:" << seq;
361 |
362 | return; // skip built in command if overridden by shortcut
363 | QMainWindow::keyPressEvent(e);
364 | }
365 |
366 | void MainWindow::log(QString l) {
367 | QString ts;
368 | ts.sprintf("%06.5f", QDateTime::currentMSecsSinceEpoch() / 1000.0);
369 | ui->log->appendPlainText(QString("%1 %2").arg(ts, l));
370 | }
371 |
372 | void MainWindow::updatePlot() {
373 | double tsl = QDateTime::currentMSecsSinceEpoch() / 1000.0;
374 | ui->plot->xAxis->setRange(tsl - zoomTime, tsl);
375 | ui->plot->yAxis->rescale(true);
376 | //ui->plot->rescaleAxes();
377 | ui->plot->replot(QCustomPlot::rpQueued);
378 | }
379 |
380 | void MainWindow::on_action_Print_triggered() {
381 | QPrinter printer;
382 | printer.setPageMargins (15,15,15,15, QPrinter::Millimeter);
383 | printer.setPageSize(QPrinter::A4);
384 | printer.setOrientation(QPrinter::Landscape);
385 | //printer.setResolution(QPrinter::HighResolution);
386 | printer.setFullPage(false);
387 |
388 | QPrintPreviewDialog preview(&printer, this);
389 | preview.setWindowTitle("Preview Dialog");
390 | Qt::WindowFlags flags(Qt::WindowTitleHint | Qt::Window);
391 | preview.setWindowFlags(flags);
392 | connect(&preview, SIGNAL(paintRequested(QPrinter *)), SLOT(printPreview(QPrinter *)));
393 | preview.exec();
394 | }
395 |
396 | void MainWindow::printPreview(QPrinter *printer) {
397 | printer->setPageSize(QPrinter::A4);
398 | QCPPainter painter(printer);
399 | QRectF pageRect = printer->pageRect(QPrinter::DevicePixel);
400 |
401 | int plotWidth = ui->plot->viewport().width();
402 | int plotHeight = ui->plot->viewport().height();
403 | double scale = qMin(pageRect.width()/(double)plotWidth, pageRect.height()/(double)plotHeight);
404 |
405 | painter.setRenderHints(QPainter::Antialiasing |
406 | QPainter::TextAntialiasing |
407 | QPainter::SmoothPixmapTransform, true);
408 |
409 | painter.setMode(QCPPainter::pmVectorized);
410 | painter.setMode(QCPPainter::pmNoCaching);
411 |
412 | // comment this out if you want cosmetic thin lines (always 1 pixel thick independent of pdf zoom level)
413 | painter.setMode(QCPPainter::pmNonCosmetic);
414 |
415 | painter.scale(scale, scale);
416 | ui->plot->toPainter(&painter, plotWidth, plotHeight);
417 | }
418 |
419 | MainWindow::~MainWindow()
420 | {
421 | delete ui;
422 | }
423 |
--------------------------------------------------------------------------------
/mainwindow.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2016 Jakob Flierl
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without
6 | * modification, are permitted provided that the following conditions are met:
7 | *
8 | * * Redistributions of source code must retain the above copyright notice,
9 | * this list of conditions and the following disclaimer.
10 | * * Redistributions in binary form must reproduce the above copyright
11 | * notice, this list of conditions and the following disclaimer in the
12 | * documentation and/or other materials provided with the distribution.
13 | * * Neither the name of mqttc nor the names of its contributors may be used
14 | * to endorse or promote products derived from this software without
15 | * specific prior written permission.
16 | *
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 | * POSSIBILITY OF SUCH DAMAGE.
28 | *
29 | */
30 |
31 | #ifndef MAINWINDOW_H
32 | #define MAINWINDOW_H
33 |
34 | #include
35 | #include
36 | #include
37 | #include
38 | #include
39 | #include
40 | #include
41 | #include
42 |
43 | #include "ledindicator.h"
44 |
45 | const QHostAddress EXAMPLE_HOST = QHostAddress("192.168.0.114");
46 | const quint16 EXAMPLE_PORT = 1883;
47 | const QString EXAMPLE_TOPIC = "rm501/0/pos";
48 |
49 | class Publisher : public QMQTT::Client
50 | {
51 | Q_OBJECT
52 | public:
53 | explicit Publisher(const QHostAddress& host = EXAMPLE_HOST,
54 | const quint16 port = EXAMPLE_PORT,
55 | QObject* parent = NULL)
56 | : QMQTT::Client(host, port, parent)
57 | , _number(0)
58 | {
59 | connect(this, &Publisher::connected, this, &Publisher::onConnected);
60 | connect(&_timer, &QTimer::timeout, this, &Publisher::onTimeout);
61 | connect(this, &Publisher::disconnected, this, &Publisher::onDisconnected);
62 | }
63 | virtual ~Publisher() {}
64 |
65 | QTimer _timer;
66 | quint16 _number;
67 |
68 | public slots:
69 | void onConnected()
70 | {
71 | subscribe(EXAMPLE_TOPIC, 0);
72 | _timer.start(1000);
73 | }
74 |
75 | void onTimeout()
76 | {
77 | QMQTT::Message message(_number, EXAMPLE_TOPIC,
78 | QString("Number is %1").arg(_number).toUtf8());
79 | publish(message);
80 | _number++;
81 | if(_number >= 10)
82 | {
83 | _timer.stop();
84 | disconnectFromHost();
85 | }
86 | }
87 |
88 | void onDisconnected()
89 | {
90 | #if (QT_VERSION < QT_VERSION_CHECK(5, 4, 0))
91 | QTimer::singleShot(0, qApp, SLOT(QCoreApplication::quit()));
92 | #else
93 | QTimer::singleShot(0, qApp, &QCoreApplication::quit);
94 | #endif
95 | }
96 | };
97 |
98 | class Subscriber : public QMQTT::Client
99 | {
100 | Q_OBJECT
101 | public:
102 | explicit Subscriber(const QHostAddress& host = EXAMPLE_HOST,
103 | const quint16 port = EXAMPLE_PORT,
104 | QObject* parent = NULL)
105 | : QMQTT::Client(host, port, parent)
106 | , _qout(stdout)
107 | {
108 | connect(this, &Subscriber::connected, this, &Subscriber::onConnected);
109 | connect(this, &Subscriber::disconnected, this, &Subscriber::onDisconnected);
110 | connect(this, &Subscriber::subscribed, this, &Subscriber::onSubscribed);
111 | connect(this, &Subscriber::received, this, &Subscriber::onReceived);
112 | }
113 | virtual ~Subscriber() {}
114 |
115 | QTextStream _qout;
116 |
117 | signals:
118 | void signalReceived(QString topic, QString msg);
119 | void signalConnected();
120 | void signalDisconnected();
121 | void signalSubscribed(QString topic);
122 |
123 | public slots:
124 | void onConnected()
125 | {
126 | // _qout << "connected" << endl;
127 | emit signalConnected();
128 | }
129 |
130 | void onDisconnected()
131 | {
132 | // _qout << "disconnected" << endl;
133 | emit signalDisconnected();
134 | }
135 |
136 | void onSubscribed(const QString& topic)
137 | {
138 | Q_UNUSED(topic)
139 | // _qout << "subscribed " << topic << endl;
140 | emit signalSubscribed(topic);
141 | }
142 |
143 | void onReceived(const QMQTT::Message& message)
144 | {
145 | emit signalReceived(message.topic(), QString::fromUtf8(message.payload()));
146 | // _qout << "publish received: \"" << QString::fromUtf8(message.payload())
147 | // << "\"" << endl;
148 | }
149 | };
150 |
151 | namespace Ui {
152 | class MainWindow;
153 | }
154 |
155 | class MainWindow : public QMainWindow
156 | {
157 | Q_OBJECT
158 |
159 | public:
160 | explicit MainWindow(QWidget *parent = 0);
161 | ~MainWindow();
162 |
163 | public slots:
164 | void onReceived(QString topic, QString msg);
165 |
166 | void onConnected();
167 | void onDisconnected();
168 |
169 | void connectDisconnectMQTT(bool connect);
170 |
171 | void keyPressEvent(QKeyEvent *e);
172 |
173 | void loadSettings();
174 | void saveSettings();
175 |
176 | void log(QString l);
177 |
178 | void on_action_Zoom_In_triggered();
179 | void on_action_Zoom_Out_triggered();
180 |
181 | void on_action_Print_triggered();
182 |
183 | void printPreview(QPrinter *printer);
184 |
185 | void updateMQTTSubscription();
186 |
187 | private slots:
188 | void closeEvent(QCloseEvent *);
189 | void updatePlot();
190 |
191 | private:
192 | Ui::MainWindow *ui;
193 |
194 | Subscriber *subscriber;
195 |
196 | QSettings *settings;
197 | QLineEdit *mqttHost;
198 | QLineEdit *mqttTopic;
199 |
200 | QLedIndicator *led1;
201 |
202 | QTimer *timer;
203 |
204 | QLabel *lag;
205 |
206 | double zoomTime;
207 |
208 | QString mqttTopicOld;
209 | };
210 |
211 | #endif // MAINWINDOW_H
212 |
--------------------------------------------------------------------------------
/mainwindow.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | MainWindow
4 |
5 |
6 |
7 | 0
8 | 0
9 | 651
10 | 474
11 |
12 |
13 |
14 | qmqtt-plot
15 |
16 |
17 |
18 | :/qmqtt-plot.svg:/qmqtt-plot.svg
19 |
20 |
21 |
22 |
23 | 6
24 |
25 |
26 | 6
27 |
28 |
29 | 6
30 |
31 |
32 | 6
33 |
34 |
35 |
36 |
37 | 0
38 |
39 |
40 |
41 | Tab 1
42 |
43 |
44 |
45 | 6
46 |
47 |
48 | 6
49 |
50 |
51 | 6
52 |
53 |
54 | 6
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 | Tab 2
64 |
65 |
66 |
67 | 6
68 |
69 |
70 | 6
71 |
72 |
73 | 6
74 |
75 |
76 | 6
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 | 0
91 | 0
92 | 651
93 | 25
94 |
95 |
96 |
97 |
98 |
99 |
100 | toolBar
101 |
102 |
103 | TopToolBarArea
104 |
105 |
106 | false
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 | toolBar_2
115 |
116 |
117 | TopToolBarArea
118 |
119 |
120 | false
121 |
122 |
123 |
124 |
125 | toolBar_2
126 |
127 |
128 | TopToolBarArea
129 |
130 |
131 | false
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 | true
141 |
142 |
143 |
144 | ..
145 |
146 |
147 | Connect / Disconnect
148 |
149 |
150 | Connect
151 |
152 |
153 | Space
154 |
155 |
156 |
157 |
158 |
159 | ..
160 |
161 |
162 | Quit
163 |
164 |
165 |
166 |
167 |
168 | ..
169 |
170 |
171 | Zoom In
172 |
173 |
174 | Zoom In Time
175 |
176 |
177 | Ctrl++
178 |
179 |
180 |
181 |
182 |
183 | ..
184 |
185 |
186 | Zoom Out
187 |
188 |
189 | Zoom Out Time
190 |
191 |
192 | Ctrl+-
193 |
194 |
195 |
196 |
197 |
198 | ..
199 |
200 |
201 | Print
202 |
203 |
204 | Ctrl+P
205 |
206 |
207 |
208 |
209 |
210 | QCustomPlot
211 | QWidget
212 | qcustomplot.h
213 | 1
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 | action_Quit
222 | triggered()
223 | MainWindow
224 | close()
225 |
226 |
227 | -1
228 | -1
229 |
230 |
231 | 139
232 | 152
233 |
234 |
235 |
236 |
237 |
238 |
--------------------------------------------------------------------------------
/qmqtt-plot.desktop:
--------------------------------------------------------------------------------
1 | [Desktop Entry]
2 | Encoding=UTF-8
3 | Version=1.0
4 | Name=qmqtt-plot
5 | GenericName=QMQTT Plot
6 | Comment=MQTT Timestamped data plotter
7 | Icon=/usr/share/icons/hicolor/scalable/apps/qmqtt-plot.svg
8 |
9 | Type=Application
10 | Categories=Engineering;Development
11 |
12 | Exec=qmqtt-plot %f
13 | Terminal=false
14 |
--------------------------------------------------------------------------------
/qmqtt-plot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/koppi/qmqtt-plot/153e953da56d987215f4dc3e9ffb7b01d5994ac6/qmqtt-plot.png
--------------------------------------------------------------------------------
/qmqtt-plot.svg:
--------------------------------------------------------------------------------
1 |
2 |
131 |
--------------------------------------------------------------------------------
/res.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | qmqtt-plot.svg
6 |
7 |
8 |
--------------------------------------------------------------------------------