diff --git a/.clang-format b/.clang-format
new file mode 100644
index 00000000..eb68164e
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,273 @@
+---
+Language: Cpp
+# BasedOnStyle: Google
+AccessModifierOffset: -4
+#AlignAfterOpenBracket: Align
+AlignAfterOpenBracket: BlockIndent
+AlignArrayOfStructures: None
+AlignConsecutiveAssignments:
+ Enabled: false
+ AcrossEmptyLines: false
+ AcrossComments: false
+ AlignCompound: false
+ PadOperators: true
+AlignConsecutiveBitFields:
+ Enabled: false
+ AcrossEmptyLines: false
+ AcrossComments: false
+ AlignCompound: false
+ PadOperators: false
+AlignConsecutiveDeclarations:
+ Enabled: false
+ AcrossEmptyLines: false
+ AcrossComments: false
+ AlignCompound: false
+ PadOperators: false
+AlignConsecutiveMacros:
+ Enabled: false
+ AcrossEmptyLines: false
+ AcrossComments: false
+ AlignCompound: false
+ PadOperators: false
+# Clang-17
+#AlignConsecutiveShortCaseStatements:
+# Enabled: false
+# AcrossEmptyLines: false
+# AcrossComments: false
+# AlignCaseColons: false
+AlignEscapedNewlines: Left
+AlignOperands: Align
+AlignTrailingComments:
+ Kind: Always
+ OverEmptyLines: 0
+AllowAllArgumentsOnNextLine: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortBlocksOnASingleLine: Never
+AllowShortCaseLabelsOnASingleLine: false
+AllowShortEnumsOnASingleLine: true
+AllowShortFunctionsOnASingleLine: All
+AllowShortIfStatementsOnASingleLine: Never
+AllowShortLambdasOnASingleLine: All
+AllowShortLoopsOnASingleLine: true
+AlwaysBreakAfterDefinitionReturnType: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakBeforeMultilineStrings: true
+AlwaysBreakTemplateDeclarations: Yes
+AttributeMacros:
+ - __capability
+BinPackArguments: true
+BinPackParameters: true
+BitFieldColonSpacing: Both
+BraceWrapping:
+ AfterCaseLabel: false
+ AfterClass: true
+ AfterControlStatement: Never
+ AfterEnum: false
+ AfterExternBlock: false
+ AfterFunction: true
+ AfterNamespace: false
+ AfterObjCDeclaration: false
+ AfterStruct: true
+ AfterUnion: false
+ BeforeCatch: true
+ BeforeElse: true
+ BeforeLambdaBody: false
+ BeforeWhile: false
+ IndentBraces: false
+ SplitEmptyFunction: true
+ SplitEmptyRecord: true
+ SplitEmptyNamespace: true
+BreakAfterAttributes: Never
+BreakAfterJavaFieldAnnotations: false
+BreakArrays: true
+BreakBeforeBinaryOperators: None
+BreakBeforeConceptDeclarations: Always
+BreakBeforeBraces: Custom
+BreakBeforeInlineASMColon: OnlyMultiline
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializers: BeforeColon
+BreakInheritanceList: BeforeColon
+BreakStringLiterals: true
+ColumnLimit: 94
+CommentPragmas: '^ IWYU pragma:'
+CompactNamespaces: false
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: true
+DerivePointerAlignment: false
+DisableFormat: false
+EmptyLineAfterAccessModifier: Never
+EmptyLineBeforeAccessModifier: LogicalBlock
+ExperimentalAutoDetectBinPacking: false
+FixNamespaceComments: true
+ForEachMacros:
+ - foreach
+ - Q_FOREACH
+ - BOOST_FOREACH
+IfMacros:
+ - KJ_IF_MAYBE
+IncludeBlocks: Regroup
+IncludeCategories:
+ - Regex: '^'
+ Priority: 2
+ SortPriority: 0
+ CaseSensitive: false
+ - Regex: '^<.*\.h>'
+ Priority: 1
+ SortPriority: 0
+ CaseSensitive: false
+ - Regex: '^<.*'
+ Priority: 2
+ SortPriority: 0
+ CaseSensitive: false
+ - Regex: '.*'
+ Priority: 3
+ SortPriority: 0
+ CaseSensitive: false
+IncludeIsMainRegex: '([-_](test|unittest))?$'
+IncludeIsMainSourceRegex: ''
+IndentAccessModifiers: false
+IndentCaseBlocks: false
+IndentCaseLabels: true
+IndentExternBlock: AfterExternBlock
+IndentGotoLabels: true
+IndentPPDirectives: BeforeHash
+IndentRequiresClause: true
+IndentWidth: 4
+IndentWrappedFunctionNames: false
+InsertBraces: false
+InsertNewlineAtEOF: true
+InsertTrailingCommas: None
+IntegerLiteralSeparator:
+ Binary: 0
+ BinaryMinDigits: 0
+ Decimal: 0
+ DecimalMinDigits: 0
+ Hex: 0
+ HexMinDigits: 0
+JavaScriptQuotes: Leave
+JavaScriptWrapImports: true
+KeepEmptyLinesAtTheStartOfBlocks: false
+KeepEmptyLinesAtEOF: false
+LambdaBodyIndentation: Signature
+LineEnding: DeriveLF
+MacroBlockBegin: ''
+MacroBlockEnd: ''
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: None
+ObjCBinPackProtocolList: Never
+ObjCBlockIndentWidth: 2
+ObjCBreakBeforeNestedBlockParam: true
+ObjCSpaceAfterProperty: false
+ObjCSpaceBeforeProtocolList: true
+PackConstructorInitializers: NextLine
+PenaltyBreakAssignment: 2
+PenaltyBreakBeforeFirstCallParameter: 1
+PenaltyBreakComment: 300
+PenaltyBreakFirstLessLess: 120
+PenaltyBreakOpenParenthesis: 0
+PenaltyBreakString: 1000
+PenaltyBreakTemplateDeclaration: 10
+PenaltyExcessCharacter: 1000000
+PenaltyIndentedWhitespace: 0
+PenaltyReturnTypeOnItsOwnLine: 200
+PointerAlignment: Left
+PPIndentWidth: -1
+QualifierAlignment: Leave
+RawStringFormats:
+ - Language: Cpp
+ Delimiters:
+ - cc
+ - CC
+ - cpp
+ - Cpp
+ - CPP
+ - 'c++'
+ - 'C++'
+ CanonicalDelimiter: ''
+ BasedOnStyle: google
+ - Language: TextProto
+ Delimiters:
+ - pb
+ - PB
+ - proto
+ - PROTO
+ EnclosingFunctions:
+ - EqualsProto
+ - EquivToProto
+ - PARSE_PARTIAL_TEXT_PROTO
+ - PARSE_TEST_PROTO
+ - PARSE_TEXT_PROTO
+ - ParseTextOrDie
+ - ParseTextProtoOrDie
+ - ParseTestProto
+ - ParsePartialTestProto
+ CanonicalDelimiter: pb
+ BasedOnStyle: google
+ReferenceAlignment: Pointer
+ReflowComments: true
+RemoveBracesLLVM: false
+RemoveParentheses: Leave
+RemoveSemicolon: false
+RequiresClausePosition: OwnLine
+RequiresExpressionIndentation: OuterScope
+SeparateDefinitionBlocks: Leave
+ShortNamespaceLines: 1
+SortIncludes: CaseSensitive
+SortJavaStaticImport: Before
+SortUsingDeclarations: LexicographicNumeric
+SpaceAfterCStyleCast: false
+SpaceAfterLogicalNot: false
+SpaceAfterTemplateKeyword: true
+SpaceAroundPointerQualifiers: Default
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCaseColon: false
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeJsonColon: false
+SpaceBeforeParens: ControlStatements
+SpaceBeforeParensOptions:
+ AfterControlStatements: true
+ AfterForeachMacros: true
+ AfterFunctionDefinitionName: false
+ AfterFunctionDeclarationName: false
+ AfterIfMacros: true
+ AfterOverloadedOperator: false
+ AfterRequiresInClause: false
+ AfterRequiresInExpression: false
+ BeforeNonEmptyParentheses: false
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceBeforeSquareBrackets: false
+SpaceInEmptyBlock: false
+SpacesBeforeTrailingComments: 2
+SpacesInAngles: Never
+SpacesInContainerLiterals: true
+SpacesInLineCommentPrefix:
+ Minimum: 1
+ Maximum: -1
+# Clang Format >v17
+#SpacesInParens: Never
+#SpacesInParensOptions:
+# InCStyleCasts: false
+# InConditionalStatements: false
+# InEmptyParentheses: false
+# Other: false
+SpacesInSquareBrackets: false
+Standard: Auto
+StatementAttributeLikeMacros:
+ - Q_EMIT
+StatementMacros:
+ - Q_UNUSED
+ - QT_REQUIRE_VERSION
+TabWidth: 4
+UseTab: Never
+VerilogBreakBetweenInstancePorts: true
+WhitespaceSensitiveMacros:
+ - BOOST_PP_STRINGIZE
+ - CF_SWIFT_NAME
+ - NS_SWIFT_NAME
+ - PP_STRINGIZE
+ - STRINGIZE
+...
+
diff --git a/.editorconfig b/.editorconfig
index 3418f791..812a2953 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -5,7 +5,7 @@ root = true
[*]
charset = utf-8
-indent_style = tab
+indent_style = space
indent_size = 4
end_of_line = lf
insert_final_newline = true
diff --git a/.github/workflows/cmake-multi-platform.yml b/.github/workflows/cmake-multi-platform.yml
new file mode 100644
index 00000000..21d47395
--- /dev/null
+++ b/.github/workflows/cmake-multi-platform.yml
@@ -0,0 +1,134 @@
+# This starter workflow is for a CMake project running on multiple platforms. There is a different starter workflow if you just want a single platform.
+# See: https://github.com/actions/starter-workflows/blob/main/ci/cmake-single-platform.yml
+name: CMake on multiple platforms
+
+on:
+ push:
+ branches: [ "master", "develop" ]
+ pull_request:
+ branches: [ "master", "develop" ]
+
+jobs:
+ build:
+ runs-on: ${{ matrix.os }}
+
+ strategy:
+ # Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable.
+ fail-fast: false
+
+ # Set up a matrix to run the following 3 configurations:
+ # 1.
+ # 2.
+ # 3.
+ #
+ # To add more build types (Release, Debug, RelWithDebInfo, etc.) customize the build_type list.
+ matrix:
+ os: [ubuntu-latest, windows-latest]
+ build_type: [Release, Debug]
+ c_compiler: [gcc, clang, cl]
+ include:
+ - os: windows-latest
+ c_compiler: cl
+ cpp_compiler: cl
+ - os: ubuntu-latest
+ c_compiler: gcc
+ cpp_compiler: g++
+ - os: ubuntu-latest
+ c_compiler: clang
+ cpp_compiler: clang++
+ exclude:
+ - os: windows-latest
+ c_compiler: gcc
+ - os: windows-latest
+ c_compiler: clang
+ - os: ubuntu-latest
+ c_compiler: cl
+
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ submodules: recursive
+
+ - name: Install Mosquitto (ubuntu)
+ if: matrix.os == 'ubuntu-latest'
+ run: |
+ sudo apt-add-repository ppa:mosquitto-dev/mosquitto-ppa
+ sudo apt-get update
+ sudo apt-get -y install mosquitto
+
+# TODO: Figure out how to install and run mosquitto on Windows for unit tests.
+
+# - name: Install Mosquitto from Source (windows)
+# if: matrix.os == 'windows-latest'
+# run: |
+# git clone https://github.com/eclipse/mosquitto.git
+# cd mosquitto
+# git checkout "v2.0.18"
+# mkdir build && cd build
+# cmake .. -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }}
+# cmake --build . --target install
+# "C:\Program Files\mosquitto\mosquitto install"
+
+ - name: Install Catch2 v2 from Source (ubuntu)
+ if: matrix.os == 'ubuntu-latest'
+ run: |
+ git clone https://github.com/catchorg/Catch2.git
+ cd Catch2
+ git checkout "v2.13.8"
+ mkdir build && cd build
+ cmake .. -DBUILD_TESTING=OFF -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }}
+ sudo cmake --build . --target install
+
+ - name: Install Catch2 v2 from Source (windows)
+ # For Windows, it's important to build Catch2 with the same 'build_type'
+ # as the Paho C++ library, so that they link without errors.
+ if: matrix.os == 'windows-latest'
+ run: |
+ git clone https://github.com/catchorg/Catch2.git
+ cd Catch2
+ git checkout "v2.13.8"
+ mkdir build && cd build
+ cmake .. -DBUILD_TESTING=OFF -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }}
+ cmake --build . --config ${{ matrix.build_type }} --target install
+
+ - name: Set reusable strings
+ # Turn repeated input strings (such as the build output directory) into step outputs.
+ # These step outputs can be used throughout the workflow file.
+ id: strings
+ shell: bash
+ run: |
+ echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT"
+
+ - name: Configure CMake
+ # We configure to build the examples, unit tests, and Paho C library.
+ #
+ # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required
+ # if you are using a single-configuration generator such as make.
+ # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
+ run: >
+ cmake -B ${{ steps.strings.outputs.build-output-dir }}
+ -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }}
+ -DCMAKE_C_COMPILER=${{ matrix.c_compiler }}
+ -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
+ -DPAHO_BUILD_EXAMPLES=ON
+ -DPAHO_BUILD_TESTS=ON
+ -DPAHO_WITH_MQTT_C=ON
+ -S ${{ github.workspace }}
+
+ - name: Build
+ # Build your program with the given configuration. Note that --config is
+ # needed for Windows because the default Windows generator is a multi-config
+ # generator (Visual Studio generator).
+ run: cmake --build ${{ steps.strings.outputs.build-output-dir }} --config ${{ matrix.build_type }}
+
+ - name: Test
+ if: matrix.os == 'ubuntu-latest'
+ working-directory: ${{ steps.strings.outputs.build-output-dir }}
+ # Execute tests defined by the CMake configuration.
+ # Note that --build-config is needed because the default Windows generator
+ # is a multi-config generator (Visual Studio generator).
+ # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
+ run: ctest --build-config ${{ matrix.build_type }}
diff --git a/.gitignore b/.gitignore
index 60ca950b..86a3e8b2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,8 @@ obj/
.deps/
.libs/
*.vp*
+*.vtg
+*~
aclocal.m4
# AC_CONFIG_AUX_DIR created by /bootstrap
autotools_build/
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 00000000..462e4bdb
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "src/externals/paho-mqtt-c"]
+ path = externals/paho-mqtt-c
+ url = https://github.com/eclipse/paho.mqtt.c.git
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 0dd5f455..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,166 +0,0 @@
-language: cpp
-sudo: required
-dist: xenial
-os: linux
-
-before_install:
- - ./install_catch2.sh
- - ./travis_install.sh
-
-install:
- # Install Paho MQTT C (Need only paho-mqtt3a and paho-mqtt3as)
- - ./install_paho_mqtt_c.sh
-
-addons:
- apt:
- sources:
- - sourceline: 'ppa:mosquitto-dev/mosquitto-ppa'
- packages:
- - cppcheck
- - git
- - cmake
- - cmake-data
- - doxygen
- - mosquitto
-
-matrix:
- include:
- # GCC 5
- - compiler: gcc
- addons:
- apt:
- sources:
- - ubuntu-toolchain-r-test
- - sourceline: 'ppa:mosquitto-dev/mosquitto-ppa'
- packages:
- - g++-5
- - cppcheck
- - git
- - cmake
- - cmake-data
- - doxygen
- - mosquitto
- env: COMPILER=g++-5
- # GCC 6
- - compiler: gcc
- addons:
- apt:
- sources:
- - ubuntu-toolchain-r-test
- - sourceline: 'ppa:mosquitto-dev/mosquitto-ppa'
- packages:
- - g++-6
- - cppcheck
- - git
- - cmake
- - cmake-data
- - doxygen
- - mosquitto
- env: COMPILER=g++-6
- # GCC 7
- - compiler: gcc
- addons:
- apt:
- sources:
- - ubuntu-toolchain-r-test
- - sourceline: 'ppa:mosquitto-dev/mosquitto-ppa'
- packages:
- - g++-7
- - cppcheck
- - git
- - cmake
- - cmake-data
- - doxygen
- - mosquitto
- env: COMPILER=g++-7
- # GCC 8
- - compiler: gcc
- addons:
- apt:
- sources:
- - ubuntu-toolchain-r-test
- - sourceline: 'ppa:mosquitto-dev/mosquitto-ppa'
- packages:
- - g++-8
- - cppcheck
- - git
- - cmake
- - cmake-data
- - doxygen
- - mosquitto
- env: COMPILER=g++-8
- # Clang 3.9
- - compiler: clang
- addons:
- apt:
- sources:
- - ubuntu-toolchain-r-test
- - sourceline: 'ppa:mosquitto-dev/mosquitto-ppa'
- packages:
- - clang-3.9
- - cppcheck
- - git
- - cmake
- - cmake-data
- - doxygen
- - mosquitto
- env: COMPILER=clang++-3.9
- # Clang 4.0
- - compiler: clang
- addons:
- apt:
- sources:
- - ubuntu-toolchain-r-test
- - sourceline: 'ppa:mosquitto-dev/mosquitto-ppa'
- packages:
- - clang-4.0
- - cppcheck
- - git
- - cmake
- - cmake-data
- - doxygen
- - mosquitto
- env: COMPILER=clang++-4.0
- # Clang 7
- - compiler: clang
- addons:
- apt:
- sources:
- - ubuntu-toolchain-r-test
- - llvm-toolchain-xenial-7
- - sourceline: 'ppa:mosquitto-dev/mosquitto-ppa'
- packages:
- - clang-7
- - cppcheck
- - git
- - cmake
- - cmake-data
- - doxygen
- - mosquitto
- env: COMPILER=clang++-7
- # Clang 8
- - compiler: clang
- addons:
- apt:
- sources:
- - ubuntu-toolchain-r-test
- - llvm-toolchain-xenial-8
- - sourceline: 'ppa:mosquitto-dev/mosquitto-ppa'
- packages:
- - clang-8
- - cppcheck
- - git
- - cmake
- - cmake-data
- - doxygen
- - mosquitto
- env: COMPILER=clang++-8
- exclude:
- - compiler: gcc
-
-script:
- # Test build
- - ./travis_build.sh
- # Static Analysis
- - cppcheck --enable=all --std=c++11 --force --quiet src/*.cpp
-
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b6fabc73..f243838d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,169 @@
# Change Log
-
-## Version 1.2.0 (2020-12-27)
+#
+# Eclipse Paho MQTT C++ Library
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## Unreleased
+
+- Fixed `topic_matcher` and `topic_filter` to properly match parent with multi-level ('#') wildcard.
+- Slight optimization of `topic_filter` to do simple string comparison if the filter does not contain wildcards.
+- [#556](https://github.com/eclipse-paho/paho.mqtt.cpp/pull/556) fix potential deadlock in `thread_queue` on capacity increase.
+- [#559](https://github.com/eclipse-paho/paho.mqtt.cpp/pull/559) prevent undefined behaviour on empty topic matching
+
+## [Version 1.5.3](https://github.com/eclipse/paho.mqtt.cpp/compare/v1.5.2..v1.5.3) (2025-05-15)
+
+- Fix the bundled Paho C build foc C23 compilers by forcing C99 compliance in CMake build
+- [#544](https://github.com/eclipse-paho/paho.mqtt.cpp/pull/544) and [#550](https://github.com/eclipse-paho/paho.mqtt.cpp/pull/550) Use std::vector for the ALPN protocol list in wire format
+- [#547](https://github.com/eclipse-paho/paho.mqtt.cpp/pull/547) Fixed up some of the v5 examples for proper connect options
+- [#549](https://github.com/eclipse-paho/paho.mqtt.cpp/pull/549) Update TEST_EXTERNAL_SERVER urls
+
+
+## [Version 1.5.2](https://github.com/eclipse/paho.mqtt.cpp/compare/v1.5.1..v1.5.2) (2025-03-11)
+
+- Fixed the Version number and string.
+- Synchronous `Client` constructors updated to use `persistence_type` and (just) `create_options`
+ - Restored compatibility with `async_client`
+- [#505](https://github.com/eclipse-paho/paho.mqtt.cpp/issues/505): Example of retrieving MQTT v5 properties in message received callback
+- [#537](https://github.com/eclipse-paho/paho.mqtt.cpp/issues/537) Fixed the Windows DLL build by exporting message::EMPTY_STR and message::EMPTY_BIN
+- [#540](https://github.com/eclipse-paho/paho.mqtt.cpp/issues/537) Missing default argument in `async_client` changed constructor breaks code compatibility
+
+
+## [Version 1.5.1](https://github.com/eclipse/paho.mqtt.cpp/compare/v1.5.0..v1.5.1) - (2025-02-09)
+
+- Minor fixes to README and docs
+- [#532](https://github.com/eclipse-paho/paho.mqtt.cpp/pull/532) Fix CMake install target lib path
+- [#534](https://github.com/eclipse-paho/paho.mqtt.cpp/issues/534) Fixed seg fault with clang in get_topic() when publishing a message
+- [#535](https://github.com/eclipse-paho/paho.mqtt.cpp/issues/535) Fixed last few files that were not properly licenced for EPL v2.0
+
+
+## [Version 1.5.0](https://github.com/eclipse/paho.mqtt.cpp/compare/v1.4.1..v1.5.0) - (2025-01-07)
+
+- Code base updated to to C++17
+ - Now a C++17 compiler is required to compile the library
+- CMake minimum required version raised to v3.13
+ - Need a fairly recent CMake for C++17 support (>= v3.12)
+ - [#504](https://github.com/eclipse-paho/paho.mqtt.cpp/issues/504) CMake v3.13 allows INSTALL(TARGETS) to work outside the current directory.
+- Clients always created for v5 persistence format, making it universal for any connection.
+ - If the application specifies a version it is kept as a hint for default connections.
+ - The version for the connection should be specified in the connect options.
+- The `create_options` now have all the parameters to create a client.
+ - Can specify Server URL, Client ID, and persistence in the create options.
+ - New client constructor that takes just the options object
+ - The client caches a const `create_options` struct with all the creation parameters
+ - Client creation internally simplified without breaking the public API
+- Expanded the message constmer to be a full client "event" consumer.
+ - The events are for *connected, connection_lost, disconnected, message arrived,* and application *shutdown.*
+ - The application can get client state change notifications without resorting to callbacks.
+- There's a new `persistence_type` (std::variant) that can hold any of the persistence specifiers (none, file directory, or user interface).
+- Most of the class static constants are now `constexpr`.
+- Removed the fake `ReasonCode::MQTTPP_V3_CODE`. Now all reason codes in a v3 connection are SUCCESS.
+- The `mqtt::exception` checks if the 'rc' return code actually contains a reason code error, amd if so, sets it as the reason code.
+- `property` can now report the `typeid` of its contained value.
+- The `properties` list implements a const iterator
+- Added a `to_string()` and `operator<<()` for reason codes.
+- `thread_queue` is now closable.
+- Added documentation for UNIX domain sockets coming in with Paho C v1.3.14
+- Removed the manual implementation of `make_unique<>()`
+- Added `create_options` assignment operators.
+- Fixed some corner cases for topic_filter::matches()
+- Cleaned up and fixed a number of example apps.
+ - Most apps now except a server URI from the command line
+ - 'data_publish' example uses C++17 std::filesystem for creating a file-based encrypted persistence for messages.
+- Updated local CI (buildtst.sh) for current compilers and unit tests.
+- Reorganized the source repository
+- Completely reformat the sources and added a .clang-format file (a project master and a slightly-different one for headers).
+- Added GitHub CI Action, removing legacy Travis and Appveyor files
+- [#410](https://github.com/eclipse-paho/paho.mqtt.cpp/issues/410) Added 'shutdown_event' to the event consumer and reworked consumer to prevent propagating exceptions on shutdown.
+- [#451](https://github.com/eclipse-paho/paho.mqtt.cpp/issues/451) Added low keep alive to async_publish_time to test connected/connection_lost callbacks
+- [#503](https://github.com/eclipse-paho/paho.mqtt.cpp/issues/503) Fixed issue that generated docs were empty.
+- [#518](https://github.com/eclipse-paho/paho.mqtt.cpp/pull/518) Add function for checking async consumer event queue size
+- [#519](https://github.com/eclipse-paho/paho.mqtt.cpp/pull/519) Fix potential deadlock in set_callback
+- [#524](https://github.com/eclipse-paho/paho.mqtt.cpp/issues/524) Fixed copy and move operations for 'subscribe_options'. Added unit tests.
+
+
+## [Version 1.4.1](https://github.com/eclipse/paho.mqtt.cpp/compare/v1.4.0..v1.4.1) - (2024-07-09)
+
+- [#458](https://github.com/eclipse/paho.mqtt.cpp/issues/458) Set 'disconnected' handler for the consumer queue.
+
+
+## [Version 1.4.0](https://github.com/eclipse/paho.mqtt.cpp/compare/v1.3.2..v1.4.0) - (2024-06-16)
+
+- Ability to build the Paho C library automatically (now working properly)
+ - CMake 'PAHO_WITH_MQTT_C' option properly compiles the existing Paho C v1.3.13
+ - Moved 'src/externals/' to top-level
+- Reorganized the source tree:
+ - Moved header files to top-level 'include/' directory.
+ - Moved 'src/sampless/' to top-level and renamed 'examples/'
+- Fixed and optimized 'topic_matcher' trie collection
+- Added some missing Eclipse/Paho legal documents to the repo.
+- Ran a spell-checker over the code and doc files.
+
+- [#498](https://github.com/eclipse/paho.mqtt.cpp/issues/498) Overloaded property constructor to also take a uint32_t
+- [#491](https://github.com/eclipse/paho.mqtt.cpp/pull/491) add topic_matcher.h to install
+- [#485](https://github.com/eclipse/paho.mqtt.cpp/pull/485) export dependencies
+- [#484](https://github.com/eclipse/paho.mqtt.cpp/pull/484) add token::get_message
+- [#480](https://github.com/eclipse/paho.mqtt.cpp/issues/480) Fixed Paho C version in 'install_paho_mqtt_c.sh' script.
+- [#473](https://github.com/eclipse/paho.mqtt.cpp/issues/473) Getter for the client's cached connect options.
+- [#466](https://github.com/eclipse/paho.mqtt.cpp/pull/466) Iterable string collection
+- [#416](https://github.com/eclipse/paho.mqtt.cpp/issues/416) Removed FindPahoMqttC.cmake. Using Paho C package directly.
+
+
+## [Version 1.3.2](https://github.com/eclipse/paho.mqtt.cpp/compare/v1.3.1..v1.3.2) - (2023-12-05)
+
+- [#463](https://github.com/eclipse/paho.mqtt.cpp/issues/463) Fixed generator expression for older CMake
+- [#378](https://github.com/eclipse/paho.mqtt.cpp/issues/378) Bad LWT message in async_publish.cpp sample.
+
+
+## [Version 1.3.1](https://github.com/eclipse/paho.mqtt.cpp/compare/v1.3.0..v1.3.1) - (2023-11-23)
+
+- [#462](https://github.com/eclipse/paho.mqtt.cpp/pull/462) Fix version string for version v1.3.x
+
+
+## [Version 1.3.0](https://github.com/eclipse/paho.mqtt.cpp/compare/v1.2.0..v1.3.0) - (2023-11-22)
+
+- Fixed building and using library as DLL on Windows with MSVC
+- Updated License to Eclipse Public License v2.0
+- Updated create and connect options to better deal with MQTT protocol version
+- Defaulting connect version to v5 if specified in create options.
+- Added a `topic_filter` class to match a single filter to specific topics.
+- Added a `topic_matcher` class to create a collection of items in a trie structure that can contain items tied to topic filters. (Useful for queues or callbacks per-subscription topic).
+- Minor tweaks to prepare for C++20
+- Support for Catch2 v3.x for unit tests (v2.x also still supported).
+- Changed the sample apps to use the newer "mqtt://" schemas.
+- Connect option initializers for v5 and WebSockets.
+
+Fixed Issues and Pull Requests:
+
+- [#343](https://github.com/eclipse/paho.mqtt.cpp/issues/343) async_client::try_consume_message_until taking single parameter fails to compile
+- [#445](https://github.com/eclipse/paho.mqtt.cpp/pull/445) Update properties when moving/copying connect options.
+- [#325](https://github.com/eclipse/paho.mqtt.cpp/issues/325) Cache connect options in client to keep memory valid for callbacks like SSL on_error()
+- [#361](https://github.com/eclipse/paho.mqtt.cpp/issues/361) Added missing LICENSE file to conform to GitHub conventions.
+- [#304](https://github.com/eclipse/paho.mqtt.cpp/issues/304) Missing create_options::DFLT_C_STRUCT symbol when linking with MSVC.
+- [#429](https://github.com/eclipse/paho.mqtt.cpp/issues/429) Remove declaration of connect_options::to_string() with missing implementation.
+- [#411](https://github.com/eclipse/paho.mqtt.cpp/issues/411) Missing virtual keyword for some client methods
+- [#444](https://github.com/eclipse/paho.mqtt.cpp/issues/444) Unit tests to check that connect options builder sets properties.
+- [#313](https://github.com/eclipse/paho.mqtt.cpp/issues/313) Get unit tests building on Windows. Needed to get rid of make_unique<> for Windows
+- [#397](https://github.com/eclipse/paho.mqtt.cpp/issues/397) Doc about clean session in connect_options.h is wrong
+- [#442](https://github.com/eclipse/paho.mqtt.cpp/issues/442) g++ complains with multiple definition of static constexpr for mixed C++11/17 builds
+- [#445](https://github.com/eclipse/paho.mqtt.cpp/pull/445)Fix copy/move constructor for connect/disconnect opts with properties
+- [#425](https://github.com/eclipse/paho.mqtt.cpp/pull/425) Silence warning for unused variable rsp in class `unsubscribe_response`
+- [#440](https://github.com/eclipse/paho.mqtt.cpp/pull/440) Fix typos across the project
+- [#428](https://github.com/eclipse/paho.mqtt.cpp/issues/428) Fixed type in create_options.h
+- [#407](https://github.com/eclipse/paho.mqtt.cpp/pull/407) Fix nodiscard warnings in sync client
+- [#385](https://github.com/eclipse/paho.mqtt.cpp/issues/385) Thread queue deadlock with multiple consumers
+- [#374](https://github.com/eclipse/paho.mqtt.cpp/pull/374) Add Paho C as a submodeule
+- [#350](https://github.com/eclipse/paho.mqtt.cpp/pull/350) avoid adding Paho MQTT C library twice
+- [#253](https://github.com/eclipse/paho.mqtt.cpp/issues/253) implicit capture of 'this' via '[=]' is deprecated in C++20
+- [#337](https://github.com/eclipse/paho.mqtt.cpp/issues/337) copy/move of caPath_ in ssl_options
+- [#330](https://github.com/eclipse/paho.mqtt.cpp/pull/330) added /build/ folder to .gitignore
+- [#317](https://github.com/eclipse/paho.mqtt.cpp/issues/317) String constructor using just len instead of end iterator.
+- [#323](https://github.com/eclipse/paho.mqtt.cpp/issues/323) Added Session Expiry Interval to v5 chat sample to test.
+
+
+## [Version 1.2.0](https://github.com/eclipse/paho.mqtt.cpp/compare/v1.1..v1.2.0) - (2020-12-27)
This release bring in some missing MQTT v5 features, brings in support for websocket headers and proxies, ALPN protocol lists, adds the builder pattern for options, and fixes a number of bugs in both the C++ library and the underlying C lib.
@@ -36,7 +199,6 @@ Requires Paho C v1.3.8
- Several memory issues and bug fixes from updated Paho C library support.
-
## Version 1.1 (2019-10-12)
This release was primarily to add MQTT v5 support and server responses.
@@ -49,17 +211,18 @@ This release was primarily to add MQTT v5 support and server responses.
- Properties can also be obtained from server responses to requests such as from a _connect_ call. These are available in the `token` objects when they complete.
- The client object tracks the desired MQTT version that the app requested and/or is currently connected at. Internally this is now required by the `response_options` the need to distinguish between pre-v5 and post-v5 callback functions.
- MQTT v5 reason codes for requests are available via `token` objects when they complete. They are also available in `exception` objects that are thrown by tokens.
- - Support for subscibe options, like no local subscriptions, etc.
+ - Support for subscribe options, like no local subscriptions, etc.
- Sample applications were added showing how to do basic Remote Procedure Calls (RPC's) with MQTT v5 using the *RESPONSE_TOPIC* and *CORRELATION_DATA* properties. These are *rpc_math_cli* and *rpc_math_srvr* in the _src/samples_ directory.
- A sample "chat" application was added, showing how to use subscribe options, such as "no local".
- More descriptive error messages (PR #154), integrated into the `mqtt::exception` class. MQTT v5 reason codes are also included in the exceptions when an error occurs.
- Applications can (finally) get server responses from the various ACK packets. These are available through the tokens after they complete, as `connect_response`, `subscribe_response`, and `unsubscribe_response`.
- The `topic` objects can be used to subscribe.
- Applications can register individual callback functions instead of using a `callback` interface object. This allows easy use of lambda functions for callbacks.
-- The connect options can take a LWT as a plain message, via `connect_options::set_will_message()`
+- The connect options can take a LWT as a plain message, via `connect_options::set_will_message()`
- New unit tests have started using _Catch2_.
- Tested with Paho C v1.3.1
+
## Version 1.0.1 (2018-12-12)
This is a bug-fix released aimed mainly at issues with the build system and working towards more "modern" usage of CMake. In addition:
@@ -75,7 +238,7 @@ This is a bug-fix released aimed mainly at issues with the build system and work
The initial Paho C++ Client library for memory-managed platforms (Linux, Windows, etc).
- Requires Paho C Client Library v1.2.
-- MQTT 3.1 & 3.1.1
+- MQTT 3.1 & 3.1.1
- SSL/TLS
- Asynchronous & Synchronous interfaces
- Persistence and off-line buffering
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c85ac9b0..33658ec7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -5,15 +5,15 @@
#*******************************************************************************
# This is part of the Paho MQTT C++ client library.
#
+# Copyright (c) 2017-2025, Frank Pagliughi
# Copyright (c) 2016-2017, Guilherme Maciel Ferreira
-# Copyright (c) 2017, Frank Pagliughi
#
# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
+# are made available under the terms of the Eclipse Public License v2.0
# and Eclipse Distribution License v1.0 which accompany this distribution.
#
# The Eclipse Public License is available at
-# http://www.eclipse.org/legal/epl-v10.html
+# http://www.eclipse.org/legal/epl-v20.html
# and the Eclipse Distribution License is available at
# http://www.eclipse.org/org/documents/edl-v10.php.
#
@@ -22,56 +22,102 @@
# Frank Pagliughi
#*******************************************************************************/
-## Note: on OS X you should install XCode and the associated command-line tools
+cmake_minimum_required(VERSION 3.13)
-## cmake flags
-cmake_minimum_required(VERSION 3.5)
-
-## project name
-project("paho-mqtt-cpp"
- VERSION "1.2.0"
- LANGUAGES CXX
-)
+project(PahoMqttCpp VERSION "1.5.4")
## --- Build options ---
if(WIN32)
- option(PAHO_BUILD_STATIC "Build static library" TRUE)
- option(PAHO_BUILD_SHARED "Build shared library (DLL)" FALSE)
- option(PAHO_WITH_SSL "Build SSL-enabled library" FALSE)
+ option(PAHO_BUILD_STATIC "Build static library" TRUE)
+ option(PAHO_BUILD_SHARED "Build shared library (DLL)" FALSE)
+ option(PAHO_WITH_SSL "Build SSL-enabled library" FALSE)
else()
- option(PAHO_BUILD_STATIC "Build static library" FALSE)
- option(PAHO_BUILD_SHARED "Build shared library" TRUE)
- option(PAHO_WITH_SSL "Build SSL-enabled library" TRUE)
- option(PAHO_BUILD_DEB_PACKAGE "Build debian package" FALSE)
+ option(PAHO_BUILD_STATIC "Build static library" FALSE)
+ option(PAHO_BUILD_SHARED "Build shared library" TRUE)
+ option(PAHO_WITH_SSL "Build SSL-enabled library" TRUE)
+ option(PAHO_BUILD_DEB_PACKAGE "Build debian package" FALSE)
endif()
-option(PAHO_BUILD_SAMPLES "Build sample programs" FALSE)
-option(PAHO_BUILD_TESTS "Build tests" FALSE)
+option(PAHO_BUILD_SAMPLES "Build sample/example programs" FALSE)
+option(PAHO_BUILD_EXAMPLES "Build sample/example programs" FALSE)
+option(PAHO_BUILD_TESTS "Build tests (requires Catch2)" FALSE)
option(PAHO_BUILD_DOCUMENTATION "Create and install the API documentation (requires Doxygen)" FALSE)
+option(PAHO_WITH_MQTT_C "Build Paho C from the internal GIT submodule." FALSE)
+
+if(NOT PAHO_BUILD_SHARED AND NOT PAHO_BUILD_STATIC)
+ message(FATAL_ERROR "You must set either PAHO_BUILD_SHARED, PAHO_BUILD_STATIC, or both")
+endif()
-## --- C++11 build flags ---
+# --- Setting naming variables ---
-set(CMAKE_CXX_STANDARD 11)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-set(CMAKE_CXX_EXTENSIONS OFF)
+set(PAHO_MQTTPP_GENERATED_DIR ${CMAKE_CURRENT_BINARY_DIR}/generated)
-# Generate position-independent code (-fPIC on UNIX)
-set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+## --- Find Paho C or build it, if reqested ---
-# --- System Libraries ---
+if(PAHO_WITH_SSL)
+ find_package(OpenSSL REQUIRED)
+ set(PAHO_MQTT_C_LIB eclipse-paho-mqtt-c::paho-mqtt3as)
+else()
+ set(PAHO_MQTT_C_LIB eclipse-paho-mqtt-c::paho-mqtt3a)
+endif()
+
+if(PAHO_WITH_MQTT_C)
+ message(STATUS "Paho C: Bundled")
+
+ ## Build the Paho C library from the submodule
+ set(PAHO_ENABLE_TESTING FALSE CACHE BOOL "No Paho C tests")
+ set(PAHO_HIGH_PERFORMANCE TRUE CACHE BOOL "Paho C high performance")
+ if(NOT WIN32)
+ set(PAHO_WITH_UNIX_SOCKETS TRUE CACHE BOOL "Support for Unix-domain sockets")
+ endif()
+ set(CMAKE_C_STANDARD 99 CACHE STRING "Paho C language standard")
+
+ add_subdirectory(${PROJECT_SOURCE_DIR}/externals/paho-mqtt-c)
+
+ ## Alias namespace so that the full names can be used with the subdir.
+ if(PAHO_BUILD_SHARED)
+ add_library(eclipse-paho-mqtt-c::paho-mqtt3a ALIAS paho-mqtt3a)
+ list(APPEND PAHO_MQTT_C_LIBS paho-mqtt3a)
+ if(PAHO_WITH_SSL)
+ add_library(eclipse-paho-mqtt-c::paho-mqtt3as ALIAS paho-mqtt3as)
+ list(APPEND PAHO_MQTT_C_LIBS paho-mqtt3as)
+ endif()
+ endif()
+
+ if(PAHO_BUILD_STATIC)
+ add_library(eclipse-paho-mqtt-c::paho-mqtt3a-static ALIAS paho-mqtt3a-static)
+ list(APPEND PAHO_MQTT_C_LIBS paho-mqtt3a-static)
+ if(PAHO_WITH_SSL)
+ add_library(eclipse-paho-mqtt-c::paho-mqtt3as-static ALIAS paho-mqtt3as-static)
+ list(APPEND PAHO_MQTT_C_LIBS paho-mqtt3as-static)
+ endif()
+ endif()
+
+ ## install paho.mqtt.c library (appending to PahoMqttCpp export)
+ install(TARGETS ${PAHO_MQTT_C_LIBS}
+ EXPORT PahoMqttCpp
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ )
+else()
+ find_package(eclipse-paho-mqtt-c REQUIRED)
+endif()
+
+# --- System Details ---
include(GNUInstallDirs)
if(WIN32)
- add_definitions(-D_CRT_SECURE_NO_WARNINGS)
+ add_definitions(-D_CRT_SECURE_NO_WARNINGS)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
set(LIBS_SYSTEM ws2_32)
-elseif(UNIX)
- set(LIBS_SYSTEM c stdc++)
endif()
-## --- Build directories ---
+# --- The headers ---
+
+add_subdirectory(include/mqtt)
# For the paho_mqtt_c module
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
@@ -83,26 +129,28 @@ if(PAHO_BUILD_DOCUMENTATION)
add_subdirectory(doc)
endif()
-# --- Default library for samples and unit tests ---
-
-if(PAHO_BUILD_SHARED)
- set(PAHO_CPP_LIB paho-mqttpp3)
-else()
- set(PAHO_CPP_LIB paho-mqttpp3-static)
-endif()
-
-# --- Sample Apps ---
+# --- Example Apps ---
-if(PAHO_BUILD_SAMPLES)
- add_subdirectory(src/samples)
+if(PAHO_BUILD_SAMPLES OR PAHO_BUILD_EXAMPLES)
+ add_subdirectory(examples)
endif()
# --- Unit Tests ---
if(PAHO_BUILD_TESTS)
+ enable_testing()
add_subdirectory(test/unit)
endif()
+## --- Install generated header(s) ---
+
+install(
+ DIRECTORY
+ ${PAHO_MQTTPP_GENERATED_DIR}/include/
+ DESTINATION
+ ${CMAKE_INSTALL_INCLUDEDIR}
+)
+
## --- Packaging settings ---
if(WIN32)
@@ -117,6 +165,8 @@ elseif(UNIX)
endif()
include(CPack)
-add_subdirectory(cmake)
+# --- Export CMake TARGETS ---
+
+add_subdirectory(cmake)
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 00000000..3d5d776f
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,47 @@
+# Community Code of Conduct
+
+**Version 1.2
+August 19, 2020**
+
+## Our Pledge
+
+In the interest of fostering an open and welcoming environment, we as community members, contributors, committers, and project leaders pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
+
+## Our Standards
+
+Examples of behavior that contributes to creating a positive environment include:
+
+* Using welcoming and inclusive language
+* Being respectful of differing viewpoints and experiences
+* Gracefully accepting constructive criticism
+* Focusing on what is best for the community
+* Showing empathy towards other community members
+
+Examples of unacceptable behavior by participants include:
+
+* The use of sexualized language or imagery and unwelcome sexual attention or advances
+* Trolling, insulting/derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or electronic address, without explicit permission
+* Other conduct which could reasonably be considered inappropriate in a professional setting
+
+## Our Responsibilities
+
+With the support of the Eclipse Foundation staff (the “Staff”), project committers and leaders are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
+
+Project committers and leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
+
+## Scope
+
+This Code of Conduct applies within all project spaces, and it also applies when an individual is representing the Eclipse Foundation project or its community in public spaces. Examples of representing a project or community include posting via an official social media account, or acting as a project representative at an online or offline event. Representation of a project may be further defined and clarified by project committers, leaders, or the EMO.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the Staff at codeofconduct@eclipse.org. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The Staff is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+
+Project committers or leaders who do not follow the Code of Conduct in good faith may face temporary or permanent repercussions as determined by the Staff.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org) , version 1.4, available at [https://www.contributor-covenant.org/version/1/4/code-of-conduct.html](https://www.contributor-covenant.org/version/1/4/code-of-conduct/)
+
diff --git a/CODING_STYLE.md b/CODING_STYLE.md
index ba0ed06d..4aadf8ce 100644
--- a/CODING_STYLE.md
+++ b/CODING_STYLE.md
@@ -18,13 +18,13 @@ The Paho C++ library attempts to follow the naming conventions of the C++ standa
- Class names are lower snake case: *classes_like_this*
- Function names are lower snake case: *functions_like_this*
- Variable names are lower camel case: *varsLikeThis*
- - Class memeber are lower camel case with a trailing underscore: *memVarsLikeThis_*
+ - Class members are lower camel case with a trailing underscore: *memVarsLikeThis_*
- Constants are all caps: *CONSTANTS_LIKE_THIS*
-
+
## Format Conventions
-The top-level project directory contains a _.editorconfig_ file with some basic hints as to formatting conventions for source files.
+The top-level project directory contains a _.editorconfig_ file with some basic hints as to formatting conventions for source files.
-A few minutes looking through the existing sources will reveal the basic styles used. Pull Requests should generally try to fit in to the existing style and not try to impose new ones.
+A few minutes looking through the existing sources will reveal the basic styles used. Pull Requests should generally try to fit in to the existing style and not try to impose new ones.
-At some point in the future, a formatter may be added to the project (probably Clang format), but until then, any sources that can be fixed up with an automated code generator or beautifier would generally be accepted into the project. But at some point soon after would then be reformat to fit into the overall conventions.
\ No newline at end of file
+At some point in the future, a formatter may be added to the project (probably Clang format), but until then, any sources that can be fixed up with an automated code generator or beautifier would generally be accepted into the project. But at some point soon after would then be reformat to fit into the overall conventions.
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 00000000..f7bcc4bc
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,13 @@
+Eclipse Public License - v 2.0
+
+This program and the accompanying materials
+are made available under the terms of the Eclipse Public License v2.0
+and Eclipse Distribution License v1.0 which accompany this distribution.
+
+The Eclipse Public License is available at
+ https://www.eclipse.org/legal/epl-20/
+and the Eclipse Distribution License is available at
+ http://www.eclipse.org/org/documents/edl-v10.php.
+
+For an explanation of what dual-licensing means to you, see:
+https://www.eclipse.org/legal/eplfaq.php#DUALLIC
diff --git a/NOTICE b/NOTICE
new file mode 100644
index 00000000..1cfcffde
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,55 @@
+# Notices for Eclipse Paho
+
+This content is produced and maintained by the Eclipse Paho project.
+
+* Project home: https://projects.eclipse.org/projects/iot.paho
+
+## Trademarks
+
+Paho™ is a trademark of the Eclipse Foundation.
+
+## Copyright
+
+All content is the property of the respective authors or their employers. For
+more information regarding authorship of content, please consult the listed
+source code repository logs.
+
+## Declared Project Licenses
+
+This program and the accompanying materials are made available under the terms
+of the Eclipse Public License v2.0 which is available at
+https://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
+v1.0 which is available at https://www.eclipse.org/org/documents/edl-v10.php.
+
+SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+
+## Source Code
+
+The project maintains the following source code repositories:
+
+* https://github.com/eclipse/paho-website
+* https://github.com/eclipse/paho.golang
+* https://github.com/eclipse/paho.mqtt-sn.embedded-c
+* https://github.com/eclipse/paho.mqtt-spy
+* https://github.com/eclipse/paho.mqtt.android
+* https://github.com/eclipse/paho.mqtt.c
+* https://github.com/eclipse/paho.mqtt.cpp
+* https://github.com/eclipse/paho.mqtt.d
+* https://github.com/eclipse/paho.mqtt.embedded-c
+* https://github.com/eclipse/paho.mqtt.golang
+* https://github.com/eclipse/paho.mqtt.java
+* https://github.com/eclipse/paho.mqtt.javascript
+* https://github.com/eclipse/paho.mqtt.m2mqtt
+* https://github.com/eclipse/paho.mqtt.python
+* https://github.com/eclipse/paho.mqtt.ruby
+* https://github.com/eclipse/paho.mqtt.rust
+* https://github.com/eclipse/paho.mqtt.testing
+
+## Cryptography
+
+Content may contain encryption software. The country in which you are currently
+may have restrictions on the import, possession, and use, and/or re-export to
+another country, of encryption software. BEFORE using any encryption software,
+please check the country's laws, regulations and policies concerning the import,
+possession, or use, and re-export of encryption software, to see if this is
+permitted.
diff --git a/README.md b/README.md
index 0af93a53..78ac016d 100644
--- a/README.md
+++ b/README.md
@@ -1,143 +1,139 @@
# Eclipse Paho MQTT C++ Client Library
-[](https://travis-ci.org/eclipse/paho.mqtt.cpp)
+This repository contains the source code for the [Eclipse Paho](http://eclipse.org/paho) MQTT C++ client library for memory-managed operating systems such as Linux, MacOS, and Windows.
-This repository contains the source code for the [Eclipse Paho](http://eclipse.org/paho) MQTT C++ client library on memory-managed operating systems such as Linux/Posix and Windows.
-
-This code builds a library which enables C++11 applications to connect to an [MQTT](http://mqtt.org) broker, publish messages to the broker, and to subscribe to topics and receive published messages.
+This code builds a library which enables Modern C++ applications (C++17 and beyond) to connect to an [MQTT](http://mqtt.org) broker, publish messages, subscribe to topics, and receive messages from the broker.
The library has the following features:
- Support for MQTT v3.1, v3.1.1, and v5.
- Network Transports:
- Standard TCP
+ - UNIX-domain sockets
- Secure sockets with SSL/TLS
- - WebSockets
+ - WebSockets
- Secure and insecure
- Proxy support
- Message persistence
- - User configurable
+ - User configurable
- Built-in File persistence
- User-defined key/value persistence easy to implement
- Automatic Reconnect
- Offline Buffering
- High Availability
-- Blocking and non-blocking API's
-- Modern C++ interface (C++11 and better)
+- Blocking and non-blocking APIs
+- Modern C++ interface (C++17)
-This code requires the [Paho C library](https://github.com/eclipse/paho.mqtt.c) by Ian Craggs, et al., specifically version 1.3.8 or possibly later.
+This code requires the [Paho C library](https://github.com/eclipse/paho.mqtt.c) by Ian Craggs, et al., specifically version 1.3.14 or possibly later.
## Latest News
To keep up with the latest announcements for this project, or to ask questions:
-**Twitter:** [@eclipsepaho](https://twitter.com/eclipsepaho) and [@fmpagliughi](https://twitter.com/fmpagliughi)
-
-**EMail:** [Eclipse Paho Mailing List](https://accounts.eclipse.org/mailing-list/paho-dev)
-
-**Mattermost:** [Eclipse Mattermost Paho Channel](https://mattermost.eclipse.org/eclipse/channels/paho)
-
-
-### Unreleased features in this branch
-
-- Added Session Expiry Interval to v5 chat sample
-- Minor tweaks to prepare for C++20
-- Minor cleanup of the tests
-[#317](https://github.com/eclipse/paho.mqtt.cpp/issues/317) String constructor using just len instead of end iterator.
-[#337](https://github.com/eclipse/paho.mqtt.cpp/issues/337) Copy and move constructors/assignment of `ssl_options` not handling CA path.
+**Email:** [Eclipse Paho Mailing List](https://accounts.eclipse.org/mailing-list/paho-dev)
+### What's New in v1.5.x
-### What's new in Version 1.2.0
+The latest updates for v1.5 moved the codebase to C++17 and added support for UNIX-domain sockets. They also fixed a number of build issues, now targeting the latest Paho C release, v1.3.14.
-This release brings in some missing MQTT v5 features, support for websocket headers and proxies, ALPN protocol lists, adds the builder pattern for options, and fixes a number of bugs in both the C++ library and the underlying C lib.
+The primary changes in the v1.5 versions are:
-Requires Paho C v1.3.8
+- Updated the code base to C++17
+- Support for the Paho C v1.3.14 release.
+ - Support for UNIX-domain sockets
+- Reorganize and reformat the sources and added a .clang-format capability.
+- Create universal client instances that can connect using v3 or v5. (i.e. no more instances that are only v3 capable)
+- Bump the CMake to v3.13
+- Fix a large number of CMake build issues
+- Updated the GitHub CI
+- (v1.5.3) Fixes for building this library and the Paho C library with the latest C & C++ compilers, like Clang 20 and GCC 15 which created some breaking hcanges for legacy code.
+- (v1.5.4) Fixes for `topic_matcher` and `topic_filter` to match against parent with the multi-field wildcard.
-- Missing MQTT v5 features:
- - Ability to add properties to Subscribe and Unsubscribe packets (i.e. subscription identifiers)
- - "Disconnected" callback gives reason code and properties for server disconnect
-- New `create_options` that can be used to construct a client with new features:
- - Send while disconnected before the 1st successful connection
- - Output buffer can delete oldest messages when full
- - Can choose to clear the persistence store on startup
- - Select whether to persist QoS 0 messages
-- Started classes to create options using the Builder Pattern, with the `create_options_builder`, `connect_options_builder`, `message_ptr_builder`, etc.
-- User-defined websocket HTTP headers.
-- HTTP/S proxy support
-- Added ALPN protocol support to SSL/TLS options
-- SSL/TLS error and PSK callback support
-- Update connection callback support (change credentials when using auto-reconnect)
-- Updates to the sample apps:
- - Overall cleanup with better consistency
- - Example of using websockets and a proxy
- - User-based file persistence with simple encoding/encryption
- - Sharing a client between multiple threads
-- Converted the unit tests to use Catch2
-- All library exceptions are now properly derived from the `mqtt::exception` base class.
-- [#231] Added `on_disconnected` callback to handle receipt of disconnect packet from server.
-- [#211, #223, #235] Removed use of Log() function from the Paho C library.
-- [#227] Fixed race condition in thread-safe queue
-- [#224] & [#255] Subscribing to MQTT v3 broker with array of one topic causes segfault.
-- [#282] Ability to build Debian/Ubuntu package
-- [#300] Calling `reconnect()` was hanging forever, even when successful. In addition several of the synchronous `client` calls were hanging forever on failure. They now properly throw a `timeout_error` exception.
-- Several memory issues and bug fixes from updated Paho C library support.
-
-### _Catch2_ Unit Tests
-
-Unit tests were converted to use _Catch2_ for the test framework.
-
-_Catch2_ can be found here: [Catch2](https://github.com/catchorg/Catch2)
+For the full list of updates in each release, see the [CHANGELOG](https://github.com/eclipse-paho/paho.mqtt.cpp/blob/master/CHANGELOG.md).
## Contributing
-Contributions to this project are gladly welcomed and appreciated Before submitting a Pull Request, please keep three things in mind:
+Contributions to this project are gladly welcomed and appreciated. Before submitting a Pull Request, please keep three things in mind:
- This is an official Eclipse project, so it is required that all contributors sign an [Eclipse Contributor Agreement (ECA)](https://www.eclipse.org/legal/ECA.php)
- Please submit all Pull Requests against the _develop_ branch (not master).
- Please sign all commits.
-
+
For full details, see [CONTRIBUTING.md](https://github.com/eclipse/paho.mqtt.cpp/blob/master/CONTRIBUTING.md).
-
+
## Building from source
-_CMake_ is a cross-platform build system suitable for Unix and non-Unix platforms such as Microsoft Windows. It is now the only supported build system.
+As of v1.5, the Paho C++ library uses C++17 features, thus requiring a fully compliant C++17 compiler. Some of the more common compilers that can be used, depending on the target platform, are:
-The Paho C++ library requires the Paho C library, v1.3.8 or greater, to be built and installed first. More information below.
+* GCC v8 or later
+* _clang_ v5 or later
+* Visual Studio 2017 15.8 (MSVC 19.15) or later
+
+_CMake_ is a cross-platform build system suitable for Unix and non-Unix platforms such as Microsoft Windows. It is the only supported build system. The current supported minimum version is:
+
+* cmake v3.13
+
+The Paho C++ library requires the Paho C library, v1.3.14 or greater to be built and installed. That can be done before building this library, or it can be done here using the CMake `PAHO_WITH_MQTT_C` build option to build both libraries at the same time. This also guarantees that a proper version of the C library is used, and that it is build with compatible options.
+
+### Build Options
CMake allows for options to direct the build. The following are specific to Paho C++:
Variable | Default Value | Description
------------ | ------------- | -------------
-PAHO_BUILD_SHARED | TRUE (Linux), FALSE (Win32) | Whether to build the shared library
-PAHO_BUILD_STATIC | FALSE (Linux), TRUE (Win32) | Whether to build the static library
-PAHO_BUILD_DOCUMENTATION | FALSE | Create and install the HTML based API documentation (requires Doxygen)
-PAHO_BUILD_SAMPLES | FALSE | Build sample programs
-PAHO_BUILD_TESTS | FALSE | Build the unit tests. (This requires _Catch2_)
-PAHO_WITH_SSL | TRUE (Linux), FALSE (Win32) | Flag that defines whether to build ssl-enabled binaries too
+PAHO_BUILD_SHARED | TRUE (*nix), FALSE (Win32) | Whether to build the shared library
+PAHO_BUILD_STATIC | FALSE (*nix), TRUE (Win32) | Whether to build the static library
+PAHO_WITH_SSL | TRUE (*nix), FALSE (Win32) | Whether to build SSL/TLS support into the library
+PAHO_BUILD_DOCUMENTATION | FALSE | Create the HTML API documentation (requires _Doxygen_)
+PAHO_BUILD_EXAMPLES | FALSE | Whether to build the example programs
+PAHO_BUILD_TESTS | FALSE | Build the unit tests. (Requires _Catch2_)
PAHO_BUILD_DEB_PACKAGE | FALSE | Flag that configures cpack to build a Debian/Ubuntu package
+PAHO_WITH_MQTT_C | FALSE | Whether to build the bundled Paho C library
+
+Enabling `PAHO_WITH_MQTT_C` builds and links in the Paho C library using compatible build options. If this is enabled, it passes the `PAHO_WITH_SSL` option to the C library, and also sets the options `PAHO_HIGH_PERFORMANCE` and `PAHO_WITH_UNIX_SOCKETS` for the C lib. These can be disabled in the cache before building if desired.
+
+In addition, the C++ build might commonly use `CMAKE_PREFIX_PATH` to help the build system find the location of the Paho C library if it was built separately.
-In addition, the C++ build might commonly use `CMAKE_PREFIX_PATH` to help the build system find the location of the Paho C library.
+### Build the Paho C++ and Paho C libraries together
+
+The quickest and easiest way to build Paho C++ is to build it together with Paho C in a single step using the included Git submodule.
+This requires the CMake option `PAHO_WITH_MQTT_C` set.
+
+```
+$ git clone https://github.com/eclipse/paho.mqtt.cpp
+$ cd paho.mqtt.cpp
+$ git co v1.5.4
-### Unix and Linux
+$ git submodule init
+$ git submodule update
+
+$ cmake -Bbuild -H. -DPAHO_WITH_MQTT_C=ON -DPAHO_BUILD_EXAMPLES=ON
+$ sudo cmake --build build/ --target install
+```
+
+This assumes the build tools and dependencies, such as OpenSSL, have already been installed. For more details and platform-specific requirements, see below.
+
+### Unix-style Systems (Linux, macOS, etc)
On *nix systems CMake creates Makefiles.
The build process currently supports a number of Unix and Linux flavors. The build process requires the following tools:
- * CMake v3.5 or newer
- * GCC v4.8 or newer or Clang v3.9 or newer
- * GNU Make
+* CMake v3.13 or newer
+* A fully-compatible C++17 compiler. Common options are:
+ * GCC v8 or later
+ * _clang_ v5 or later
On Debian based systems this would mean that the following packages have to be installed:
```
-$ sudo apt-get install build-essential gcc make cmake cmake-gui cmake-curses-gui
+$ sudo apt-get install build-essential gcc make cmake
```
-If you will be using secure sockets (and you probably should):
+If you will be using secure sockets (and you probably should if you're sending messages across a public netwok):
```
-$ sudo apt-get install libssl-dev
+$ sudo apt-get install libssl-dev
```
Building the documentation requires doxygen and optionally graphviz to be installed:
@@ -146,151 +142,158 @@ Building the documentation requires doxygen and optionally graphviz to be instal
$ sudo apt-get install doxygen graphviz
```
-Unit tests are being built using _Catch2_.
+Unit tests are built using _Catch2_.
-_Catch2_ can be found here: [Catch2](https://github.com/catchorg/Catch2). You must download and install _Catch2_ to build and run the unit tests locally.
+_Catch2_ can be found here: [Catch2](https://github.com/catchorg/Catch2). You must download and install _Catch2_ to build and run the unit tests locally. Currently _Catch2_ versions v2.x and v3.x are supported.
#### Building the Paho C library
-Before building the C++ library, first, build and install the Paho C library, if not already present. Note, this version of the C++ library requires Paho C v1.3.8 or greater.
+The Paho C library can be built automatically when building this library by enabling the CMake build option, `PAHO_WITH_MQTT_C`. That will build and install the Paho C library from a Git submodule, using a known-good version, and the proper build configuration for the C++ library. But iIf you want to manually specify the build configuration of the Paho C library or use a different version, then it must be built and installed before building the C++ library. Note, this version of the C++ library requires Paho C v1.3.14 or greater.
-```
-$ git clone https://github.com/eclipse/paho.mqtt.c.git
-$ cd paho.mqtt.c
-$ git checkout v1.3.8
+To download and build the Paho C library:
-$ cmake -Bbuild -H. -DPAHO_ENABLE_TESTING=OFF -DPAHO_BUILD_STATIC=ON \
- -DPAHO_WITH_SSL=ON -DPAHO_HIGH_PERFORMANCE=ON
-$ sudo cmake --build build/ --target install
-$ sudo ldconfig
-```
+ $ git clone https://github.com/eclipse/paho.mqtt.c.git
+ $ cd paho.mqtt.c
+ $ git checkout v1.3.14
-This builds with SSL/TLS enabled. If that is not desired, omit the `-DPAHO_WITH_SSL=ON`.
+ $ cmake -Bbuild -H. -DPAHO_ENABLE_TESTING=OFF -DPAHO_WITH_SSL=ON -DPAHO_HIGH_PERFORMANCE=ON
+ $ sudo cmake --build build/ --target install
-It also uses the "high performace" option of the C library to disable more extensive internal memory checks. Remove the _PAHO_HIGH_PERFORMANCE_ option (i.e. turn it off) to debug memory issues, but for most production systems, leave it on for better performance.
+This builds the C library with SSL/TLS enabled. If that is not desired, omit the `-DPAHO_WITH_SSL=ON`.
-To install the library to a non-standard location, use the `CMAKE_INSTALL_PREFIX` to specify a location. For example, to install into under the build directory, perhaps for local testing, do this:
+It also uses the "high performance" option of the C library to disable more extensive internal memory checks. Remove the _PAHO_HIGH_PERFORMANCE_ option (i.e. turn it off) to debug memory issues, but for most production systems, leave it on for better performance.
-```
-$ cmake -Bbuild -H. -DPAHO_ENABLE_TESTING=OFF -DPAHO_BUILD_STATIC=ON \
- -DPAHO_WITH_SSL=ON -DPAHO_HIGH_PERFORMANCE=ON \
- -DCMAKE_INSTALL_PREFIX=./build/_install
-```
+The above will install the library to the default location on the host, which for Linux is normally `/usr/local`. To install the library to a non-standard location, use the `CMAKE_INSTALL_PREFIX` to specify a location. For example, to install into a directory under the user's home directory, perhaps for local testing, do this:
-#### Building the Paho C++ library
+ $ cmake -Bbuild -H. -DPAHO_ENABLE_TESTING=OFF \
+ -DPAHO_WITH_SSL=ON -DPAHO_HIGH_PERFORMANCE=ON \
+ -DCMAKE_INSTALL_PREFIX=$HOME/install
-An example CMake build session might look like this:
+#### Building the Paho C++ library
-```
-$ git clone https://github.com/eclipse/paho.mqtt.cpp
-$ cd paho.mqtt.cpp
+If the Paho C library is not already installed, the recommended version can be built along with the C++ library in a single step using the CMake option `PAHO_WITH_MQTT_C` set on.
-$ cmake -Bbuild -H. -DPAHO_BUILD_STATIC=ON \
- -DPAHO_BUILD_DOCUMENTATION=TRUE -DPAHO_BUILD_SAMPLES=TRUE
-$ sudo cmake --build build/ --target install
-$ sudo ldconfig
-```
+ $ git clone https://github.com/eclipse/paho.mqtt.cpp
+ $ cd paho.mqtt.cpp
+ $ git co v1.5.4
+ $ git submodule init
+ $ git submodule update
-If you did not install Paho C library to a default system location or you want to build against a different version, use the `CMAKE_PREFIX_PATH` to specify its install location. Perhaps something like this:
+ $ cmake -Bbuild -H. -DPAHO_WITH_MQTT_C=ON -DPAHO_BUILD_EXAMPLES=ON
+ $ sudo cmake --build build/ --target install
-```
-$ cmake -Bbuild -H. -DPAHO_BUILD_DOCUMENTATION=ON -DPAHO_BUILD_SAMPLES=ON \
- -DPAHO_BUILD_STATIC=ON \
- -DCMAKE_PREFIX_PATH=$HOME/mqtt/paho.mqtt.c/build/_install
-```
+If a recent version of the Paho C library is available on the build host, and it's installed to a default location, it does not need to be built again. Omit the `PAHO_WITH_MQTT_C` option:
-To use another compiler, either the CXX environment variable can be specified in the configuration step:
+ $ cmake -Bbuild -H. -DPAHO_BUILD_SAMPLES=ON
-```
-$ CXX=clang++ cmake ..
-```
+If the Paho C library is installed to a _non-default_ location, or you want to build against a different version, use the `CMAKE_PREFIX_PATH` to specify its install location. Perhaps something like this:
-or the `CMAKE_CXX_COMPILER` flag can be used:
-
-```
-$ cmake -DCMAKE_CXX_COMPILER=clang++
-```
+ $ cmake -Bbuild -H. -DPAHO_BUILD_SAMPLES=ON -DCMAKE_PREFIX_PATH=$HOME/install
#### Building a Debian/Ubuntu package
+A Debian/Ubuntu install `.deb` file can be created as follows:
+
```
$ cmake -Bbuild -H. -DPAHO_WITH_SSL=ON -DPAHO_ENABLE_TESTING=OFF -DPAHO_BUILD_DEB_PACKAGE=ON
$ cmake --build build
$ (cd build && cpack)
```
-will generate a `.deb` file.
-
### Windows
-On Windows systems CMake creates Visual Studio project files.
+On Windows, CMake creates Visual Studio project files for use with MSVC. Currently, other compilers like _clang_ or _MinGW_ are not directly supported.
-The build process currently supports a number Windows versions. The build process requires the following tools:
- * CMake GUI v3.5 or newer
- * Visual Studio 2015 or newer
+#### Using Paho C++ as a Windows DLL
-First install and open the cmake-gui application. This tutorial is based on cmake-gui 3.5.2.
+The project can be built as a static library or shared DLL on Windows. If using it as a DLL in your application, you should define the macro `PAHO_MQTTPP_IMPORTS` before including any Paho C++ include files. Preferably, make it a global definition in the application's build file, like in CMake:
-Second, select the path to the Paho MQTT C library (CMAKE_PREFIX_PATH) if not installed in a standard path. Remember that the Paho MQTT C must be installed on the system. Next, choose if it is supposed to build the documentation (PAHO_BUILD_DOCUMENTATION) and/or the sample applications (PAHO_BUILD_SAMPLES).
+ target_compile_definitions(myapp PUBLIC PAHO_MQTTPP_IMPORTS)
-Once the configuration is done, click on the Configure button, select the version of the Visual Studio, and then click on Generate button.
+It's better not to mix DLLs and static libraries, but if you do link the Paho C++ DLL against the Paho C static library, you may need to manually resolve some system dependencies, like adding the WinSock library as a dependency to your application:
-At the end of this process you have a Visual Studio solution.
+ target_link_libraries(myapp ws2_32)
-Alternately, the libraries can be completely built at an MSBuild Command Prompt. Download the Paho C and C++ library sources, then open a command window and first compile the Paho C library:
+#### Building the Library on Windows
-```
-> cd paho.mqtt.c
-> cmake -Bbuild -H. -DCMAKE_INSTALL_PREFIX=C:\mqtt\paho-c
-> cmake --build build/ --target install
-```
+The build process currently supports a number Windows versions. The build process requires the following tools:
+ * CMake GUI v3.13 or newer
+ * Visual Studio 2019 or newer
-Then build the C++ library:
+The libraries can be completely built at an MSBuild Command Prompt. Download the Paho C and C++ library sources, then open a command window and first compile the Paho C library:
-```
-> cd ..\paho.mqtt.cpp
-> cmake -Bbuild -H. -DCMAKE_INSTALL_PREFIX=C:\mqtt\paho-cpp -DPAHO_BUILD_SAMPLES=ON -DPAHO_WITH_SSL=OFF -DCMAKE_PREFIX_PATH=C:\mqtt\paho-c
-> cmake --build build/ --target install
-```
-This builds and installs both libraries to a non-standard location under `C:\mqtt`. Modify this location as desired or use the default location, but either way, the C++ library will most likely need to be told where the C library was built using `CMAKE_PREFIX_PATH`.
+ > cd paho.mqtt.c
+ > cmake -Bbuild -H. -DCMAKE_INSTALL_PREFIX=C:\mqtt\paho-c
+ > cmake --build build/ --target install
-It seems quite odd, but even on a 64-bit system using a 64-bit compiler, MSVC seems to default to a 32-bit build target.
+Then build the C++ library:
-The 64-bit target can be selected using tge CMake generator switch, *-G*, at configuration time. The full version must be provided. For Visual Studio 2015 which is v14 do this to first build the Paho C library:
+ > cd ..\paho.mqtt.cpp
+ > cmake -Bbuild -H. -DCMAKE_INSTALL_PREFIX=C:\mqtt\paho-cpp -DPAHO_BUILD_SAMPLES=ON -DPAHO_WITH_SSL=OFF -DCMAKE_PREFIX_PATH=C:\mqtt\paho-c
+ > cmake --build build/ --target install
-```
-> cmake -G "Visual Studio 14 Win64" -Bbuild -H. -DCMAKE_INSTALL_PREFIX=C:\mqtt\paho-c
-...
-```
+This builds and installs both libraries to a non-standard location under `C:\mqtt`. Modify this location as desired or use the default location, but either way, the C++ library will most likely need to be told where the C library was built using `CMAKE_PREFIX_PATH`.
-Then use it to build the C++ library:
+It seems quite odd, but even on a 64-bit system using a 64-bit compiler, MSVC seems to default to a 32-bit build target.
-```
-> cmake -G "Visual Studio 14 Win64" -Bbuild -H. -DCMAKE_INSTALL_PREFIX=C:\mqtt\paho-cpp -DPAHO_WITH_SSL=OFF -DCMAKE_PREFIX_PATH=C:\mqtt\paho-c
-...
-```
+The 64-bit target can be selected using the CMake generator switch, *-G*, at configuration time. The full version must be provided.
+
+ > cmake -G "Visual Studio 16 2019" -Ax64 -Bbuild -H. -DCMAKE_INSTALL_PREFIX=C:\mqtt\paho-c
+ > ...
*Note that it is very important that you use the same generator (target) to build BOTH libraries, otherwise you will get lots of linker errors when you try to build the C++ library.*
## Supported Network Protocols
-The library supports connecting to an MQTT server/broker using TCP, SSL/TLS, and websockets (secure and unsecure). This is chosen by the URI supplied to the connect() call. It can be specified as:
+The library supports connecting to an MQTT server/broker using TCP, SSL/TLS, and websockets both (secure and insecure). On *nix targets, UNIX-domain sockets are also supported. The underlying transport is chosen by the URI supplied to indicate the remote host. It can be specified as:
-```
-"tcp://:" - TCP (unsecure)
-"ssl://:" - SSL/TLS
-"ws://:" - Unsecure websockets
-"wss://:" - Secure websockets
-```
+ "mqtt://:" - TCP, unsecure
+ "tcp://:" (same)
+
+ "mqtts://:" - SSL/TLS
+ "ssl://:" (same)
-Note that to use "ssl://" or "wss://" you must compile the library with OpenSSL, and you _must_ supply a set of `ssl_options` with the `connect_options`.
+ "ws://:" - Unsecure websockets
+ "wss://:" - Secure websockets
-## Example
+ "unix://" - A UNIX-domain socket on the local machine.
+ (*nix systems, only)
-Sample applications can be found in the source repository at _src/samples_:
-https://github.com/eclipse/paho.mqtt.cpp/tree/master/src/samples
+The "mqtt://" and "tcp://" schemas are identical. They indicate an insecure connection over TCP. The "mqtt://" variation is new for the library, but becoming more common across different MQTT libraries.
-This is a partial example of what a typical example might look like:
+Similarly, the "mqtts://" and "ssl://" schemas are identical. They specify a secure connection over SSL/TLS sockets.
+
+Note that to use any of the secure connect options, "mqtts://, "ssl://", or "wss://" you must compile the library with the `PAHO_WITH_SSL=ON` CMake option to include OpenSSL. In addition, you _must_ specify `ssl_options` when you connect to the broker - i.e. you must add an instance of `ssl_options` to the `connect_options` when calling `connect()`.
+
+The use of Unix-domain sockets is only available on *nix-style systems like Linux and macOS. It is not available on Windows. It requires the Paho C library built with the CMake option of PAHO_WITH_UNIX_SOCKETS=ON. This is done by default when building the C library automatically with the Git submodule.
+
+## _Catch2_ Unit Tests
+
+Unit tests use _Catch2_ for the test framework. Versions 2.x and 3.x are supported.
+
+_Catch2_ can be found here: [Catch2](https://github.com/catchorg/Catch2)
+
+## Basics of Thread Safety
+
+Some things to keep in mind when using the library in a multi-threaded application:
+
+- The clients are thread-safe. You can publish/subscribe/etc from multiple threads simultaneously. There are internal mutexes to protect multi-threaded access.
+- You should not make a blocking call from within a callback from the library, i.e. anything registered with `set_callback()`, `set_message_callback()`, etc. Callbacks are invoked from the one internal thread that is processing incoming packets from the network. If you make a blocking call that expects an ACK, you will deadlock.
+- You can only register one `on_message()` callback per client to receive incoming messages for all of your registered subscriptions. That callback runs in the context of the library thread. If you want to process incoming messages from a different (or multiple) threads:
+ - Use a consumer queue, or create one or more instances of a thread-safe queue to move the messages around.
+ - The [thread_queue](https://github.com/eclipse/paho.mqtt.cpp/blob/master/include/mqtt/thread_queue.h) class in the library is a thread-safe queue that you can use for this.
+ - To route incoming messages by topic:
+ - Use an instance of the (topic_matcher)[https://github.com/eclipse/paho.mqtt.cpp/blob/master/include/mqtt/topic_matcher.h] collection to create a collection of queues or callback functions to receive messages that match a set of topic filters.
+ - For MQTT v5 consider using Subscription Identifiers to map incoming messages to callbacks or queues.
+- The various data and options structs (like connect_options) are simple data structs. They are not thread protected.
+
+## Examples
+
+Sample applications can be found in the source repository at [examples/](https://github.com/eclipse/paho.mqtt.cpp/tree/master/examples).
+
+These can all be build along with the library by specifying the CMake flag: `-DPAHO_BUILD_EXAMPLES=ON` when configuring the build.
+
+This is a partial example of what a typical application might look like:
```cpp
int main(int argc, char* argv[])
@@ -301,7 +304,7 @@ int main(int argc, char* argv[])
callback cb;
cli.set_callback(cb);
- auto connOpts = mqtt::connect_options_builder()
+ auto connOpts = mqtt::connect_options_builder()
.keep_alive_interval(20);
.clean_session()
.finalize();
@@ -320,7 +323,7 @@ int main(int argc, char* argv[])
cli.publish(TOPIC, PAYLOAD2, strlen(PAYLOAD2)+1, 0, false);
// Disconnect
-
+
cli.disconnect();
}
catch (const mqtt::persistence_exception& exc) {
@@ -338,32 +341,7 @@ int main(int argc, char* argv[])
}
```
------------
-
-The original API organization and documentation were adapted from:
-
-The Paho Java library
-by Dave Locke et al.
-Copyright (c) 2012, IBM Corp
-
- All rights reserved. This program and the accompanying materials
- are made available under the terms of the Eclipse Public License v1.0
- which accompanies this distribution, and is available at
- http://www.eclipse.org/legal/epl-v10.html
-
------------
-
This code requires:
-The Paho C library by Ian Craggs
-Copyright (c) 2013-2018, IBM Corp.
-
- All rights reserved. This program and the accompanying materials
- are made available under the terms of the Eclipse Public License v1.0
- and Eclipse Distribution License v1.0 which accompany this distribution.
-
- The Eclipse Public License is available at
- http://www.eclipse.org/legal/epl-v10.html
- and the Eclipse Distribution License is available at
- http://www.eclipse.org/org/documents/edl-v10.php.
-
+The Paho C library by Ian Craggs, et al.
+https://github.com/eclipse/paho.mqtt.c
\ No newline at end of file
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 00000000..d1ae30d8
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,16 @@
+# Security Policy
+
+This project follows the [Eclipse Vulnerability Reporting Policy](https://www.eclipse.org/security/policy.php).
+Vulnerabilities are tracked by the Eclipse security team, in cooperation with the project lead.
+Fixing vulnerabilities is taken care of by the project committers, with assistance and guidance of the security
+team.
+
+## Supported Versions
+
+Eclipse Paho provides security updates for the most recent version only.
+
+## Reporting a Vulnerability
+
+We recommend that in case of suspected vulnerabilities you do not create a GitHub issue, but instead contact the
+Eclipse Security Team directly sending an email to security@eclipse.org.
+
diff --git a/about.html b/about.html
index 6555a44e..a8f9dfb2 100644
--- a/about.html
+++ b/about.html
@@ -13,7 +13,7 @@
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index 6205c505..00000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-version: 1.1.{build}
-image: Visual Studio 2015
-configuration: Debug
-install:
-- cmd: >-
- git clone https://github.com/eclipse/paho.mqtt.c.git
-
- cd paho.mqtt.c
-
- mkdir build_cmake
-
- cd build_cmake
-
- "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64
-
- cmake -G "NMake Makefiles" -DCMAKE_INSTALL_PREFIX="C:\Temp\paho-c" -DPAHO_WITH_SSL=TRUE -DPAHO_BUILD_DOCUMENTATION=FALSE -DPAHO_BUILD_SAMPLES=FALSE -DCMAKE_BUILD_TYPE=Release -DCMAKE_VERBOSE_MAKEFILE=FALSE ..
-
- nmake install
-
- cd ..\..
-
-build_script:
-- cmd: >-
- mkdir build_cmake
-
- cd build_cmake
-
- "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64
-
- cmake -G "NMake Makefiles" -DCMAKE_INSTALL_PREFIX="C:\Temp\paho-cpp" -DCMAKE_PREFIX_PATH="C:\Temp\paho-c" -DPAHO_WITH_SSL=TRUE -DPAHO_BUILD_DOCUMENTATION=FALSE -DCMAKE_BUILD_TYPE=Release -DCMAKE_VERBOSE_MAKEFILE=TRUE ..
-
- nmake
-
- nmake install
-
- cd ..
-
diff --git a/buildtst.sh b/buildtst.sh
index 1df494d3..cee19011 100755
--- a/buildtst.sh
+++ b/buildtst.sh
@@ -4,20 +4,22 @@
#
# Build test for the Paho C++ library.
#
+# This is a local CI for testing the build on a dev machine.
+#
# This test the build with a few compilers on Linux. It does a build using
# CMake, for the library, tests, and examples, then runs the unit tests.
# This is repeated for each of the compilers in the list. If a particular
# compiler is not installed on the system, it is just skipped.
#
-# This is not meant to replace Travis or other CI on the repo server, but
-# is a quick test to use locally during development.
+# This is not meant to replace any CI on the repo server, but is a quick
+# test to use locally during development.
#
-COMPILERS="g++-5 g++-6 g++-7 g++-8 clang++-3.9 clang++-4.0 clang++-5.0 clang++-6.0 clang++-7 clang++-8"
+COMPILERS="g++-9 g++-11 g++-13 clang++-14 clang++-17 clang++-20"
+
[ "$#" -gt 0 ] && COMPILERS="$@"
[ -z "${BUILD_JOBS}" ] && BUILD_JOBS=4
-[ -n "${PAHO_C_PATH}" ] && PAHO_C_SWITCH="-DCMAKE_PREFIX_PATH=${PAHO_C_PATH}"
for COMPILER in $COMPILERS; do
if [ -z "$(which ${COMPILER})" ]; then
@@ -25,30 +27,25 @@ for COMPILER in $COMPILERS; do
else
printf "===== Testing: %s =====\n\n" "${COMPILER}"
rm -rf buildtst-build/
- mkdir buildtst-build ; pushd buildtst-build &> /dev/null
+ mkdir buildtst-build
+ pushd buildtst-build &> /dev/null
- if ! cmake -DCMAKE_CXX_COMPILER=${COMPILER} -DPAHO_WITH_SSL=ON -DPAHO_BUILD_SAMPLES=ON -DPAHO_BUILD_TESTS=ON ${PAHO_C_SWITCH} .. ; then
+ if ! cmake .. -DCMAKE_CXX_COMPILER=${COMPILER} -DPAHO_WITH_SSL=ON -DPAHO_BUILD_SAMPLES=ON -DPAHO_BUILD_TESTS=ON -DPAHO_WITH_MQTT_C=ON ; then
printf "\nCMake configuration failed for %s\n" "${COMPILER}"
exit 1
fi
- if ! make -j${BUILD_JOBS} ; then
- printf "\nCompilation failed for %s\n" "${COMPILER}"
+ if ! cmake --build . -j ${BUILD_JOBS} ; then
+ printf "\nBuild failed for %s\n" "${COMPILER}"
exit 2
fi
- printf "Running Catch2 Unit tests for %s:\n" "${COMPILER}"
+ printf "\nRunning Catch2 Unit tests for %s:\n" "${COMPILER}"
if ! ./test/unit/unit_tests ; then
printf "\nCatch2 unit test failed for %s\n" "${COMPILER}"
exit 3
fi
- printf "Running CppUnit tests for %s:\n" "${COMPILER}"
- if ! ./test/cppunit/paho-mqttpp-test ; then
- printf "\nUnit test failed for %s\n" "${COMPILER}"
- exit 4
- fi
-
popd &> /dev/null
fi
printf "\n"
@@ -57,7 +54,7 @@ done
rm -rf buildtst-build/
printf "\nAll builds completed successfully\n\n"
-if ! cppcheck --enable=all --std=c++11 --force --quiet src/*.cpp ; then
+if ! cppcheck --enable=all --std=c++17 --force --quiet src/*.cpp ; then
printf "\ncppcheck failed\n"
exit 5
fi
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
index a9f89087..dc9fd75a 100644
--- a/cmake/CMakeLists.txt
+++ b/cmake/CMakeLists.txt
@@ -1,22 +1,46 @@
+# CMakeLists.txt
+#
+# CMake export file for the Paho C++ library.
+#
+#*******************************************************************************
+# This is part of the Paho MQTT C++ client library.
+#
+# Copyright (c) 2017-2023, Frank Pagliughi
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v2.0
+# and Eclipse Distribution License v1.0 which accompany this distribution.
+#
+# The Eclipse Public License is available at
+# http://www.eclipse.org/legal/epl-v20.html
+# and the Eclipse Distribution License is available at
+# http://www.eclipse.org/org/documents/edl-v10.php.
+#*******************************************************************************/
+
set(package_name PahoMqttCpp)
configure_file(${package_name}Config.cmake.in ${package_name}Config.cmake @ONLY)
include(CMakePackageConfigHelpers)
+
write_basic_package_version_file(
- "${CMAKE_CURRENT_BINARY_DIR}/${package_name}ConfigVersion.cmake"
- VERSION ${PROJECT_VERSION}
- COMPATIBILITY SameMajorVersion) # TODO
+ "${CMAKE_CURRENT_BINARY_DIR}/${package_name}ConfigVersion.cmake"
+ VERSION ${PROJECT_VERSION}
+ COMPATIBILITY SameMajorVersion
+)
export(EXPORT ${package_name}
- FILE "${CMAKE_CURRENT_BINARY_DIR}/${package_name}Targets.cmake"
- NAMESPACE ${package_name}::)
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/${package_name}Targets.cmake"
+ NAMESPACE ${package_name}::
+)
-install(EXPORT ${package_name} DESTINATION lib/cmake/${package_name}
- FILE ${package_name}Targets.cmake
- NAMESPACE ${package_name}::)
+install(EXPORT ${package_name}
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${package_name}
+ FILE ${package_name}Targets.cmake
+ NAMESPACE ${package_name}::
+)
install(FILES
- "${CMAKE_CURRENT_BINARY_DIR}/${package_name}Config.cmake"
- FindPahoMqttC.cmake
- "${CMAKE_CURRENT_BINARY_DIR}/${package_name}ConfigVersion.cmake"
- DESTINATION lib/cmake/${package_name})
+ "${CMAKE_CURRENT_BINARY_DIR}/${package_name}Config.cmake"
+ "${CMAKE_CURRENT_BINARY_DIR}/${package_name}ConfigVersion.cmake"
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${package_name}
+)
diff --git a/cmake/CPackDebConfig.cmake b/cmake/CPackDebConfig.cmake
index a0b93184..2c140f82 100644
--- a/cmake/CPackDebConfig.cmake
+++ b/cmake/CPackDebConfig.cmake
@@ -1,7 +1,7 @@
if(CPACK_GENERATOR MATCHES "DEB")
- set(CPACK_PACKAGE_NAME "libpaho-mqtt.cpp")
+ set(CPACK_PACKAGE_NAME "libpaho-mqtt.cpp")
set(CPACK_DEBIAN_PACKAGE_NAME ${CPACK_PACKAGE_NAME})
- set(CPACK_PACKAGE_CONTACT "Eclipse")
+ set(CPACK_PACKAGE_CONTACT "Eclipse")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Eclipse Paho MQTT C++ client")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER " <>")
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
diff --git a/cmake/FindPahoMqttC.cmake b/cmake/FindPahoMqttC.cmake
deleted file mode 100644
index b3e7ec39..00000000
--- a/cmake/FindPahoMqttC.cmake
+++ /dev/null
@@ -1,34 +0,0 @@
-# find the Paho MQTT C library
-if(PAHO_WITH_SSL)
- set(_PAHO_MQTT_C_LIB_NAME paho-mqtt3as)
- find_package(OpenSSL REQUIRED)
-else()
- set(_PAHO_MQTT_C_LIB_NAME paho-mqtt3a)
-endif()
-
-# add suffix when using static Paho MQTT C library variant on Windows
-if(WIN32)
- if(PAHO_BUILD_STATIC)
- set(_PAHO_MQTT_C_LIB_NAME ${_PAHO_MQTT_C_LIB_NAME}-static)
- endif()
-endif()
-
-find_library(PAHO_MQTT_C_LIBRARIES NAMES ${_PAHO_MQTT_C_LIB_NAME})
-unset(_PAHO_MQTT_C_LIB_NAME)
-find_path(PAHO_MQTT_C_INCLUDE_DIRS NAMES MQTTAsync.h)
-
-add_library(PahoMqttC::PahoMqttC UNKNOWN IMPORTED)
-
-set_target_properties(PahoMqttC::PahoMqttC PROPERTIES
- IMPORTED_LOCATION "${PAHO_MQTT_C_LIBRARIES}"
- INTERFACE_INCLUDE_DIRECTORIES "${PAHO_MQTT_C_INCLUDE_DIRS}"
- IMPORTED_LINK_INTERFACE_LANGUAGES "C")
-if(PAHO_WITH_SSL)
- set_target_properties(PahoMqttC::PahoMqttC PROPERTIES
- INTERFACE_COMPILE_DEFINITIONS "OPENSSL=1"
- INTERFACE_LINK_LIBRARIES "OpenSSL::SSL;OpenSSL::Crypto")
-endif()
-
-include(FindPackageHandleStandardArgs)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(PahoMqttC
- REQUIRED_VARS PAHO_MQTT_C_LIBRARIES PAHO_MQTT_C_INCLUDE_DIRS)
diff --git a/cmake/PahoMqttCppConfig.cmake.in b/cmake/PahoMqttCppConfig.cmake.in
index 164e123a..b7cc7f4b 100644
--- a/cmake/PahoMqttCppConfig.cmake.in
+++ b/cmake/PahoMqttCppConfig.cmake.in
@@ -2,11 +2,26 @@
set(PAHO_BUILD_STATIC @PAHO_BUILD_STATIC@)
set(PAHO_BUILD_SHARED @PAHO_BUILD_SHARED@)
set(PAHO_WITH_SSL @PAHO_WITH_SSL@)
+set(PAHO_WITH_MQTT_C @PAHO_WITH_MQTT_C@)
include(CMakeFindDependencyMacro)
-list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR})
-find_dependency(PahoMqttC REQUIRED)
-list(REMOVE_AT CMAKE_MODULE_PATH -1)
+
find_dependency(Threads REQUIRED)
-include("${CMAKE_CURRENT_LIST_DIR}/@package_name@Targets.cmake")
+if (NOT PAHO_WITH_MQTT_C)
+ find_dependency(eclipse-paho-mqtt-c REQUIRED)
+endif()
+
+if (PAHO_WITH_SSL)
+ find_dependency(OpenSSL REQUIRED)
+endif()
+
+if(NOT TARGET PahoMqttCpp::paho-mqttpp3-shared AND NOT TARGET PahoMqttCpp::paho-mqttpp3-static)
+ include("${CMAKE_CURRENT_LIST_DIR}/@package_name@Targets.cmake")
+
+ if(TARGET PahoMqttCpp::paho-mqttpp3-shared)
+ add_library(PahoMqttCpp::paho-mqttpp3 ALIAS PahoMqttCpp::paho-mqttpp3-shared)
+ else()
+ add_library(PahoMqttCpp::paho-mqttpp3 ALIAS PahoMqttCpp::paho-mqttpp3-static)
+ endif()
+endif()
diff --git a/dist/paho-cpp.spec b/dist/paho-cpp.spec
index 6a05157a..079af895 100644
--- a/dist/paho-cpp.spec
+++ b/dist/paho-cpp.spec
@@ -1,8 +1,8 @@
Summary: MQTT CPP Client
Name: paho-cpp
-Version: 1.0.0
+Version: 1.5.4
Release: 0%{?dist}
-License: Eclipse Distribution License 1.0 and Eclipse Public License 1.0
+License: Eclipse Eclipse Public License 2.0 and Distribution License 1.0
Group: Development/Tools
Source: https://github.com/eclipse/paho.mqtt.cpp/archive/v%{version}.tar.gz
URL: https://eclipse.org/paho/clients/cpp/
@@ -17,7 +17,7 @@ Requires: paho-c
%description
-The Paho MQTT CPP Client is a fully fledged MQTT client written in ANSI standard C++ 11.
+The Paho MQTT CPP Client is a fully fledged MQTT client written in ANSI standard C++ 17.
%package devel
@@ -41,7 +41,7 @@ Development documentation files for the the Paho MQTT CPP Client.
%build
mkdir build.paho.cpp && cd build.paho.cpp
-%cmake3 -DPAHO_WITH_SSL=TRUE -DPAHO_BUILD_DOCUMENTATION=TRUE -DPAHO_BUILD_SAMPLES=TRUE ..
+%cmake3 -DPAHO_WITH_SSL=TRUE -DPAHO_BUILD_DOCUMENTATION=TRUE -DPAHO_BUILD_EXAMPLES=TRUE ..
make %{?_smp_mflags}
%install
@@ -49,7 +49,7 @@ cd build.paho.cpp
make install DESTDIR=%{buildroot}
%files
-%doc edl-v10 epl-v10
+%doc edl-v10 epl-v20
%{_libdir}/*
%files devel
diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt
index 63a53411..5327f689 100644
--- a/doc/CMakeLists.txt
+++ b/doc/CMakeLists.txt
@@ -1,43 +1,47 @@
#*******************************************************************************
-# Copyright (c) 2016
+# Copyright (c) 2024, Frank Pagliughi
+# Copyright (c) 2016, Guilherme Maciel Ferreira
#
# All rights reserved. This program and the accompanying materials
-# are made available under the terms of the Eclipse Public License v1.0
+# are made available under the terms of the Eclipse Public License v2.0
# and Eclipse Distribution License v1.0 which accompany this distribution.
#
# The Eclipse Public License is available at
-# http://www.eclipse.org/legal/epl-v10.html
+# http://www.eclipse.org/legal/epl-v20.html
# and the Eclipse Distribution License is available at
# http://www.eclipse.org/org/documents/edl-v10.php.
#
# Contributors:
+# Frank Pagliughi - Updated paths. Fixed conflict with Paho C
# Guilherme Maciel Ferreira - initial version
#*******************************************************************************/
## documentation settings
-find_package(Doxygen)
-if(NOT DOXYGEN_FOUND)
- message(FATAL_ERROR "Doxygen is needed to build the documentation.")
-endif()
-
-set(DOXYTARGETS)
-
+find_package(Doxygen REQUIRED)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc)
-set(DOXYFILE_SRC Doxyfile.cmake)
-set(DOXYFILE ${CMAKE_CURRENT_BINARY_DIR}/${DOXYFILE_SRC})
+message(STATUS "Doxygen: ${DOXYGEN_EXECUTABLE}")
+
+configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.cmake
+ ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
+ @ONLY
+)
-configure_file(${DOXYFILE_SRC} ${DOXYFILE} @ONLY)
add_custom_target(
- ${DOXYFILE_SRC}.target
- COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE}
+ paho-mqttpp3-doc.target
+ COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen"
VERBATIM
)
-set(DOXYTARGETS ${DOXYTARGETS} ${DOXYFILE_SRC}.target)
-add_custom_target(doc ALL DEPENDS ${DOXYTARGETS})
+add_custom_target(paho-mqttpp3-doc ALL
+ DEPENDS paho-mqttpp3-doc.target
+)
-install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc DESTINATION share)
+install(
+ DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc/
+ DESTINATION share/doc/EclipsePahoCpp
+)
diff --git a/doc/Doxyfile.cmake b/doc/Doxyfile.cmake
index 41532af4..e861ee81 100644
--- a/doc/Doxyfile.cmake
+++ b/doc/Doxyfile.cmake
@@ -648,8 +648,8 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
-STRIP_FROM_PATH = @PROJECT_SOURCE_DIR@/src/mqtt
-INPUT = @PROJECT_SOURCE_DIR@/src/mqtt/
+STRIP_FROM_PATH = @PROJECT_SOURCE_DIR@/include/mqtt
+INPUT = @PROJECT_SOURCE_DIR@/include/mqtt/
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
diff --git a/epl-v10 b/epl-v10
deleted file mode 100644
index 79e486c3..00000000
--- a/epl-v10
+++ /dev/null
@@ -1,70 +0,0 @@
-Eclipse Public License - v 1.0
-
-THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
-
-1. DEFINITIONS
-
-"Contribution" means:
-
-a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and
-b) in the case of each subsequent Contributor:
-i) changes to the Program, and
-ii) additions to the Program;
-where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program.
-"Contributor" means any person or entity that distributes the Program.
-
-"Licensed Patents" mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
-
-"Program" means the Contributions distributed in accordance with this Agreement.
-
-"Recipient" means anyone who receives the Program under this Agreement, including all Contributors.
-
-2. GRANT OF RIGHTS
-
-a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form.
-b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder.
-c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program.
-d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement.
-3. REQUIREMENTS
-
-A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
-
-a) it complies with the terms and conditions of this Agreement; and
-b) its license agreement:
-i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose;
-ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits;
-iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and
-iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange.
-When the Program is made available in source code form:
-
-a) it must be made available under this Agreement; and
-b) a copy of this Agreement must be included with each copy of the Program.
-Contributors may not remove or alter any copyright notices contained within the Program.
-
-Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution.
-
-4. COMMERCIAL DISTRIBUTION
-
-Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense.
-
-For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages.
-
-5. NO WARRANTY
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations.
-
-6. DISCLAIMER OF LIABILITY
-
-EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-
-7. GENERAL
-
-If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
-
-If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed.
-
-All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive.
-
-Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
-
-This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.
diff --git a/epl-v20 b/epl-v20
new file mode 100644
index 00000000..e23ece2c
--- /dev/null
+++ b/epl-v20
@@ -0,0 +1,277 @@
+Eclipse Public License - v 2.0
+
+ THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE
+ PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION
+ OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
+
+1. DEFINITIONS
+
+"Contribution" means:
+
+ a) in the case of the initial Contributor, the initial content
+ Distributed under this Agreement, and
+
+ b) in the case of each subsequent Contributor:
+ i) changes to the Program, and
+ ii) additions to the Program;
+ where such changes and/or additions to the Program originate from
+ and are Distributed by that particular Contributor. A Contribution
+ "originates" from a Contributor if it was added to the Program by
+ such Contributor itself or anyone acting on such Contributor's behalf.
+ Contributions do not include changes or additions to the Program that
+ are not Modified Works.
+
+"Contributor" means any person or entity that Distributes the Program.
+
+"Licensed Patents" mean patent claims licensable by a Contributor which
+are necessarily infringed by the use or sale of its Contribution alone
+or when combined with the Program.
+
+"Program" means the Contributions Distributed in accordance with this
+Agreement.
+
+"Recipient" means anyone who receives the Program under this Agreement
+or any Secondary License (as applicable), including Contributors.
+
+"Derivative Works" shall mean any work, whether in Source Code or other
+form, that is based on (or derived from) the Program and for which the
+editorial revisions, annotations, elaborations, or other modifications
+represent, as a whole, an original work of authorship.
+
+"Modified Works" shall mean any work in Source Code or other form that
+results from an addition to, deletion from, or modification of the
+contents of the Program, including, for purposes of clarity any new file
+in Source Code form that contains any contents of the Program. Modified
+Works shall not include works that contain only declarations,
+interfaces, types, classes, structures, or files of the Program solely
+in each case in order to link to, bind by name, or subclass the Program
+or Modified Works thereof.
+
+"Distribute" means the acts of a) distributing or b) making available
+in any manner that enables the transfer of a copy.
+
+"Source Code" means the form of a Program preferred for making
+modifications, including but not limited to software source code,
+documentation source, and configuration files.
+
+"Secondary License" means either the GNU General Public License,
+Version 2.0, or any later versions of that license, including any
+exceptions or additional permissions as identified by the initial
+Contributor.
+
+2. GRANT OF RIGHTS
+
+ a) Subject to the terms of this Agreement, each Contributor hereby
+ grants Recipient a non-exclusive, worldwide, royalty-free copyright
+ license to reproduce, prepare Derivative Works of, publicly display,
+ publicly perform, Distribute and sublicense the Contribution of such
+ Contributor, if any, and such Derivative Works.
+
+ b) Subject to the terms of this Agreement, each Contributor hereby
+ grants Recipient a non-exclusive, worldwide, royalty-free patent
+ license under Licensed Patents to make, use, sell, offer to sell,
+ import and otherwise transfer the Contribution of such Contributor,
+ if any, in Source Code or other form. This patent license shall
+ apply to the combination of the Contribution and the Program if, at
+ the time the Contribution is added by the Contributor, such addition
+ of the Contribution causes such combination to be covered by the
+ Licensed Patents. The patent license shall not apply to any other
+ combinations which include the Contribution. No hardware per se is
+ licensed hereunder.
+
+ c) Recipient understands that although each Contributor grants the
+ licenses to its Contributions set forth herein, no assurances are
+ provided by any Contributor that the Program does not infringe the
+ patent or other intellectual property rights of any other entity.
+ Each Contributor disclaims any liability to Recipient for claims
+ brought by any other entity based on infringement of intellectual
+ property rights or otherwise. As a condition to exercising the
+ rights and licenses granted hereunder, each Recipient hereby
+ assumes sole responsibility to secure any other intellectual
+ property rights needed, if any. For example, if a third party
+ patent license is required to allow Recipient to Distribute the
+ Program, it is Recipient's responsibility to acquire that license
+ before distributing the Program.
+
+ d) Each Contributor represents that to its knowledge it has
+ sufficient copyright rights in its Contribution, if any, to grant
+ the copyright license set forth in this Agreement.
+
+ e) Notwithstanding the terms of any Secondary License, no
+ Contributor makes additional grants to any Recipient (other than
+ those set forth in this Agreement) as a result of such Recipient's
+ receipt of the Program under the terms of a Secondary License
+ (if permitted under the terms of Section 3).
+
+3. REQUIREMENTS
+
+3.1 If a Contributor Distributes the Program in any form, then:
+
+ a) the Program must also be made available as Source Code, in
+ accordance with section 3.2, and the Contributor must accompany
+ the Program with a statement that the Source Code for the Program
+ is available under this Agreement, and informs Recipients how to
+ obtain it in a reasonable manner on or through a medium customarily
+ used for software exchange; and
+
+ b) the Contributor may Distribute the Program under a license
+ different than this Agreement, provided that such license:
+ i) effectively disclaims on behalf of all other Contributors all
+ warranties and conditions, express and implied, including
+ warranties or conditions of title and non-infringement, and
+ implied warranties or conditions of merchantability and fitness
+ for a particular purpose;
+
+ ii) effectively excludes on behalf of all other Contributors all
+ liability for damages, including direct, indirect, special,
+ incidental and consequential damages, such as lost profits;
+
+ iii) does not attempt to limit or alter the recipients' rights
+ in the Source Code under section 3.2; and
+
+ iv) requires any subsequent distribution of the Program by any
+ party to be under a license that satisfies the requirements
+ of this section 3.
+
+3.2 When the Program is Distributed as Source Code:
+
+ a) it must be made available under this Agreement, or if the
+ Program (i) is combined with other material in a separate file or
+ files made available under a Secondary License, and (ii) the initial
+ Contributor attached to the Source Code the notice described in
+ Exhibit A of this Agreement, then the Program may be made available
+ under the terms of such Secondary Licenses, and
+
+ b) a copy of this Agreement must be included with each copy of
+ the Program.
+
+3.3 Contributors may not remove or alter any copyright, patent,
+trademark, attribution notices, disclaimers of warranty, or limitations
+of liability ("notices") contained within the Program from any copy of
+the Program which they Distribute, provided that Contributors may add
+their own appropriate notices.
+
+4. COMMERCIAL DISTRIBUTION
+
+Commercial distributors of software may accept certain responsibilities
+with respect to end users, business partners and the like. While this
+license is intended to facilitate the commercial use of the Program,
+the Contributor who includes the Program in a commercial product
+offering should do so in a manner which does not create potential
+liability for other Contributors. Therefore, if a Contributor includes
+the Program in a commercial product offering, such Contributor
+("Commercial Contributor") hereby agrees to defend and indemnify every
+other Contributor ("Indemnified Contributor") against any losses,
+damages and costs (collectively "Losses") arising from claims, lawsuits
+and other legal actions brought by a third party against the Indemnified
+Contributor to the extent caused by the acts or omissions of such
+Commercial Contributor in connection with its distribution of the Program
+in a commercial product offering. The obligations in this section do not
+apply to any claims or Losses relating to any actual or alleged
+intellectual property infringement. In order to qualify, an Indemnified
+Contributor must: a) promptly notify the Commercial Contributor in
+writing of such claim, and b) allow the Commercial Contributor to control,
+and cooperate with the Commercial Contributor in, the defense and any
+related settlement negotiations. The Indemnified Contributor may
+participate in any such claim at its own expense.
+
+For example, a Contributor might include the Program in a commercial
+product offering, Product X. That Contributor is then a Commercial
+Contributor. If that Commercial Contributor then makes performance
+claims, or offers warranties related to Product X, those performance
+claims and warranties are such Commercial Contributor's responsibility
+alone. Under this section, the Commercial Contributor would have to
+defend claims against the other Contributors related to those performance
+claims and warranties, and if a court requires any other Contributor to
+pay any damages as a result, the Commercial Contributor must pay
+those damages.
+
+5. NO WARRANTY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT
+PERMITTED BY APPLICABLE LAW, THE PROGRAM IS PROVIDED ON AN "AS IS"
+BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
+IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF
+TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR
+PURPOSE. Each Recipient is solely responsible for determining the
+appropriateness of using and distributing the Program and assumes all
+risks associated with its exercise of rights under this Agreement,
+including but not limited to the risks and costs of program errors,
+compliance with applicable laws, damage to or loss of data, programs
+or equipment, and unavailability or interruption of operations.
+
+6. DISCLAIMER OF LIABILITY
+
+EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, AND TO THE EXTENT
+PERMITTED BY APPLICABLE LAW, NEITHER RECIPIENT NOR ANY CONTRIBUTORS
+SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST
+PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
+EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+7. GENERAL
+
+If any provision of this Agreement is invalid or unenforceable under
+applicable law, it shall not affect the validity or enforceability of
+the remainder of the terms of this Agreement, and without further
+action by the parties hereto, such provision shall be reformed to the
+minimum extent necessary to make such provision valid and enforceable.
+
+If Recipient institutes patent litigation against any entity
+(including a cross-claim or counterclaim in a lawsuit) alleging that the
+Program itself (excluding combinations of the Program with other software
+or hardware) infringes such Recipient's patent(s), then such Recipient's
+rights granted under Section 2(b) shall terminate as of the date such
+litigation is filed.
+
+All Recipient's rights under this Agreement shall terminate if it
+fails to comply with any of the material terms or conditions of this
+Agreement and does not cure such failure in a reasonable period of
+time after becoming aware of such noncompliance. If all Recipient's
+rights under this Agreement terminate, Recipient agrees to cease use
+and distribution of the Program as soon as reasonably practicable.
+However, Recipient's obligations under this Agreement and any licenses
+granted by Recipient relating to the Program shall continue and survive.
+
+Everyone is permitted to copy and distribute copies of this Agreement,
+but in order to avoid inconsistency the Agreement is copyrighted and
+may only be modified in the following manner. The Agreement Steward
+reserves the right to publish new versions (including revisions) of
+this Agreement from time to time. No one other than the Agreement
+Steward has the right to modify this Agreement. The Eclipse Foundation
+is the initial Agreement Steward. The Eclipse Foundation may assign the
+responsibility to serve as the Agreement Steward to a suitable separate
+entity. Each new version of the Agreement will be given a distinguishing
+version number. The Program (including Contributions) may always be
+Distributed subject to the version of the Agreement under which it was
+received. In addition, after a new version of the Agreement is published,
+Contributor may elect to Distribute the Program (including its
+Contributions) under the new version.
+
+Except as expressly stated in Sections 2(a) and 2(b) above, Recipient
+receives no rights or licenses to the intellectual property of any
+Contributor under this Agreement, whether expressly, by implication,
+estoppel or otherwise. All rights in the Program not expressly granted
+under this Agreement are reserved. Nothing in this Agreement is intended
+to be enforceable by any entity that is not a Contributor or Recipient.
+No third-party beneficiary rights are created under this Agreement.
+
+Exhibit A - Form of Secondary Licenses Notice
+
+"This Source Code may also be made available under the following
+Secondary Licenses when the conditions for such availability set forth
+in the Eclipse Public License, v. 2.0 are satisfied: {name license(s),
+version(s), and exceptions or additional permissions here}."
+
+ Simply including a copy of this Agreement, including this Exhibit A
+ is not sufficient to license the Source Code under Secondary Licenses.
+
+ If it is not possible or desirable to put the notice in a particular
+ file, then You may include the notice in a location (such as a LICENSE
+ file in a relevant directory) where a recipient would be likely to
+ look for such a notice.
+
+ You may add additional accurate notices of copyright ownership.
\ No newline at end of file
diff --git a/src/samples/.gitignore b/examples/.gitignore
similarity index 100%
rename from src/samples/.gitignore
rename to examples/.gitignore
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
new file mode 100644
index 00000000..3275e485
--- /dev/null
+++ b/examples/CMakeLists.txt
@@ -0,0 +1,88 @@
+# CMakeLists.txt
+#
+# CMake file for the Paho C++ example applications.
+#
+#*******************************************************************************
+# This is part of the Paho MQTT C++ client library.
+#
+# Copyright (c) 2016-2024
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v2.0
+# and Eclipse Distribution License v1.0 which accompany this distribution.
+#
+# The Eclipse Public License is available at
+# http://www.eclipse.org/legal/epl-v20.html
+# and the Eclipse Distribution License is available at
+# http://www.eclipse.org/org/documents/edl-v10.php.
+#
+# Contributors:
+# Guilherme Maciel Ferreira - initial version
+# Frank Pagliughi - Updates for new samples
+#*******************************************************************************/
+
+## --- Library dependencies ---
+
+set (THREADS_PREFER_PTHREAD_FLAG ON)
+find_package(Threads REQUIRED)
+
+# The example applications
+set(EXECUTABLES
+ async_publish
+ async_publish_time
+ async_subscribe
+ async_subscribe_v5
+ async_consume
+ async_consume_v5
+ async_message_consume
+ async_message_consume_v5
+ data_publish
+ mqttpp_chat
+ multithr_pub_sub
+ pub_speed_test
+ rpc_math_cli
+ rpc_math_srvr
+ server_props_v5
+ sync_publish
+ sync_consume
+ sync_consume_v5
+ sync_reconnect
+ topic_publish
+ ws_publish
+)
+
+# These will only be built if SSL selected
+if(PAHO_WITH_SSL)
+ set(SSL_EXECUTABLES ssl_publish)
+endif()
+
+## Build the example apps
+foreach(EXECUTABLE ${EXECUTABLES} ${SSL_EXECUTABLES})
+ add_executable(${EXECUTABLE} ${EXECUTABLE}.cpp)
+ target_link_libraries(${EXECUTABLE} PahoMqttCpp::paho-mqttpp3)
+
+ set_target_properties(${EXECUTABLE} PROPERTIES
+ CXX_STANDARD 17
+ CXX_STANDARD_REQUIRED ON
+ CXX_EXTENSIONS OFF
+ )
+
+ if(PAHO_BUILD_SHARED)
+ target_compile_definitions(${EXECUTABLE} PRIVATE PAHO_MQTTPP_IMPORTS)
+ endif()
+endforeach()
+
+## Extra configuration for the SSL/TLS examples, if selected
+foreach(EXECUTABLE ${SSL_EXECUTABLES})
+ target_compile_definitions(${EXECUTABLE} PUBLIC OPENSSL)
+endforeach()
+
+## install binaries
+include(GNUInstallDirs)
+
+install(TARGETS ${EXECUTABLES} ${SSL_EXECUTABLES}
+ EXPORT PahoMqttCppSamples
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+)
+
+
diff --git a/examples/async_consume.cpp b/examples/async_consume.cpp
new file mode 100644
index 00000000..27c30a89
--- /dev/null
+++ b/examples/async_consume.cpp
@@ -0,0 +1,115 @@
+// async_consume.cpp
+//
+// This is a Paho MQTT C++ client, sample application.
+//
+// This application is an MQTT consumer/subscriber using the C++
+// asynchronous client interface, employing the to receive messages
+// and status updates.
+//
+// The sample demonstrates:
+// - Connecting to an MQTT v3 server/broker.
+// - Subscribing to a topic
+// - Persistent subscriber session
+// - Receiving messages through the synchronous queuing API
+// - Auto reconnecting
+//
+
+/*******************************************************************************
+ * Copyright (c) 2013-2024 Frank Pagliughi
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * Frank Pagliughi - initial implementation and documentation
+ *******************************************************************************/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "mqtt/async_client.h"
+
+using namespace std;
+
+const string DFLT_SERVER_URI{"mqtt://localhost:1883"};
+const string CLIENT_ID{"paho_cpp_async_consume"};
+
+const string TOPIC{"hello"};
+const int QOS = 1;
+
+/////////////////////////////////////////////////////////////////////////////
+
+int main(int argc, char* argv[])
+{
+ auto serverUri = (argc > 1) ? string{argv[1]} : DFLT_SERVER_URI;
+
+ mqtt::async_client cli(serverUri, CLIENT_ID);
+
+ auto connOpts = mqtt::connect_options_builder::v3()
+ .keep_alive_interval(30s)
+ .clean_session(false)
+ .automatic_reconnect()
+ .finalize();
+
+ try {
+ // Start consumer before connecting to make sure to not miss any messages
+
+ cli.start_consuming();
+
+ // Connect to the server
+
+ cout << "Connecting to the MQTT server..." << flush;
+ auto tok = cli.connect(connOpts);
+
+ // Getting the connect response will block waiting for the
+ // connection to complete.
+ auto rsp = tok->get_connect_response();
+
+ // If there is no session present, then we need to subscribe, but if
+ // there is a session, then the server remembers us and our
+ // subscriptions.
+ if (!rsp.is_session_present()) {
+ cout << " No session present on server. Subscribing..." << flush;
+ cli.subscribe(TOPIC, QOS)->wait();
+ }
+
+ cout << "OK" << endl;
+
+ // Consume messages
+
+ cout << "\nWaiting for messages on topic: '" << TOPIC << "'" << endl;
+
+ // The client handles automatic reconnects, but we monitor
+ // the events here to report them to the user.
+ while (true) {
+ auto evt = cli.consume_event();
+
+ if (const auto* p = evt.get_message_if()) {
+ auto& msg = *p;
+ if (msg)
+ cout << msg->get_topic() << ": " << msg->to_string() << endl;
+ }
+ else if (evt.is_connected())
+ cout << "\n*** Connected ***" << endl;
+ else if (evt.is_connection_lost())
+ cout << "*** Connection Lost ***" << endl;
+ }
+ }
+ catch (const mqtt::exception& exc) {
+ cerr << "\n " << exc << endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/examples/async_consume_v5.cpp b/examples/async_consume_v5.cpp
new file mode 100644
index 00000000..f7f2096b
--- /dev/null
+++ b/examples/async_consume_v5.cpp
@@ -0,0 +1,159 @@
+// async_consume_v5.cpp
+//
+// This is a Paho MQTT C++ client, sample application.
+//
+// This application is an MQTT consumer/subscriber using the C++
+// asynchronous client interface, employing the to receive messages
+// and status updates.
+//
+// The sample demonstrates:
+// - Connecting to an MQTT v5 server/broker.
+// - Subscribing to a topic
+// - Receiving messages through the consuming (queuing) API
+//
+
+/*******************************************************************************
+ * Copyright (c) 2013-2024 Frank Pagliughi
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * Frank Pagliughi - initial implementation and documentation
+ *******************************************************************************/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "mqtt/async_client.h"
+
+using namespace std;
+
+const string DFLT_SERVER_URI{"mqtt://localhost:1883"};
+const string CLIENT_ID{"PahoCppAsyncConsumeV5"};
+
+const string TOPIC{"#"};
+const int QOS = 1;
+
+/////////////////////////////////////////////////////////////////////////////
+
+int main(int argc, char* argv[])
+{
+ auto serverURI = (argc > 1) ? string{argv[1]} : DFLT_SERVER_URI;
+
+ auto cli = std::make_shared(serverURI, CLIENT_ID);
+
+ auto connOpts = mqtt::connect_options_builder::v5()
+ .clean_start(false)
+ .properties({{mqtt::property::SESSION_EXPIRY_INTERVAL, 604800}})
+ .finalize();
+
+ try {
+ // Start consumer before connecting to make sure to not miss messages
+
+ cli->start_consuming();
+
+ // Connect to the server
+
+ cout << "Connecting to the MQTT server..." << flush;
+ auto tok = cli->connect(connOpts);
+
+ // Getting the connect response will block waiting for the
+ // connection to complete.
+ auto rsp = tok->get_connect_response();
+
+ // Make sure we were granted a v5 connection.
+ if (rsp.get_mqtt_version() < MQTTVERSION_5) {
+ cout << "\n Did not get an MQTT v5 connection." << flush;
+ exit(1);
+ }
+
+ // If there is no session present, then we need to subscribe, but if
+ // there is a session, then the server remembers us and our
+ // subscriptions.
+ if (!rsp.is_session_present()) {
+ cout << "\n Session not present on broker. Subscribing..." << flush;
+ cli->subscribe(TOPIC, QOS)->wait();
+ }
+
+ cout << "\n OK" << endl;
+
+ // We'll signal the consumer to exit from another thread.
+ // (just to show that we can)
+ thread([cli] {
+ this_thread::sleep_for(60s);
+ cout << "\nClosing the consumer." << endl;
+ cli->stop_consuming();
+ }).detach();
+
+ // Consume messages
+ //
+ // This just exits if the consumer is closed or the client is
+ // disconnected. (See some other examples for auto or manual
+ // reconnect)
+
+ cout << "\nWaiting for messages on topic: '" << TOPIC << "'" << endl;
+
+ try {
+ while (true) {
+ auto evt = cli->consume_event();
+
+ if (const auto* p = evt.get_message_if()) {
+ auto& msg = *p;
+ if (!msg)
+ continue;
+
+ cout << msg->get_topic() << ": " << msg->to_string();
+
+ const auto& props = msg->get_properties();
+ if (size_t n = props.size(); n != 0) {
+ cout << "\n [";
+ for (size_t i = 0; i < n - 1; ++i) cout << props[i] << ", ";
+ cout << props[n - 1] << "]";
+ }
+ cout << endl;
+ }
+ else if (evt.is_connected()) {
+ cout << "\n*** Connected ***" << endl;
+ }
+ else if (evt.is_connection_lost()) {
+ cout << "*** Connection Lost ***" << endl;
+ break;
+ }
+ else if (const auto* p = evt.get_disconnected_if()) {
+ cout << "*** Disconnected. Reason [0x" << hex << int{p->reasonCode}
+ << "]: " << p->reasonCode << " ***" << endl;
+ break;
+ }
+ }
+ }
+ catch (mqtt::queue_closed&) {
+ }
+
+ // If we're here, the client was almost certainly disconnected.
+ // But we check, just to make sure.
+
+ if (cli->is_connected()) {
+ cout << "\nShutting down and disconnecting from the MQTT server..." << flush;
+ cli->disconnect()->wait();
+ cout << "OK" << endl;
+ }
+ }
+ catch (const mqtt::exception& exc) {
+ cerr << "\n " << exc << endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/examples/async_message_consume.cpp b/examples/async_message_consume.cpp
new file mode 100644
index 00000000..cc802d0f
--- /dev/null
+++ b/examples/async_message_consume.cpp
@@ -0,0 +1,114 @@
+// async_consume.cpp
+//
+// This is a Paho MQTT C++ client, sample application.
+//
+// This application is an MQTT consumer/subscriber using the C++
+// asynchronous client interface, employing the to receive messages
+// and status updates.
+//
+// The sample demonstrates:
+// - Connecting to an MQTT v3 server/broker.
+// - Subscribing to a topic
+// - Persistent subscriber session
+// - Receiving messages through the synchronous queuing API
+// - Auto reconnecting
+//
+
+/*******************************************************************************
+ * Copyright (c) 2013-2024 Frank Pagliughi
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * Frank Pagliughi - initial implementation and documentation
+ *******************************************************************************/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "mqtt/async_client.h"
+
+using namespace std;
+
+const string DFLT_SERVER_URI{"mqtt://localhost:1883"};
+const string CLIENT_ID{"paho_cpp_async_consume"};
+
+const string TOPIC{"hello"};
+const int QOS = 1;
+
+/////////////////////////////////////////////////////////////////////////////
+
+int main(int argc, char* argv[])
+{
+ auto serverUri = (argc > 1) ? string{argv[1]} : DFLT_SERVER_URI;
+
+ mqtt::async_client cli(serverUri, CLIENT_ID);
+
+ auto connOpts = mqtt::connect_options_builder::v3()
+ .keep_alive_interval(30s)
+ .clean_session(false)
+ .automatic_reconnect()
+ .finalize();
+
+ // The client will handle automatic reconnects, but we add this
+ // callbacks to let the user know when we're reconnected.
+ cli.set_connected_handler([](const std::string&) {
+ cout << "\n*** Connected ***" << endl;
+ });
+
+ try {
+ // Start consumer before connecting to make sure to not miss any messages
+
+ cli.start_consuming();
+
+ // Connect to the server
+
+ cout << "Connecting to the MQTT server..." << flush;
+ auto tok = cli.connect(connOpts);
+
+ // Getting the connect response will block waiting for the
+ // connection to complete.
+ auto rsp = tok->get_connect_response();
+
+ // If there is no session present, then we need to subscribe, but if
+ // there is a session, then the server remembers us and our
+ // subscriptions.
+ if (!rsp.is_session_present()) {
+ cout << " No session present on server. Subscribing..." << flush;
+ cli.subscribe(TOPIC, QOS)->wait();
+ }
+
+ cout << "OK" << endl;
+
+ // Consume messages
+
+ cout << "\nWaiting for messages on topic: '" << TOPIC << "'" << endl;
+
+ while (true) {
+ auto msg = cli.consume_message();
+
+ if (msg)
+ cout << msg->get_topic() << ": " << msg->to_string() << endl;
+ else
+ cout << "*** Connection Lost ***" << endl;
+ }
+ }
+ catch (const mqtt::exception& exc) {
+ cerr << "\n " << exc << endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/examples/async_message_consume_v5.cpp b/examples/async_message_consume_v5.cpp
new file mode 100644
index 00000000..a7d9566a
--- /dev/null
+++ b/examples/async_message_consume_v5.cpp
@@ -0,0 +1,133 @@
+// async_consume_v5.cpp
+//
+// This is a Paho MQTT C++ client, sample application.
+//
+// This application is an MQTT consumer/subscriber using the C++
+// asynchronous client interface, employing the to receive messages
+// and status updates.
+//
+// The sample demonstrates:
+// - Connecting to an MQTT v5 server/broker.
+// - Subscribing to a topic
+// - Receiving messages through the consuming (queuing) API
+//
+
+/*******************************************************************************
+ * Copyright (c) 2013-2024 Frank Pagliughi
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * Frank Pagliughi - initial implementation and documentation
+ *******************************************************************************/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "mqtt/async_client.h"
+
+using namespace std;
+
+const string DFLT_SERVER_URI{"mqtt://localhost:1883"};
+const string CLIENT_ID{"PahoCppAsyncConsumeV5"};
+
+const string TOPIC{"hello"};
+const int QOS = 1;
+
+/////////////////////////////////////////////////////////////////////////////
+
+int main(int argc, char* argv[])
+{
+ auto serverURI = (argc > 1) ? string{argv[1]} : DFLT_SERVER_URI;
+
+ mqtt::async_client cli(serverURI, CLIENT_ID);
+
+ auto connOpts = mqtt::connect_options_builder::v5()
+ .clean_start(false)
+ .properties({{mqtt::property::SESSION_EXPIRY_INTERVAL, 604800}})
+ .finalize();
+
+ try {
+ cli.set_connection_lost_handler([](const std::string&) {
+ cout << "*** Connection Lost ***" << endl;
+ });
+
+ cli.set_disconnected_handler([](const mqtt::properties&, mqtt::ReasonCode reason) {
+ cout << "*** Disconnected. Reason [0x" << hex << int{reason} << "]: " << reason
+ << " ***" << endl;
+ });
+
+ // Start consumer before connecting to make sure to not miss messages
+
+ cli.start_consuming();
+
+ // Connect to the server
+
+ cout << "Connecting to the MQTT server..." << flush;
+ auto tok = cli.connect(connOpts);
+
+ // Getting the connect response will block waiting for the
+ // connection to complete.
+ auto rsp = tok->get_connect_response();
+
+ // Make sure we were granted a v5 connection.
+ if (rsp.get_mqtt_version() < MQTTVERSION_5) {
+ cout << "\n Did not get an MQTT v5 connection." << flush;
+ exit(1);
+ }
+
+ // If there is no session present, then we need to subscribe, but if
+ // there is a session, then the server remembers us and our
+ // subscriptions.
+ if (!rsp.is_session_present()) {
+ cout << "\n Session not present on broker. Subscribing..." << flush;
+ cli.subscribe(TOPIC, QOS)->wait();
+ }
+
+ cout << "\n OK" << endl;
+
+ // Consume messages
+ // This just exits if the client is disconnected.
+ // (See some other examples for auto or manual reconnect)
+
+ cout << "\nWaiting for messages on topic: '" << TOPIC << "'" << endl;
+
+ while (true) {
+ auto msg = cli.consume_message();
+ if (!msg)
+ break;
+ cout << msg->get_topic() << ": " << msg->to_string() << endl;
+ }
+
+ // If we're here, the client was almost certainly disconnected.
+ // But we check, just to make sure.
+
+ if (cli.is_connected()) {
+ cout << "\nShutting down and disconnecting from the MQTT server..." << flush;
+ cli.stop_consuming();
+ cli.disconnect()->wait();
+ cout << "OK" << endl;
+ }
+ else {
+ cout << "\nClient was disconnected" << endl;
+ }
+ }
+ catch (const mqtt::exception& exc) {
+ cerr << "\n " << exc << endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/examples/async_publish.cpp b/examples/async_publish.cpp
new file mode 100644
index 00000000..ccb0b5af
--- /dev/null
+++ b/examples/async_publish.cpp
@@ -0,0 +1,221 @@
+// async_publish.cpp
+//
+// This is a Paho MQTT C++ client, sample application.
+//
+// It's an example of how to send messages as an MQTT publisher using the
+// C++ asynchronous client interface.
+//
+// The sample demonstrates:
+// - Connecting to an MQTT server/broker
+// - Using a connect timeout
+// - Publishing messages
+// - Default file persistence
+// - Last will and testament
+// - Using asynchronous tokens
+// - Implementing callbacks and action listeners
+//
+
+/*******************************************************************************
+ * Copyright (c) 2013-2023 Frank Pagliughi
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * Frank Pagliughi - initial implementation and documentation
+ *******************************************************************************/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "mqtt/async_client.h"
+
+using namespace std;
+using namespace std::chrono;
+
+const string DFLT_SERVER_URI{"mqtt://localhost:1883"};
+const string CLIENT_ID{"paho_cpp_async_publish"};
+
+const mqtt::persistence_type PERSIST_DIR{"./persist"};
+
+const string TOPIC{"hello"};
+
+const string PAYLOAD1{"Hello World!"};
+const string PAYLOAD2{"Hi there!"};
+const string PAYLOAD3{"Is anyone listening?"};
+const string PAYLOAD4{"Someone is always listening."};
+
+const string LWT_PAYLOAD{"Last will and testament."};
+
+const int QOS = 1;
+
+const auto TIMEOUT = std::chrono::seconds(10);
+
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ * A callback class for use with the main MQTT client.
+ */
+class callback : public virtual mqtt::callback
+{
+public:
+ void connection_lost(const string& cause) override
+ {
+ cout << "\nConnection lost" << endl;
+ if (!cause.empty())
+ cout << "\tcause: " << cause << endl;
+ }
+
+ void delivery_complete(mqtt::delivery_token_ptr tok) override
+ {
+ cout << "\tDelivery complete for token: " << (tok ? tok->get_message_id() : -1)
+ << endl;
+ }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ * A base action listener.
+ */
+class action_listener : public virtual mqtt::iaction_listener
+{
+protected:
+ void on_failure(const mqtt::token& tok) override
+ {
+ cout << "\tListener failure for token: " << tok.get_message_id() << endl;
+ }
+
+ void on_success(const mqtt::token& tok) override
+ {
+ cout << "\tListener success for token: " << tok.get_message_id() << endl;
+ }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ * A derived action listener for publish events.
+ */
+class delivery_action_listener : public action_listener
+{
+ atomic done_;
+
+ void on_failure(const mqtt::token& tok) override
+ {
+ action_listener::on_failure(tok);
+ done_ = true;
+ }
+
+ void on_success(const mqtt::token& tok) override
+ {
+ action_listener::on_success(tok);
+ done_ = true;
+ }
+
+public:
+ delivery_action_listener() : done_(false) {}
+ bool is_done() const { return done_; }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+int main(int argc, char* argv[])
+{
+ // A client that just publishes normally doesn't need a persistent
+ // session or Client ID unless it's using persistence, then the local
+ // library requires an ID to identify the persistence files.
+
+ string serverURI = (argc > 1) ? string{argv[1]} : DFLT_SERVER_URI,
+ clientID = (argc > 2) ? string{argv[2]} : CLIENT_ID;
+
+ cout << "Initializing for server '" << serverURI << "'..." << endl;
+ mqtt::async_client client(serverURI, clientID, PERSIST_DIR);
+
+ callback cb;
+ client.set_callback(cb);
+
+ auto connOpts = mqtt::connect_options_builder()
+ .connect_timeout(5s)
+ .clean_session()
+ .will(mqtt::message(TOPIC, LWT_PAYLOAD, QOS, false))
+ .finalize();
+
+ cout << " ...OK" << endl;
+
+ try {
+ cout << "\nConnecting..." << endl;
+ mqtt::token_ptr conntok = client.connect(connOpts);
+ cout << "Waiting for the connection..." << endl;
+ conntok->wait();
+ cout << " ...OK" << endl;
+
+ // First use a message pointer.
+
+ cout << "\nSending message..." << endl;
+ mqtt::message_ptr pubmsg = mqtt::make_message(TOPIC, PAYLOAD1);
+ pubmsg->set_qos(QOS);
+ client.publish(pubmsg)->wait_for(TIMEOUT);
+ cout << " ...OK" << endl;
+
+ // Now try with itemized publish.
+
+ cout << "\nSending next message..." << endl;
+ mqtt::delivery_token_ptr pubtok;
+ pubtok = client.publish(TOPIC, PAYLOAD2, QOS, false);
+ cout << " ...with token: " << pubtok->get_message_id() << endl;
+ cout << " ...for message with " << pubtok->get_message()->get_payload().size()
+ << " bytes" << endl;
+ pubtok->wait_for(TIMEOUT);
+ cout << " ...OK" << endl;
+
+ // Now try with a listener
+
+ cout << "\nSending next message..." << endl;
+ action_listener listener;
+ pubmsg = mqtt::make_message(TOPIC, PAYLOAD3);
+ pubtok = client.publish(pubmsg, nullptr, listener);
+ pubtok->wait();
+ cout << " ...OK" << endl;
+
+ // Finally try with a listener, but no token
+
+ cout << "\nSending final message..." << endl;
+ delivery_action_listener deliveryListener;
+ pubmsg = mqtt::make_message(TOPIC, PAYLOAD4);
+ client.publish(pubmsg, nullptr, deliveryListener);
+
+ while (!deliveryListener.is_done()) {
+ this_thread::sleep_for(std::chrono::milliseconds(100));
+ }
+ cout << "OK" << endl;
+
+ // Double check that there are no pending tokens
+
+ auto toks = client.get_pending_delivery_tokens();
+ if (!toks.empty())
+ cout << "Error: There are pending delivery tokens!" << endl;
+
+ // Disconnect
+ cout << "\nDisconnecting..." << endl;
+ client.disconnect()->wait();
+ cout << " ...OK" << endl;
+ }
+ catch (const mqtt::exception& exc) {
+ cerr << exc.what() << endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/examples/async_publish_time.cpp b/examples/async_publish_time.cpp
new file mode 100644
index 00000000..4efc6537
--- /dev/null
+++ b/examples/async_publish_time.cpp
@@ -0,0 +1,173 @@
+// async_publish_time.cpp
+//
+// This is a Paho MQTT C++ client, sample application.
+//
+// It's a fairly contrived, but useful example of an MQTT data monitor and
+// publisher, using the C++ asynchronous client interface. A fairly common
+// usage for MQTT applications to monitor a sensor and publish the reading
+// when it changes by a "significant" amount (whatever that may be).
+// This might be temperature, pressure, humidity, soil moisture, CO2 levels,
+// or anything like that.
+//
+// Since we don't have a universal sensor to use for this example, we simply
+// use time itself as out input data. We periodically "sample" the time
+// value and when it changes by more than our required delta amount, we
+// publish the time. In this case we use the system clock, measuring the
+// time with millisecond precision.
+//
+// The sample demonstrates:
+// - Connecting to an MQTT server/broker
+// - Sampling a value
+// - Publishing messages using a `topic` object
+// - Last will and testament
+// - Callbacks with lambdas (on connect and disconnect)
+// - Using `create_options`
+// - Creating options with builder classes
+// - Offline buffering in the client
+//
+
+/*******************************************************************************
+ * Copyright (c) 2019-2023 Frank Pagliughi
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * Frank Pagliughi - initial implementation and documentation
+ *******************************************************************************/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include // For sleep
+
+#include "mqtt/async_client.h"
+
+using namespace std;
+using namespace std::chrono;
+
+const std::string DFLT_SERVER_URI{"mqtt://localhost:1883"};
+
+// The QoS for sending data
+const int QOS = 1;
+
+// How often to sample the "data"
+const auto SAMPLE_PERIOD = 5ms;
+
+// How much the "data" needs to change before we publish a new value.
+const int DELTA_MS = 100;
+
+// How many to buffer while off-line
+const int MAX_BUFFERED_MESSAGES = 1200;
+
+// Atomic flag to tell the main loop to exit.
+atomic quit{false};
+
+// Handler for ^C (SIGINT)
+void ctrlc_handler(int) { quit = true; }
+
+// --------------------------------------------------------------------------
+// Gets the current time as the number of milliseconds since the epoch:
+// like a time_t with ms resolution.
+
+uint64_t timestamp()
+{
+ auto now = system_clock::now();
+ auto tse = now.time_since_epoch();
+ auto msTm = duration_cast(tse);
+ return uint64_t(msTm.count());
+}
+
+// --------------------------------------------------------------------------
+
+int main(int argc, char* argv[])
+{
+ // The server URI (address)
+ string serverURI = (argc > 1) ? string{argv[1]} : DFLT_SERVER_URI;
+
+ // The amount of time to run (in ms). Zero means "run forever".
+ uint64_t trun = (argc > 2) ? stoll(argv[2]) : 0LL;
+
+ cout << "Initializing for server '" << serverURI << "'..." << endl;
+
+ // We configure to allow publishing to the client while off-line,
+ // and that it's OK to do so before the 1st successful connection.
+ auto createOpts = mqtt::create_options_builder()
+ .server_uri(serverURI)
+ .send_while_disconnected(true, true)
+ .max_buffered_messages(MAX_BUFFERED_MESSAGES)
+ .delete_oldest_messages()
+ .finalize();
+
+ mqtt::async_client cli(createOpts);
+
+ // Set callbacks for when connected and connection lost.
+
+ cli.set_connected_handler([&cli](const std::string&) {
+ std::cout << "*** Connected (" << timestamp() << ") ***" << std::endl;
+ });
+
+ cli.set_connection_lost_handler([&cli](const std::string&) {
+ std::cout << "*** Connection Lost (" << timestamp() << ") ***" << std::endl;
+ });
+
+ auto willMsg = mqtt::message("test/events", "Time publisher disconnected", 1, true);
+ auto connOpts = mqtt::connect_options_builder()
+ .clean_session()
+ .will(willMsg)
+ .keep_alive_interval(10s)
+ .automatic_reconnect(seconds(1), seconds(10))
+ .finalize();
+
+ try {
+ // Note that we start the connection, but don't wait for completion.
+ // We configured to allow publishing before a successful connection.
+ cout << "Starting connection..." << endl;
+ cli.connect(connOpts);
+
+ auto top = mqtt::topic(cli, "data/time", QOS);
+ cout << "Publishing data..." << endl;
+
+ // Install a ^C handler for user to signal when to exit
+ signal(SIGINT, ctrlc_handler);
+
+ // Sync clock to start of delta period
+ while (timestamp() % DELTA_MS != 0);
+
+ uint64_t t = timestamp(), tlast = t, tstart = t;
+ top.publish(to_string(t));
+
+ while (!quit) {
+ this_thread::sleep_for(SAMPLE_PERIOD);
+
+ t = timestamp();
+
+ if (abs(int(t - tlast)) >= DELTA_MS)
+ top.publish(to_string(tlast = t));
+
+ if (trun > 0 && t >= (trun + tstart))
+ break;
+ }
+
+ // Disconnect
+ cout << "\nDisconnecting..." << endl;
+ cli.disconnect()->wait();
+ cout << " ...OK" << endl;
+ }
+ catch (const mqtt::exception& exc) {
+ cerr << exc.what() << endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/examples/async_subscribe.cpp b/examples/async_subscribe.cpp
new file mode 100644
index 00000000..2bf4c268
--- /dev/null
+++ b/examples/async_subscribe.cpp
@@ -0,0 +1,226 @@
+// async_subscribe.cpp
+//
+// This is a Paho MQTT C++ client, sample application.
+//
+// This application is an MQTT subscriber using the C++ asynchronous client
+// interface, employing callbacks to receive messages and status updates.
+//
+// The sample demonstrates:
+// - Connecting to an MQTT server/broker using MQTT v3.
+// - Subscribing to a topic
+// - Receiving messages through the callback API
+// - Receiving network disconnect updates and attempting manual reconnects.
+// - Using a "clean session" and manually re-subscribing to topics on
+// reconnect.
+//
+
+/*******************************************************************************
+ * Copyright (c) 2013-2025 Frank Pagliughi
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * Frank Pagliughi - initial implementation and documentation
+ *******************************************************************************/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "mqtt/async_client.h"
+
+const std::string DFLT_SERVER_URI("mqtt://localhost:1883");
+const std::string CLIENT_ID("paho_cpp_async_subscribe");
+
+const std::string TOPIC("#");
+
+const int QOS = 1;
+const int N_RETRY_ATTEMPTS = 5;
+
+/////////////////////////////////////////////////////////////////////////////
+
+// Callbacks for the success or failures of requested actions.
+// This could be used to initiate further action, but here we just log the
+// results to the console.
+
+class action_listener : public virtual mqtt::iaction_listener
+{
+ std::string name_;
+
+ void on_failure(const mqtt::token& tok) override
+ {
+ std::cout << name_ << " failure";
+ if (tok.get_message_id() != 0)
+ std::cout << " for token: [" << tok.get_message_id() << "]" << std::endl;
+ std::cout << std::endl;
+ }
+
+ void on_success(const mqtt::token& tok) override
+ {
+ std::cout << name_ << " success";
+ if (tok.get_message_id() != 0)
+ std::cout << " for token: [" << tok.get_message_id() << "]" << std::endl;
+ auto top = tok.get_topics();
+ if (top && !top->empty())
+ std::cout << "\ttoken topic: '" << (*top)[0] << "', ..." << std::endl;
+ std::cout << std::endl;
+ }
+
+public:
+ action_listener(const std::string& name) : name_(name) {}
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Local callback & listener class for use with the client connection.
+ * This is primarily intended to receive messages, but it will also monitor
+ * the connection to the broker. If the connection is lost, it will attempt
+ * to restore the connection and re-subscribe to the topic.
+ */
+class callback : public virtual mqtt::callback, public virtual mqtt::iaction_listener
+
+{
+ // Counter for the number of connection retries
+ int nretry_;
+ // The MQTT client
+ mqtt::async_client& cli_;
+ // Options to use if we need to reconnect
+ mqtt::connect_options& connOpts_;
+ // An action listener to display the result of actions.
+ action_listener subListener_;
+
+ // This deomonstrates manually reconnecting to the broker by calling
+ // connect() again. This is a possibility for an application that keeps
+ // a copy of it's original connect_options, or if the app wants to
+ // reconnect with different options.
+ // Another way this can be done manually, if using the same options, is
+ // to just call the async_client::reconnect() method.
+ void reconnect()
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(2500));
+ try {
+ cli_.connect(connOpts_, nullptr, *this);
+ }
+ catch (const mqtt::exception& exc) {
+ std::cerr << "Error: " << exc.what() << std::endl;
+ exit(1);
+ }
+ }
+
+ // Re-connection failure
+ void on_failure(const mqtt::token& tok) override
+ {
+ std::cout << "Connection attempt failed" << std::endl;
+ if (++nretry_ > N_RETRY_ATTEMPTS)
+ exit(1);
+ reconnect();
+ }
+
+ // (Re)connection success
+ // Either this or connected() can be used for callbacks.
+ void on_success(const mqtt::token& tok) override {}
+
+ // (Re)connection success
+ void connected(const std::string& cause) override
+ {
+ std::cout << "\nConnection success" << std::endl;
+ std::cout << "\nSubscribing to topic '" << TOPIC << "'\n"
+ << "\tfor client " << CLIENT_ID << " using QoS" << QOS << "\n"
+ << "\nPress Q to quit\n"
+ << std::endl;
+
+ cli_.subscribe(TOPIC, QOS, nullptr, subListener_);
+ }
+
+ // Callback for when the connection is lost.
+ // This will initiate the attempt to manually reconnect.
+ void connection_lost(const std::string& cause) override
+ {
+ std::cout << "\nConnection lost" << std::endl;
+ if (!cause.empty())
+ std::cout << "\tcause: " << cause << std::endl;
+
+ std::cout << "Reconnecting..." << std::endl;
+ nretry_ = 0;
+ reconnect();
+ }
+
+ // Callback for when a message arrives.
+ void message_arrived(mqtt::const_message_ptr msg) override
+ {
+ std::cout << "Message arrived" << std::endl;
+ std::cout << "\ttopic: '" << msg->get_topic() << "'" << std::endl;
+ std::cout << "\tpayload: '" << msg->to_string() << "'\n" << std::endl;
+ }
+
+ void delivery_complete(mqtt::delivery_token_ptr token) override {}
+
+public:
+ callback(mqtt::async_client& cli, mqtt::connect_options& connOpts)
+ : nretry_(0), cli_(cli), connOpts_(connOpts), subListener_("Subscription")
+ {
+ }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+int main(int argc, char* argv[])
+{
+ // A subscriber often wants the server to remember its messages when its
+ // disconnected. In that case, it needs a unique ClientID and a
+ // non-clean session.
+
+ auto serverURI = (argc > 1) ? std::string{argv[1]} : DFLT_SERVER_URI;
+
+ mqtt::async_client cli(serverURI, CLIENT_ID);
+
+ mqtt::connect_options connOpts;
+ connOpts.set_clean_session(false);
+
+ // Install the callback(s) before connecting.
+ callback cb(cli, connOpts);
+ cli.set_callback(cb);
+
+ // Start the connection.
+ // When completed, the callback will subscribe to topic.
+
+ try {
+ std::cout << "Connecting to the MQTT server '" << serverURI << "'..." << std::flush;
+ cli.connect(connOpts, nullptr, cb);
+ }
+ catch (const mqtt::exception& exc) {
+ std::cerr << "\nERROR: Unable to connect to MQTT server: '" << serverURI << "'" << exc
+ << std::endl;
+ return 1;
+ }
+
+ // Just block till user tells us to quit.
+
+ while (std::tolower(std::cin.get()) != 'q');
+
+ // Disconnect
+
+ try {
+ std::cout << "\nDisconnecting from the MQTT server..." << std::flush;
+ cli.disconnect()->wait();
+ std::cout << "OK" << std::endl;
+ }
+ catch (const mqtt::exception& exc) {
+ std::cerr << exc << std::endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/examples/async_subscribe_v5.cpp b/examples/async_subscribe_v5.cpp
new file mode 100644
index 00000000..ee67e747
--- /dev/null
+++ b/examples/async_subscribe_v5.cpp
@@ -0,0 +1,232 @@
+// async_subscribe.cpp
+//
+// This is a Paho MQTT C++ client, sample application.
+//
+// This application is an MQTT subscriber using the C++ asynchronous client
+// interface, employing callbacks to receive messages and status updates.
+//
+// The sample demonstrates:
+// - Connecting to an MQTT server/broker using MQTT v5.
+// - Subscribing to a topic
+// - Receiving messages through the callback API
+// - Displaying MQTT v5 message properties.
+// - Receiving network disconnect updates and attempting manual reconnects.
+// - Using a "clean session" and manually re-subscribing to topics on
+// reconnect.
+//
+
+/*******************************************************************************
+ * Copyright (c) 2013-2025 Frank Pagliughi
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v2.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v20.html
+ * and the Eclipse Distribution License is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ * Frank Pagliughi - initial implementation and documentation
+ *******************************************************************************/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "mqtt/async_client.h"
+
+const std::string DFLT_SERVER_URI("mqtt://localhost:1883");
+const std::string CLIENT_ID("paho_cpp_async_subscribe");
+const std::string TOPIC("#");
+
+const int QOS = 1;
+const int N_RETRY_ATTEMPTS = 5;
+
+/////////////////////////////////////////////////////////////////////////////
+
+// Callbacks for the success or failures of requested actions.
+// This could be used to initiate further action, but here we just log the
+// results to the console.
+
+class action_listener : public virtual mqtt::iaction_listener
+{
+ std::string name_;
+
+ void on_failure(const mqtt::token& tok) override
+ {
+ std::cout << name_ << " failure";
+ if (tok.get_message_id() != 0)
+ std::cout << " for token: [" << tok.get_message_id() << "]" << std::endl;
+ std::cout << std::endl;
+ }
+
+ void on_success(const mqtt::token& tok) override
+ {
+ std::cout << name_ << " success";
+ if (tok.get_message_id() != 0)
+ std::cout << " for token: [" << tok.get_message_id() << "]" << std::endl;
+ auto top = tok.get_topics();
+ if (top && !top->empty())
+ std::cout << "\ttoken topic: '" << (*top)[0] << "', ..." << std::endl;
+ std::cout << std::endl;
+ }
+
+public:
+ action_listener(const std::string& name) : name_(name) {}
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Local callback & listener class for use with the client connection.
+ * This is primarily intended to receive messages, but it will also monitor
+ * the connection to the broker. If the connection is lost, it will attempt
+ * to restore the connection and re-subscribe to the topic.
+ */
+class callback : public virtual mqtt::callback, public virtual mqtt::iaction_listener
+
+{
+ // Counter for the number of connection retries
+ int nretry_;
+ // The MQTT client
+ mqtt::async_client& cli_;
+ // Options to use if we need to reconnect
+ mqtt::connect_options& connOpts_;
+ // An action listener to display the result of actions.
+ action_listener subListener_;
+
+ // This deomonstrates manually reconnecting to the broker by calling
+ // connect() again. This is a possibility for an application that keeps
+ // a copy of it's original connect_options, or if the app wants to
+ // reconnect with different options.
+ // Another way this can be done manually, if using the same options, is
+ // to just call the async_client::reconnect() method.
+ void reconnect()
+ {
+ std::this_thread::sleep_for(std::chrono::milliseconds(2500));
+ try {
+ cli_.connect(connOpts_, nullptr, *this);
+ }
+ catch (const mqtt::exception& exc) {
+ std::cerr << "Error: " << exc.what() << std::endl;
+ exit(1);
+ }
+ }
+
+ // Re-connection failure
+ void on_failure(const mqtt::token& tok) override
+ {
+ std::cout << "Connection attempt failed" << std::endl;
+ if (++nretry_ > N_RETRY_ATTEMPTS)
+ exit(1);
+ reconnect();
+ }
+
+ // (Re)connection success
+ // Either this or connected() can be used for callbacks.
+ void on_success(const mqtt::token& tok) override {}
+
+ // (Re)connection success
+ void connected(const std::string& cause) override
+ {
+ std::cout << "\nConnection success" << std::endl;
+ std::cout << "\nSubscribing to topic '" << TOPIC << "'\n"
+ << "\tfor client " << CLIENT_ID << " using QoS" << QOS << "\n"
+ << "\nPress Q to quit\n"
+ << std::endl;
+
+ cli_.subscribe(TOPIC, QOS, nullptr, subListener_);
+ }
+
+ // Callback for when the connection is lost.
+ // This will initiate the attempt to manually reconnect.
+ void connection_lost(const std::string& cause) override
+ {
+ std::cout << "\nConnection lost" << std::endl;
+ if (!cause.empty())
+ std::cout << "\tcause: " << cause << std::endl;
+
+ std::cout << "Reconnecting..." << std::endl;
+ nretry_ = 0;
+ reconnect();
+ }
+
+ // Callback for when a message arrives.
+ void message_arrived(mqtt::const_message_ptr msg) override
+ {
+ std::cout << "\nMessage arrived" << std::endl;
+ std::cout << "\ttopic: '" << msg->get_topic() << "'" << std::endl;
+ std::cout << "\tpayload: '" << msg->to_string() << std::endl;
+
+ const mqtt::properties& props = msg->get_properties();
+ if (size_t n = props.size(); n != 0) {
+ std::cout << "\tproperties (" << n << "):\n\t [";
+ for (size_t i = 0; i < n - 1; ++i) std::cout << props[i] << ", ";
+ std::cout << props[n - 1] << "]" << std::endl;
+ }
+ }
+
+ void delivery_complete(mqtt::delivery_token_ptr token) override {}
+
+public:
+ callback(mqtt::async_client& cli, mqtt::connect_options& connOpts)
+ : nretry_(0), cli_(cli), connOpts_(connOpts), subListener_("Subscription")
+ {
+ }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+int main(int argc, char* argv[])
+{
+ // A subscriber often wants the server to remember its messages when its
+ // disconnected. In that case, it needs a unique ClientID and a
+ // non-clean session.
+
+ auto serverURI = (argc > 1) ? std::string{argv[1]} : DFLT_SERVER_URI;
+
+ mqtt::async_client cli(serverURI, CLIENT_ID);
+
+ auto connOpts = mqtt::connect_options_builder::v5().clean_start(true).finalize();
+
+ // Install the callback(s) before connecting.
+ callback cb(cli, connOpts);
+ cli.set_callback(cb);
+
+ // Start the connection.
+ // When completed, the callback will subscribe to topic.
+
+ try {
+ std::cout << "Connecting to the MQTT server '" << serverURI << "'..." << std::flush;
+ cli.connect(connOpts, nullptr, cb);
+ }
+ catch (const mqtt::exception& exc) {
+ std::cerr << "\nERROR: Unable to connect to MQTT server: '" << serverURI << "'" << exc
+ << std::endl;
+ return 1;
+ }
+
+ // Just block till user tells us to quit.
+
+ while (std::tolower(std::cin.get()) != 'q');
+
+ // Disconnect
+
+ try {
+ std::cout << "\nDisconnecting from the MQTT server..." << std::flush;
+ cli.disconnect()->wait();
+ std::cout << "OK" << std::endl;
+ }
+ catch (const mqtt::exception& exc) {
+ std::cerr << exc << std::endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/examples/data_publish.cpp b/examples/data_publish.cpp
new file mode 100644
index 00000000..e3fd5010
--- /dev/null
+++ b/examples/data_publish.cpp
@@ -0,0 +1,352 @@
+// data_publish.cpp
+//
+// This is a Paho MQTT C++ client, sample application.
+//
+// It's an example of how to collect and publish periodic data to MQTT, as
+// an MQTT publisher using the C++ asynchronous client interface.
+//
+// The sample demonstrates:
+// - Connecting to an MQTT server/broker
+// - Publishing messages
+// - Using a topic object to repeatedly publish to the same topic.
+// - Automatic reconnects
+// - Off-line buffering
+// - User file-based persistence with simple encoding.
+//
+// This just uses the steady clock to run a periodic loop. Each time
+// through, it generates a random number [0-100] as simulated data and
+// creates a text, CSV payload in the form:
+// ,