mirror of
https://github.com/letscontrolit/ESPEasy.git
synced 2026-07-27 19:57:38 +00:00
Merge branch 'letscontrolit:mega' into andbad-72x40
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
name: Bug Report
|
||||
description: Create a report to help improve PubSubClient3
|
||||
labels: ["bug"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: A clear and concise description of what the bug is.
|
||||
placeholder: Tell us what happened...
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Steps to reproduce the behavior
|
||||
placeholder: |
|
||||
1. Connect to '...'
|
||||
2. Publish message to '...'
|
||||
3. See error
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: expected
|
||||
attributes:
|
||||
label: Expected behavior
|
||||
description: A clear and concise description of what you expected to happen.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Library version
|
||||
description: What version of PubSubClient3 are you running?
|
||||
placeholder: v3.3.0
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: platform
|
||||
attributes:
|
||||
label: Platform
|
||||
description: What platform are you using?
|
||||
options:
|
||||
- Arduino AVR
|
||||
- ESP32
|
||||
- ESP8266
|
||||
- Other (specify in environment)
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: environment
|
||||
attributes:
|
||||
label: Environment
|
||||
description: |
|
||||
Provide details about your hardware and software environment, including:
|
||||
- Board: (e.g., Arduino Uno, ESP12E, ESP32, NodeMCU, etc.)
|
||||
- Framework Version: (e.g., Arduino AVR 5.2.0, ESP32 Arduino 3.3.2, ESP8266 Core 3.1.2 / 3.2.0-git)
|
||||
- Development Environment: (e.g., Arduino IDE 2.3.6, PlatformIO Core 6.1.8)
|
||||
- Platform: (if Other was selected above)
|
||||
placeholder: |
|
||||
- Board:
|
||||
- Framework Version:
|
||||
- Development Environment:
|
||||
render: markdown
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: example_code
|
||||
attributes:
|
||||
label: Minimal reproducible example (MVP)
|
||||
description: Provide the smallest code/config and exact steps that reproduce the bug. Paste complete minimal sketch or commands.
|
||||
placeholder: |
|
||||
```cpp
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <PubSubClient.h>
|
||||
|
||||
// minimal setup showing the bug
|
||||
void setup() {
|
||||
// ...
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
render: markdown
|
||||
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
label: Relevant log output
|
||||
description: Please copy and paste any relevant log output
|
||||
render: shell
|
||||
@@ -0,0 +1,32 @@
|
||||
name: Feature Request
|
||||
description: Suggest a new feature for PubSubClient3
|
||||
labels: ["enhancement"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to suggest a new feature!
|
||||
|
||||
- type: textarea
|
||||
id: reason
|
||||
attributes:
|
||||
label: Describe the reason of your feature request
|
||||
description: A clear and concise description of what the problem is.
|
||||
placeholder: I want to do [...]
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: solution
|
||||
attributes:
|
||||
label: Describe the solution you'd like
|
||||
description: A clear and concise description of what you want to happen.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: context
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context or code examples about the feature request here.
|
||||
render: markdown
|
||||
+1
-1
@@ -29,7 +29,7 @@ ln -s $GITHUB_WORKSPACE $HOME/Arduino/libraries/CI_Test_Library
|
||||
|
||||
# Compile all *.ino files for the Arduino
|
||||
for f in **/*.ino ; do
|
||||
if [[ "$f" != *mqtt_esp8266.ino && "$f" != *mqtt_large_message.ino ]]; then
|
||||
if [[ "$f" != *"mqtt_esp"* ]]; then
|
||||
echo "################################################################"
|
||||
echo "Arduino Uno compiling file ${f}"
|
||||
arduino-cli compile -b arduino:avr:uno $f
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ cd $GITHUB_WORKSPACE
|
||||
#command -v clang-format >/dev/null 2>&1 || sudo apt-get -y install clang-format
|
||||
# need Ubuntu clang-format version 19.1.1 (1ubuntu1~24.04.2)
|
||||
# default Ubuntu clang-format version 18.1.3 (1ubuntu1) is not working
|
||||
sudo apt-get -y install clang-format-19
|
||||
#sudo apt-get -y install clang-format-19
|
||||
# Check clang-format output
|
||||
for f in **/*.{h,c,hpp,cpp,ino} ; do
|
||||
#if [ -f "$f" ] && [[ "$f" != "tests/"* ]]; then
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
time: "06:00"
|
||||
@@ -0,0 +1,103 @@
|
||||
name: Compile examples
|
||||
|
||||
# See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- ".github/workflows/compile-examples.yml"
|
||||
- 'examples/**'
|
||||
- 'src/**'
|
||||
pull_request:
|
||||
paths:
|
||||
- ".github/workflows/compile-examples.yml"
|
||||
- 'examples/**'
|
||||
- 'src/**'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.board.fqbn }}
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
env:
|
||||
SKETCHES_REPORTS_PATH: sketches-reports
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
|
||||
matrix:
|
||||
board:
|
||||
- fqbn: arduino:avr:uno
|
||||
platforms: |
|
||||
- name: arduino:avr
|
||||
libraries: ""
|
||||
artifact-name-suffix: arduino-avr-uno
|
||||
- fqbn: arduino:megaavr:uno2018
|
||||
platforms: |
|
||||
- name: arduino:megaavr
|
||||
libraries: |
|
||||
- name: WiFiNINA
|
||||
artifact-name-suffix: arduino-megaavr-uno2018
|
||||
- fqbn: arduino:samd:mkr1000
|
||||
platforms: |
|
||||
- name: arduino:samd
|
||||
libraries: |
|
||||
- name: WiFi101
|
||||
artifact-name-suffix: arduino-samd-mkr1000
|
||||
- fqbn: esp8266:esp8266:generic
|
||||
platforms: |
|
||||
- name: esp8266:esp8266
|
||||
source-url: https://arduino.esp8266.com/stable/package_esp8266com_index.json
|
||||
libraries: ""
|
||||
artifact-name-suffix: esp8266-esp8266-generic
|
||||
- fqbn: "esp32:esp32:esp32"
|
||||
platforms: |
|
||||
- name: esp32:esp32
|
||||
libraries: ""
|
||||
artifact-name-suffix: esp32-esp32-esp32
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Download SRAM library
|
||||
run: |
|
||||
mkdir -p ./arduino-libraries
|
||||
git -C ./arduino-libraries clone https://github.com/ennui2342/arduino-sram.git
|
||||
|
||||
- name: Filter examples
|
||||
if: success()
|
||||
run: |
|
||||
if [[ "${{ matrix.board.fqbn }}" == esp32:esp32:* ]]; then
|
||||
echo "Removing non-ESP32 specific examples"
|
||||
rm -rf examples/mqtt_stream
|
||||
fi
|
||||
if [[ ! "${{ matrix.board.fqbn }}" == *:esp*:* ]]; then
|
||||
echo "Removing ESP specific examples"
|
||||
rm -rf examples/mqtt_esp*
|
||||
fi
|
||||
|
||||
- name: Compile examples
|
||||
uses: arduino/compile-sketches@v1
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
fqbn: ${{ matrix.board.fqbn }}
|
||||
platforms: ${{ matrix.board.platforms }}
|
||||
libraries: |
|
||||
# Install the library from the local path
|
||||
- source-path: ./
|
||||
- source-path: ./arduino-libraries/arduino-sram
|
||||
# Install libraries from GitHub
|
||||
#- source-url: https://github.com/ennui2342/arduino-sram
|
||||
- name: Ethernet
|
||||
${{ matrix.board.libraries }}
|
||||
sketch-paths: |
|
||||
- examples
|
||||
enable-deltas-report: true
|
||||
sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }}
|
||||
|
||||
- name: Save sketches report as workflow artifact
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
if-no-files-found: error
|
||||
path: ${{ env.SKETCHES_REPORTS_PATH }}
|
||||
name: sketches-report-${{ matrix.board.artifact-name-suffix }}
|
||||
+6
-7
@@ -7,7 +7,7 @@ name: Generate Doxygen API and deploy content to GitHub Pages
|
||||
on:
|
||||
# Runs on pushes targeting the default branch
|
||||
push:
|
||||
branches: ["master"]
|
||||
branches: ["release"]
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
@@ -34,12 +34,11 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
- name: Update Doxyfile PROJECT_NUMBER
|
||||
run: bash .github/doxygen-update-version.sh
|
||||
- name: Doxygenize
|
||||
#uses: langroodi/doxygenize@v1.7.1 # waiting for update ...
|
||||
uses: langroodi/doxygenize@6e920681c5d838e9a1b5cd273b814d1e4023b63d
|
||||
uses: langroodi/doxygenize@v1.7.1
|
||||
#uses: hmueller01/doxygenize@update-alpine-linux+patches
|
||||
with:
|
||||
# Doxygen configuration file path
|
||||
@@ -54,12 +53,12 @@ jobs:
|
||||
# run: |
|
||||
# find ./site
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v5
|
||||
uses: actions/configure-pages@v6
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
uses: actions/upload-pages-artifact@v5
|
||||
with:
|
||||
#path: '.' # Upload entire repository
|
||||
path: './site'
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
uses: actions/deploy-pages@v5
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
name: Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
paths:
|
||||
- 'examples/**'
|
||||
- 'src/**'
|
||||
- 'tests/**'
|
||||
pull_request:
|
||||
branches: [ "master" ]
|
||||
|
||||
jobs:
|
||||
run-checks:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install deps
|
||||
# need Ubuntu clang-format version 19.1.1 (1ubuntu1~24.04.2)
|
||||
# default Ubuntu clang-format version 18.1.3 (1ubuntu1) is not working
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y clang-format-19
|
||||
|
||||
- name: Check clang-format conformity
|
||||
run: bash .github/clang-lint.sh
|
||||
@@ -0,0 +1,24 @@
|
||||
name: Report Size Deltas
|
||||
|
||||
# See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- ".github/workflows/report-size-deltas.yml"
|
||||
schedule:
|
||||
# Run at the minimum interval allowed by GitHub Actions.
|
||||
# Note: GitHub Actions periodically has outages which result in workflow failures.
|
||||
# In this event, the workflows will start passing again once the service recovers.
|
||||
- cron: "*/5 * * * *"
|
||||
workflow_dispatch:
|
||||
repository_dispatch:
|
||||
|
||||
jobs:
|
||||
report:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Comment size deltas reports to PRs
|
||||
uses: arduino/report-size-deltas@v1
|
||||
with:
|
||||
# Regex matching the names of the workflow artifacts created by the "Compile Examples" workflow
|
||||
sketches-reports-source: ^sketches-report-.+
|
||||
Vendored
+5
-8
@@ -1,4 +1,4 @@
|
||||
name: build
|
||||
name: Unit tests
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -11,14 +11,11 @@ on:
|
||||
branches: [ "master" ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
run-tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Check clang-format conformity
|
||||
run: bash .github/clang-lint.sh
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Build tests
|
||||
# Build / Execute tests defined in tests folder
|
||||
@@ -31,5 +28,5 @@ jobs:
|
||||
#run: make test
|
||||
run: bin/connect_spec && bin/publish_spec && bin/receive_spec && bin/subscribe_spec
|
||||
|
||||
- name: Build on Arduino CLI
|
||||
run: bash .github/build-arduino.sh
|
||||
# - name: Build on Arduino CLI
|
||||
# run: bash .github/build-arduino.sh
|
||||
@@ -1,6 +1,8 @@
|
||||
tests/bin
|
||||
.pioenvs
|
||||
.piolibdeps
|
||||
.clang_complete
|
||||
.gcc-flags.json
|
||||
.pio/
|
||||
.pioenvs
|
||||
.piolibdeps
|
||||
.vscode/
|
||||
site/api
|
||||
tests/bin
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
# Changelog
|
||||
|
||||
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/).
|
||||
|
||||
## Unreleased
|
||||
|
||||
### Changed
|
||||
|
||||
* Improved test coverage for all QoS levels (0, 1, 2)
|
||||
* Increased robustness and correctness in client-side handling of QoS 1 and QoS 2 messages (proper handling of PUBACK, PUBREC, PUBREL, PUBCOMP sequences)
|
||||
* Merged and cleaned up tests to ensure MQTT protocol compliance for all QoS scenarios
|
||||
|
||||
## [3.3.0] - 2025-12-14
|
||||
|
||||
### Added
|
||||
|
||||
* Speedup publish large messages by using a buffer by @TD-er in [#59](https://github.com/hmueller01/pubsubclient3/pull/59)
|
||||
* Support `PROGMEM` and `__FlashStringHelper` topics by @hmueller01 in [#72](https://github.com/hmueller01/pubsubclient3/pull/72)
|
||||
* Added issue template by @hmueller01 in [#76](https://github.com/hmueller01/pubsubclient3/pull/76)
|
||||
* Report delta sizes in pull requests by @hmueller01 in [#77](https://github.com/hmueller01/pubsubclient3/pull/77)
|
||||
|
||||
### Changed
|
||||
|
||||
* Refactored private members by @hmueller01 in [#68](https://github.com/hmueller01/pubsubclient3/pull/68)
|
||||
* Refactored private functions by @hmueller01 in [#70](https://github.com/hmueller01/pubsubclient3/pull/70)
|
||||
* Do not crash if `_client` not set by @hmueller01 in [#69](https://github.com/hmueller01/pubsubclient3/pull/69)
|
||||
* Minor updates that come across by @hmueller01 in [#73](https://github.com/hmueller01/pubsubclient3/pull/73)
|
||||
* Inline optimisation by @hmueller01 in [#75](https://github.com/hmueller01/pubsubclient3/pull/75)
|
||||
* Bump actions/upload-pages-artifact from 3 to 4 by @dependabot[bot] in [#78](https://github.com/hmueller01/pubsubclient3/pull/78)
|
||||
* Bump actions/checkout from 2 to 5 by @dependabot[bot] in [#79](https://github.com/hmueller01/pubsubclient3/pull/79)
|
||||
* Tag unused parameter to avoid warnings by @hmueller01 in [#82](https://github.com/hmueller01/pubsubclient3/pull/82)
|
||||
* Fix compile warning at strnlen bound by @hmueller01 in [#83](https://github.com/hmueller01/pubsubclient3/pull/83)
|
||||
* Fix deprecated `BUILTIN_LED` by @hmueller01 in [#84](https://github.com/hmueller01/pubsubclient3/pull/84)
|
||||
* Bump actions/checkout from 5 to 6 by @dependabot[bot] in [#85](https://github.com/hmueller01/pubsubclient3/pull/85)
|
||||
* Update workflows by @hmueller01 in [#86](https://github.com/hmueller01/pubsubclient3/pull/86)
|
||||
|
||||
## [3.2.1] - 2025-09-11
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed bug introduced with QoS > 0 support (#65)
|
||||
|
||||
## [3.2.0] - 2025-07-20
|
||||
|
||||
### Added
|
||||
|
||||
- Support publish at QoS 1 and 2 (by @hmueller01) (#49)
|
||||
- Doxygen API documentation on gh-pages (by @hmueller01) (#51)
|
||||
|
||||
### Changed
|
||||
|
||||
- Add check for nullptr in `CHECK_STRING_LENGTH` (by @TD-er) (#48)
|
||||
- Move `CHECK_STRING_LENGTH` to `PubSubClient.cpp` (by @hmueller01) (#50)
|
||||
- Get rid of lazy calling parameter (by @hmueller01) (#53)
|
||||
- Implemented `writeNextMsgId()` (by @hmueller01) (#54)
|
||||
- Cleanup `writeString()` (by @hmueller01) (#55)
|
||||
|
||||
## [3.1.0] - 2025-03-20
|
||||
|
||||
### Added
|
||||
|
||||
- Added `ERROR_PSC_PRINTF` and `ERROR_PSC_PRINTF_P` outputs (#25)
|
||||
|
||||
### Changed
|
||||
|
||||
- Fix `setServer(domain, ...)` by copying domain string to an internal buffer (prevent potential dangling pointer) (#10)
|
||||
- Connect to broker only if port != 0 (protect against incorrect initialization) (#10)
|
||||
- Refactored buffer length types to `size_t` (#11)
|
||||
- Added warnings and `-Werror` to tests Makefile (#11)
|
||||
- Reformatted tests code using Google style (see `.clang-format`) (#11)
|
||||
- Fix keepalive handling (thanks to @uschnindler) (#14)
|
||||
- Use initializer lists for constructors (#15)
|
||||
- Fix `DEBUG_PSC_PRINTF` outputs (#18)
|
||||
- Introduce `MQTTRETAINED` flag (#21)
|
||||
- Added documentation on `readByte()` and `readPacket()` (#23)
|
||||
- Refactored `buildHeader()`, `readPacket()`, `readByte()`, `beginPublish()`/`endPublish()`, `publish()`/`publish_P()`, `connect()`, `connected()`, `subscribe()`/`unsubscribe()` and internal timing handling (#22, #23, #28, #30, #31, #33, #34, #37, #38, #39, #40, #44)
|
||||
- Fixed potential memory corruption in `MQTTPUBLISH` callback preparation (#25)
|
||||
- Fixed a missing failure test on `_client->read()` in `readByte()` (#32)
|
||||
- Switch from constructor init-lists to class member initialization (C++ core guideline C.45) (#42)
|
||||
|
||||
## [3.0.2] - 2025-02-27
|
||||
|
||||
### Added
|
||||
|
||||
- GitHub workflow to execute tests
|
||||
- GitHub workflow to compile examples using Arduino CLI
|
||||
- Examples: Use a better source of randomness (#9)
|
||||
- Optionally deactivate `std::function` usage (#7)
|
||||
|
||||
## [3.0.1] - 2025-02-20
|
||||
|
||||
### Added
|
||||
|
||||
- Added `.editorconfig`
|
||||
- Added GitHub workflow to check code style on push/PR
|
||||
|
||||
### Changed
|
||||
|
||||
- Reformatted code using Google style
|
||||
- Fixes for tests: missing def for `strlen_P` & Python libs
|
||||
|
||||
## [3.0] - 2025-02-17
|
||||
|
||||
Maintenance taken over by Holger Mueller
|
||||
|
||||
### Added
|
||||
|
||||
- In-source documentation added to `PubSubClient` header
|
||||
- Add flag for enabling debugging of library
|
||||
|
||||
### Changed
|
||||
|
||||
- Always use `PubSubClient()` constructor
|
||||
- Use `bool` instead of `boolean`
|
||||
- Add `yield()` calls in `connect()` and `write()` to avoid watchdog resets
|
||||
- Fix bug in `publish_P` handling of PROGMEM payload length
|
||||
- Fix increase `bytesToWrite` to `uint16_t` to prevent overflow
|
||||
- Remove compiler warning about unsigned `expectedLength`
|
||||
- Extend usage of `std::function` where available
|
||||
- Fix for keep alive zero
|
||||
|
||||
## [2.8] - 2020-05-20
|
||||
|
||||
### Added
|
||||
|
||||
- `setBufferSize()` to override `MQTT_MAX_PACKET_SIZE`
|
||||
- `setKeepAlive()` to override `MQTT_KEEPALIVE`
|
||||
- `setSocketTimeout()` to override `MQTT_SOCKET_TIMEOUT`
|
||||
- Check to prevent subscribe/unsubscribe to empty topics
|
||||
- Declare WiFi mode prior to connect in ESP example
|
||||
- Use `strnlen` to avoid overruns
|
||||
- Support pre-connected `Client` objects
|
||||
|
||||
## [2.7] - 2018-11-02
|
||||
|
||||
### Added
|
||||
|
||||
- Added large-payload API: `beginPublish`/`write`/`publish`/`endPublish`
|
||||
- Added `yield` calls to improve reliability on ESP
|
||||
- Added Clean Session flag to connect options
|
||||
- Added ESP32 support for functional callback signature
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed remaining-length handling to prevent buffer overrun
|
||||
|
||||
## [2.4] - 2015-11-21
|
||||
|
||||
### Added
|
||||
|
||||
- `MQTT_SOCKET_TIMEOUT` to avoid blocking indefinitely while waiting for inbound data
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed return code when publishing >256 bytes
|
||||
|
||||
## [2.3] - 2015-09-11
|
||||
|
||||
### Added
|
||||
|
||||
- `publish(topic,payload,retained)` convenience overload
|
||||
|
||||
## [2.2] - 2015-09-07
|
||||
|
||||
### Changed
|
||||
|
||||
- Changed code layout to match Arduino Library requirements
|
||||
|
||||
## [2.1] - 2015-09-07
|
||||
|
||||
### Added
|
||||
|
||||
- `MAX_TRANSFER_SIZE` to chunk messages if needed
|
||||
- Reject topic/payloads that exceed `MQTT_MAX_PACKET_SIZE`
|
||||
|
||||
## [2.0] - 2015-08-28
|
||||
|
||||
### Added
|
||||
|
||||
- MQTT 3.1.1 support
|
||||
- Fix PROGMEM handling for Intel Galileo/ESP8266
|
||||
- Overloaded constructors for convenience
|
||||
- Chainable setters for server/callback/client/stream
|
||||
- `state()` function to return CONNACK code
|
||||
|
||||
## [1.0] - 2009-02-02
|
||||
|
||||
- Initial release notes: QoS 0 only, 128 byte max message size, keepalive 30s, no Will messages
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
3.1.0
|
||||
* Fix setServer(domain, ...) by copy domain string to own buffer (prevent potential dangling string pointer) #10
|
||||
* Connect to broker only if port != 0 (e.g. in case of incorrect PubSubClient initialization) #10
|
||||
* Refactored different buffer length types to size_t #11
|
||||
* Added a bunch of warnings and -Werror to tests Makefile #11
|
||||
* Reformatted tests code using Google sytle (see .clang-format) #11
|
||||
* Fix keepalive handling, thanks to @uschnindler providing this to thingsboard #14
|
||||
* Use initializer lists instead of assigning global members in constructor #15
|
||||
* Fix DEBUG_PSC_PRINTF outputs #18
|
||||
* Added ERROR_PSC_PRINTF and ERROR_PSC_PRINTF_P outputs #25
|
||||
* Introduce MQTTRETAINED flag instead of hard coding #21
|
||||
* Added documentation on readByte() and readPacket() functions #23
|
||||
* Refactored buildHeader() (change return type, use MQTT_MAX_HEADER_SIZE, locals) #22, #34, #37
|
||||
* Refactored readPacket() (changed return type to size_t, used MQTT_MAX_HEADER_SIZE, locals) #23
|
||||
* Refactored readByte() #23
|
||||
* Refactored beginPublish() and endPublish() #28
|
||||
* Refactored publish() #31
|
||||
* Refactored publish_P() #30
|
||||
* Refactored connect() #40
|
||||
* Refactored connected() (mostly rewritten and simplified, added setting pingOutstanding, don't need flush()) #44
|
||||
* Refactored subscribe() and unsubscribe() #44
|
||||
* Refactored internal socketTimeout and keepAlive to millis to improve performance #33, #38, #39
|
||||
* Fix potential memory corruption in MQTTPUBLISH callback preparation #25
|
||||
* Fix potential error in readByte() (missing failure test on _client->read()) #32
|
||||
* Switch from constructor init-lists to class member initialization, see C++ core guideline C.45 #42
|
||||
|
||||
3.0.2
|
||||
* Added github workflow to execute tests
|
||||
* Added github workflow to compile examples using arduino-cli
|
||||
* Examples: Use a better source of random #9
|
||||
* Deactivate use of std::function on demand #7
|
||||
|
||||
3.0.1
|
||||
* Reformatted code using Google sytle (see .clang-format)
|
||||
* Added .editorconfig
|
||||
* Added github workflow to check code sytle on push and pull request
|
||||
* Fix-tests: missing def for strlen_P & Python libs
|
||||
|
||||
3.0
|
||||
* Maintenance taken over by Holger Mueller
|
||||
* Adds in-source documentation to PubSubClient header.
|
||||
* Add flag for enabling debugging of library
|
||||
* Always use PubSubClient() constructor
|
||||
* Use bool instead of boolean
|
||||
* Add yield() calls in connect() and write() to avoid wdt resets if either blocks for too long
|
||||
* Fix bug in publish_P which will always treat the payload length as 0 when used with PROGMEM
|
||||
* Fix increase `bytesToWrite` to uint16_t to prevent overflow
|
||||
* Remove compiler warning `expectedLength` should be unsigned
|
||||
* Extend usage of std::function on all the platforms where it's available
|
||||
* Fix for keep alive zero
|
||||
|
||||
2.8
|
||||
* Add setBufferSize() to override MQTT_MAX_PACKET_SIZE
|
||||
* Add setKeepAlive() to override MQTT_KEEPALIVE
|
||||
* Add setSocketTimeout() to overide MQTT_SOCKET_TIMEOUT
|
||||
* Added check to prevent subscribe/unsubscribe to empty topics
|
||||
* Declare wifi mode prior to connect in ESP example
|
||||
* Use `strnlen` to avoid overruns
|
||||
* Support pre-connected Client objects
|
||||
|
||||
2.7
|
||||
* Fix remaining-length handling to prevent buffer overrun
|
||||
* Add large-payload API - beginPublish/write/publish/endPublish
|
||||
* Add yield call to improve reliability on ESP
|
||||
* Add Clean Session flag to connect options
|
||||
* Add ESP32 support for functional callback signature
|
||||
* Various other fixes
|
||||
|
||||
2.4
|
||||
* Add MQTT_SOCKET_TIMEOUT to prevent it blocking indefinitely
|
||||
whilst waiting for inbound data
|
||||
* Fixed return code when publishing >256 bytes
|
||||
|
||||
2.3
|
||||
* Add publish(topic,payload,retained) function
|
||||
|
||||
2.2
|
||||
* Change code layout to match Arduino Library reqs
|
||||
|
||||
2.1
|
||||
* Add MAX_TRANSFER_SIZE def to chunk messages if needed
|
||||
* Reject topic/payloads that exceed MQTT_MAX_PACKET_SIZE
|
||||
|
||||
2.0
|
||||
* Add (and default to) MQTT 3.1.1 support
|
||||
* Fix PROGMEM handling for Intel Galileo/ESP8266
|
||||
* Add overloaded constructors for convenience
|
||||
* Add chainable setters for server/callback/client/stream
|
||||
* Add state function to return connack return code
|
||||
|
||||
1.9
|
||||
* Do not split MQTT packets over multiple calls to _client->write()
|
||||
* API change: All constructors now require an instance of Client
|
||||
to be passed in.
|
||||
* Fixed example to match 1.8 api changes - dpslwk
|
||||
* Added username/password support - WilHall
|
||||
* Added publish_P - publishes messages from PROGMEM - jobytaffey
|
||||
|
||||
1.8
|
||||
* KeepAlive interval is configurable in PubSubClient.h
|
||||
* Maximum packet size is configurable in PubSubClient.h
|
||||
* API change: Return boolean rather than int from various functions
|
||||
* API change: Length parameter in message callback changed
|
||||
from int to unsigned int
|
||||
* Various internal tidy-ups around types
|
||||
|
||||
1.7
|
||||
* Improved keepalive handling
|
||||
* Updated to the Arduino-1.0 API
|
||||
|
||||
1.6
|
||||
* Added the ability to publish a retained message
|
||||
|
||||
1.5
|
||||
* Added default constructor
|
||||
* Fixed compile error when used with arduino-0021 or later
|
||||
|
||||
1.4
|
||||
* Fixed connection lost handling
|
||||
|
||||
1.3
|
||||
* Fixed packet reading bug in PubSubClient.readPacket
|
||||
|
||||
1.2
|
||||
* Fixed compile error when used with arduino-0016 or later
|
||||
|
||||
1.1
|
||||
* Reduced size of library
|
||||
* Added support for Will messages
|
||||
* Clarified licensing - see LICENSE.txt
|
||||
|
||||
1.0
|
||||
* Only Quality of Service (QOS) 0 messaging is supported
|
||||
* The maximum message size, including header, is 128 bytes
|
||||
* The keepalive interval is set to 30 seconds
|
||||
* No support for Will messages
|
||||
Regular → Executable
@@ -29,7 +29,7 @@ Full API documentation is available here: https://hmueller01.github.io/pubsubcli
|
||||
## Limitations
|
||||
|
||||
- The client is based on the [MQTT Version 3.1.1 specification](https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html) with some limitations.
|
||||
- It can publish at QoS 0, 1 or 2.
|
||||
- It can publish at QoS 0 and since [v3.2.0](https://github.com/hmueller01/pubsubclient3/releases/tag/v3.2.0) also at QoS 1 or 2.
|
||||
|
||||
**WARNING:** No retransmission is supported to keep the library as much memory friendly as possible.
|
||||
|
||||
@@ -45,7 +45,17 @@ Full API documentation is available here: https://hmueller01.github.io/pubsubcli
|
||||
`PubSubClient::setKeepAlive(keepAlive)`.
|
||||
- The client uses MQTT 3.1.1 by default. It can be changed to use MQTT 3.1 by
|
||||
changing value of `MQTT_VERSION` in `PubSubClient.h`.
|
||||
|
||||
- Since [v3.3.0](https://github.com/hmueller01/pubsubclient3/releases/tag/v3.3.0) it can publish and subscribe to `PROGMEM` or `__FlashStringHelper` topics.
|
||||
Details see [mqtt_progmem](https://github.com/hmueller01/pubsubclient3/blob/aae84e4d1aa65e752e19e30239b5796b4fe2705b/examples/mqtt_progmem/src/mqtt_progmem.cpp#L39-L48) example.
|
||||
But if you like to publish `PROGMEM` topics you have to use
|
||||
```c
|
||||
const char TOPIC[] PROGMEM = "test";
|
||||
const char HELLO_WORLD[] PROGMEM = "hello world";
|
||||
client.beginPublish_P(TOPIC, strlen_P(HELLO_WORLD), MQTT_QOS0, false);
|
||||
client.write_P(HELLO_WORLD);
|
||||
client.endPublish();
|
||||
```
|
||||
as `client.publish_P(...)` is already used for `PROGMEM` payloads.
|
||||
|
||||
## Compatible Hardware
|
||||
|
||||
@@ -69,6 +79,10 @@ The library cannot currently be used with hardware based on the ENC28J60 chip
|
||||
such as the Nanode or the Nuelectronics Ethernet Shield. For those, there is an
|
||||
[alternative library](https://github.com/njh/NanodeMQTT) available.
|
||||
|
||||
## Changelog
|
||||
|
||||
See [CHANGELOG.md](CHANGELOG.md)
|
||||
|
||||
## License
|
||||
|
||||
This code is released under the MIT License.
|
||||
This code is released under the [MIT License](LICENSE.txt).
|
||||
|
||||
Regular → Executable
+3
-1
@@ -11,12 +11,14 @@
|
||||
#include <PubSubClient.h>
|
||||
#include <SPI.h>
|
||||
|
||||
#define _UNUSED_ __attribute__((unused))
|
||||
|
||||
// Update these with values suitable for your network.
|
||||
byte mac[] = {0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED};
|
||||
IPAddress ip(172, 16, 0, 100);
|
||||
IPAddress server(172, 16, 0, 2);
|
||||
|
||||
void callback(char* topic, uint8_t* payload, size_t plength) {
|
||||
void callback(_UNUSED_ char* topic, _UNUSED_ uint8_t* payload, _UNUSED_ size_t plength) {
|
||||
// handle message arrived
|
||||
}
|
||||
|
||||
|
||||
Regular → Executable
+5
-5
@@ -23,7 +23,7 @@
|
||||
#elif defined(ESP32)
|
||||
#include <WiFi.h>
|
||||
#include <esp_random.h>
|
||||
#define BUILTIN_LED A0
|
||||
#define LED_BUILTIN A0
|
||||
#define RANDOM_REG32 esp_random()
|
||||
#else
|
||||
#error Platform not supported.
|
||||
@@ -77,11 +77,11 @@ void callback(char* topic, uint8_t* payload, size_t plength) {
|
||||
|
||||
// Switch on the LED if an 1 was received as first character
|
||||
if ((char)payload[0] == '1') {
|
||||
digitalWrite(BUILTIN_LED, LOW); // Turn the LED on (Note that LOW is the voltage level
|
||||
digitalWrite(LED_BUILTIN, LOW); // Turn the LED on (Note that LOW is the voltage level
|
||||
// but actually the LED is on; this is because
|
||||
// it is active low on the ESP-01)
|
||||
} else {
|
||||
digitalWrite(BUILTIN_LED, HIGH); // Turn the LED off by making the voltage HIGH
|
||||
digitalWrite(LED_BUILTIN, HIGH); // Turn the LED off by making the voltage HIGH
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ void reconnect() {
|
||||
}
|
||||
|
||||
void setup() {
|
||||
pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output
|
||||
pinMode(LED_BUILTIN, OUTPUT); // Initialize the LED_BUILTIN pin as an output
|
||||
Serial.begin(115200);
|
||||
setup_wifi();
|
||||
client.setServer(mqtt_server, 1883);
|
||||
@@ -127,7 +127,7 @@ void loop() {
|
||||
if (now - lastMsg > 2000) {
|
||||
lastMsg = now;
|
||||
++value;
|
||||
snprintf(msg, MSG_BUFFER_SIZE, "hello world #%ld", value);
|
||||
snprintf(msg, MSG_BUFFER_SIZE, "hello world #%d", value);
|
||||
Serial.print("Publish message: ");
|
||||
Serial.println(msg);
|
||||
client.publish("outTopic", msg);
|
||||
-2
@@ -28,7 +28,6 @@
|
||||
#elif defined(ESP32)
|
||||
#include <WiFi.h>
|
||||
#include <esp_random.h>
|
||||
#define BUILTIN_LED A0
|
||||
#define RANDOM_REG32 esp_random()
|
||||
#else
|
||||
#error Platform not supported.
|
||||
@@ -170,7 +169,6 @@ void reconnect() {
|
||||
}
|
||||
|
||||
void setup() {
|
||||
pinMode(BUILTIN_LED, OUTPUT); // Initialize the BUILTIN_LED pin as an output
|
||||
Serial.begin(115200);
|
||||
setup_wifi();
|
||||
client.setServer(mqtt_server, 1883);
|
||||
@@ -0,0 +1,3 @@
|
||||
// Example sketch showing how to use PubSubClient with strings stored in PROGMEM.
|
||||
// This needs to be an empty file to satisfy the arduino-cli build system.
|
||||
// See src/mqtt_progmem.cpp for the actual example code.
|
||||
@@ -0,0 +1,40 @@
|
||||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
; https://docs.platformio.org/en/latest/boards/atmelavr/uno.html
|
||||
|
||||
[platformio]
|
||||
description = Basic MQTT example with Authentication and Progmem strings
|
||||
|
||||
[env]
|
||||
framework = arduino
|
||||
lib_deps =
|
||||
arduino-libraries/Ethernet @ ^2.0.2
|
||||
hmueller01/PubSubClient3 @ ^3.3.0
|
||||
build_flags =
|
||||
; -D DEBUG_ESP_PORT=Serial
|
||||
; -D DEBUG_PUBSUBCLIENT
|
||||
; -D MQTT_MAX_PACKET_SIZE=512
|
||||
; -D MQTT_KEEPALIVE=120
|
||||
|
||||
[env:uno]
|
||||
platform = atmelavr
|
||||
board = uno
|
||||
|
||||
[env:esp8266]
|
||||
platform = espressif8266
|
||||
platform_packages = platformio/framework-arduinoespressif8266 @ https://github.com/esp8266/Arduino.git
|
||||
board = esp12e
|
||||
build_flags =
|
||||
${env.build_flags}
|
||||
-D PIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK305
|
||||
|
||||
[env:esp32]
|
||||
platform = espressif32
|
||||
board = esp32dev
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
Basic MQTT example with Authentication
|
||||
|
||||
- connects to an MQTT server, providing username
|
||||
and password
|
||||
- publishes "hello world" to the topic "outTopic"
|
||||
- subscribes to the topic "inTopic"
|
||||
*/
|
||||
|
||||
#include <Ethernet.h>
|
||||
#include <PubSubClient.h>
|
||||
#include <SPI.h>
|
||||
|
||||
#define _UNUSED_ __attribute__((unused))
|
||||
|
||||
// Update these with values suitable for your network.
|
||||
byte mac[] = {0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED};
|
||||
IPAddress ip(172, 16, 0, 100);
|
||||
IPAddress server(172, 16, 0, 2);
|
||||
const char HELLO_WORLD_3[] PROGMEM = "hello world 3";
|
||||
const char HELLO_WORLD_4[] PROGMEM = "hello world 4";
|
||||
const char SUBSCRIBE_TOPIC[] PROGMEM = "inTopic1";
|
||||
|
||||
void callback(_UNUSED_ char* topic, _UNUSED_ uint8_t* payload, _UNUSED_ size_t plength) {
|
||||
// handle message arrived
|
||||
}
|
||||
|
||||
EthernetClient ethClient;
|
||||
PubSubClient client(server, 1883, callback, ethClient);
|
||||
|
||||
void setup() {
|
||||
Ethernet.begin(mac, ip);
|
||||
// Note - the default maximum packet size is 128 bytes. If the
|
||||
// combined length of clientId, username and password exceed this use the
|
||||
// following to increase the buffer size:
|
||||
// client.setBufferSize(255);
|
||||
|
||||
if (client.connect("arduinoClient", "testuser", "testpass")) {
|
||||
client.publish(F("outTopic"), "hello world 1", MQTT_QOS0, false);
|
||||
client.publish(F("outTopic"), F("hello world 2"), MQTT_QOS1, false);
|
||||
client.publish_P(F("outTopic"), HELLO_WORLD_3, MQTT_QOS2, false);
|
||||
|
||||
client.beginPublish(F("outTopic"), strlen_P(HELLO_WORLD_4), MQTT_QOS1, false);
|
||||
client.write_P(HELLO_WORLD_4);
|
||||
client.endPublish();
|
||||
|
||||
client.subscribe(F("inTopic"));
|
||||
client.subscribe_P(SUBSCRIBE_TOPIC, MQTT_QOS1);
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
client.loop();
|
||||
}
|
||||
@@ -17,6 +17,8 @@
|
||||
#include <PubSubClient.h>
|
||||
#include <SPI.h>
|
||||
|
||||
#define _UNUSED_ __attribute__((unused))
|
||||
|
||||
// Update these with values suitable for your network.
|
||||
byte mac[] = {0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED};
|
||||
IPAddress ip(172, 16, 0, 100);
|
||||
@@ -29,7 +31,7 @@ EthernetClient ethClient;
|
||||
PubSubClient client(server, 1883, callback, ethClient);
|
||||
|
||||
// Callback function
|
||||
void callback(char* topic, uint8_t* payload, size_t plength) {
|
||||
void callback(_UNUSED_ char* topic, uint8_t* payload, size_t plength) {
|
||||
// In order to republish this payload, a copy must be made
|
||||
// as the orignal payload buffer will be overwritten whilst
|
||||
// constructing the PUBLISH packet.
|
||||
|
||||
+3
-1
@@ -11,12 +11,14 @@
|
||||
#include <PubSubClient.h>
|
||||
#include <SPI.h>
|
||||
|
||||
#define _UNUSED_ __attribute__((unused))
|
||||
|
||||
// Update these with values suitable for your hardware/network.
|
||||
byte mac[] = {0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED};
|
||||
IPAddress ip(172, 16, 0, 100);
|
||||
IPAddress server(172, 16, 0, 2);
|
||||
|
||||
void callback(char* topic, uint8_t* payload, size_t plength) {
|
||||
void callback(_UNUSED_ char* topic, _UNUSED_ uint8_t* payload, _UNUSED_ size_t plength) {
|
||||
// handle message arrived
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include <SPI.h>
|
||||
#include <SRAM.h>
|
||||
|
||||
#define _UNUSED_ __attribute__((unused))
|
||||
|
||||
// Update these with values suitable for your network.
|
||||
byte mac[] = {0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED};
|
||||
IPAddress ip(172, 16, 0, 100);
|
||||
@@ -21,7 +23,7 @@ IPAddress server(172, 16, 0, 2);
|
||||
|
||||
SRAM sram(4, SRAM_1024);
|
||||
|
||||
void callback(char* topic, uint8_t* payload, size_t plength) {
|
||||
void callback(_UNUSED_ char* topic, _UNUSED_ uint8_t* payload, size_t plength) {
|
||||
sram.seek(1);
|
||||
|
||||
// do something with the message
|
||||
|
||||
Regular → Executable
+3
@@ -17,9 +17,12 @@ disconnect KEYWORD2
|
||||
publish KEYWORD2
|
||||
publish_P KEYWORD2
|
||||
beginPublish KEYWORD2
|
||||
beginPublish_P KEYWORD2
|
||||
endPublish KEYWORD2
|
||||
write KEYWORD2
|
||||
write_P KEYWORD2
|
||||
subscribe KEYWORD2
|
||||
subscribe_P KEYWORD2
|
||||
unsubscribe KEYWORD2
|
||||
loop KEYWORD2
|
||||
connected KEYWORD2
|
||||
|
||||
@@ -6,13 +6,15 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/hmueller01/pubsubclient3.git"
|
||||
},
|
||||
"version": "3.1.0",
|
||||
"version": "3.3.0",
|
||||
"license": "MIT",
|
||||
"exclude": "tests",
|
||||
"examples": "examples/*/*.ino",
|
||||
"frameworks": "arduino",
|
||||
"platforms": [
|
||||
"atmelavr",
|
||||
"atmelsam",
|
||||
"atmelmegaavr",
|
||||
"espressif8266",
|
||||
"espressif32"
|
||||
]
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name=PubSubClient3
|
||||
version=3.1.0
|
||||
version=3.3.0
|
||||
author=Nick O'Leary <nick.oleary@gmail.com>
|
||||
maintainer=Holger Mueller <github@euhm.de>
|
||||
license=MIT
|
||||
|
||||
Regular → Executable
+359
-312
File diff suppressed because it is too large
Load Diff
Regular → Executable
+272
-45
@@ -34,7 +34,7 @@
|
||||
* @brief Maximum packet size defined by MQTT protocol.
|
||||
*/
|
||||
#ifndef MQTT_MAX_POSSIBLE_PACKET_SIZE
|
||||
#define MQTT_MAX_POSSIBLE_PACKET_SIZE 268435455
|
||||
#define MQTT_MAX_POSSIBLE_PACKET_SIZE ((size_t)268435455) // might be limited to 65535 if size_t is 16-bit (unsigned int)
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -176,36 +176,39 @@
|
||||
class PubSubClient : public Print {
|
||||
private:
|
||||
Client* _client{};
|
||||
uint8_t* buffer{};
|
||||
size_t bufferSize{};
|
||||
unsigned long keepAliveMillis{};
|
||||
unsigned long socketTimeoutMillis{};
|
||||
uint16_t nextMsgId{};
|
||||
unsigned long lastOutActivity{};
|
||||
unsigned long lastInActivity{};
|
||||
bool pingOutstanding{};
|
||||
MQTT_CALLBACK_SIGNATURE{};
|
||||
IPAddress ip{};
|
||||
char* domain{};
|
||||
uint16_t port{};
|
||||
Stream* stream{};
|
||||
int _state{MQTT_DISCONNECTED};
|
||||
uint8_t* _buffer{};
|
||||
size_t _bufferSize{};
|
||||
size_t _bufferWritePos{};
|
||||
uint8_t _qos{MQTT_QOS0};
|
||||
unsigned long _keepAliveMillis{};
|
||||
unsigned long _socketTimeoutMillis{};
|
||||
uint16_t _nextMsgId{};
|
||||
unsigned long _lastOutActivity{};
|
||||
unsigned long _lastInActivity{};
|
||||
bool _pingOutstanding{};
|
||||
MQTT_CALLBACK_SIGNATURE{};
|
||||
IPAddress _ip{};
|
||||
char* _domain{};
|
||||
uint16_t _port{};
|
||||
Stream* _stream{};
|
||||
int _state{MQTT_DISCONNECTED};
|
||||
|
||||
size_t readPacket(uint8_t* hdrLen);
|
||||
bool handlePacket(uint8_t hdrLen, size_t len);
|
||||
bool readByte(uint8_t* result);
|
||||
bool readByte(uint8_t* result, size_t* pos);
|
||||
uint8_t buildHeader(uint8_t header, uint8_t* buf, size_t length);
|
||||
bool write(uint8_t header, uint8_t* buf, size_t length);
|
||||
size_t writeString(const char* string, uint8_t* buf, size_t pos, size_t size);
|
||||
size_t writeNextMsgId(uint8_t* buf, size_t pos, size_t size);
|
||||
uint8_t buildHeader(uint8_t header, size_t length);
|
||||
bool writeControlPacket(uint8_t header, size_t length);
|
||||
size_t writeBuffer(size_t pos, size_t size);
|
||||
size_t writeStringImpl(bool progmem, const char* string, size_t pos);
|
||||
size_t writeString(const char* string, size_t pos);
|
||||
size_t writeNextMsgId(size_t pos);
|
||||
|
||||
bool beginPublishImpl(bool progmem, const char* topic, size_t plength, uint8_t qos, bool retained);
|
||||
bool subscribeImpl(bool progmem, const char* topic, uint8_t qos);
|
||||
bool unsubscribeImpl(bool progmem, const char* topic);
|
||||
|
||||
// Add to buffer and flush if full (only to be used with beginPublish/endPublish)Add commentMore actions
|
||||
// Add to buffer and flush if full (only to be used with beginPublish/endPublish)
|
||||
size_t appendBuffer(uint8_t data);
|
||||
size_t appendBuffer(const uint8_t *data, size_t size);
|
||||
size_t flushBuffer();
|
||||
|
||||
public:
|
||||
@@ -428,7 +431,9 @@ class PubSubClient : public Print {
|
||||
* @return true If client succeeded in establishing a connection to the broker.
|
||||
* false If client failed to establish a connection to the broker.
|
||||
*/
|
||||
bool connect(const char* id);
|
||||
inline bool connect(const char* id) {
|
||||
return connect(id, nullptr, nullptr, nullptr, MQTT_QOS0, false, nullptr, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Connects the client using a clean session with username and password.
|
||||
@@ -440,7 +445,9 @@ class PubSubClient : public Print {
|
||||
* @return true If client succeeded in establishing a connection to the broker.
|
||||
* false If client failed to establish a connection to the broker.
|
||||
*/
|
||||
bool connect(const char* id, const char* user, const char* pass);
|
||||
inline bool connect(const char* id, const char* user, const char* pass) {
|
||||
return connect(id, user, pass, nullptr, MQTT_QOS0, false, nullptr, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Connects the client using a clean session and will.
|
||||
@@ -453,7 +460,9 @@ class PubSubClient : public Print {
|
||||
* @return true If client succeeded in establishing a connection to the broker.
|
||||
* false If client failed to establish a connection to the broker.
|
||||
*/
|
||||
bool connect(const char* id, const char* willTopic, uint8_t willQos, bool willRetain, const char* willMessage);
|
||||
inline bool connect(const char* id, const char* willTopic, uint8_t willQos, bool willRetain, const char* willMessage) {
|
||||
return connect(id, nullptr, nullptr, willTopic, willQos, willRetain, willMessage, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Connects the client using a clean session with username, password and will.
|
||||
@@ -470,7 +479,10 @@ class PubSubClient : public Print {
|
||||
* @return true If client succeeded in establishing a connection to the broker.
|
||||
* false If client failed to establish a connection to the broker.
|
||||
*/
|
||||
bool connect(const char* id, const char* user, const char* pass, const char* willTopic, uint8_t willQos, bool willRetain, const char* willMessage);
|
||||
inline bool connect(const char* id, const char* user, const char* pass, const char* willTopic, uint8_t willQos, bool willRetain,
|
||||
const char* willMessage) {
|
||||
return connect(id, user, pass, willTopic, willQos, willRetain, willMessage, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Connects the client with all possible parameters (user, password, will and session).
|
||||
@@ -503,7 +515,9 @@ class PubSubClient : public Print {
|
||||
* @return true If the publish succeeded.
|
||||
* false If the publish failed, either connection lost or message too large.
|
||||
*/
|
||||
bool publish(const char* topic, const char* payload);
|
||||
inline bool publish(const char* topic, const char* payload) {
|
||||
return publish(topic, payload, MQTT_QOS0, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Publishes a message to the specified topic using QoS 0.
|
||||
@@ -513,7 +527,9 @@ class PubSubClient : public Print {
|
||||
* @return true If the publish succeeded.
|
||||
* false If the publish failed, either connection lost or message too large.
|
||||
*/
|
||||
bool publish(const char* topic, const char* payload, bool retained);
|
||||
inline bool publish(const char* topic, const char* payload, bool retained) {
|
||||
return publish(topic, payload, MQTT_QOS0, retained);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Publishes a message to the specified topic.
|
||||
@@ -524,7 +540,35 @@ class PubSubClient : public Print {
|
||||
* @return true If the publish succeeded.
|
||||
* false If the publish failed, either connection lost or message too large.
|
||||
*/
|
||||
bool publish(const char* topic, const char* payload, uint8_t qos, bool retained);
|
||||
inline bool publish(const char* topic, const char* payload, uint8_t qos, bool retained) {
|
||||
return publish(topic, reinterpret_cast<const uint8_t*>(payload), payload ? strlen(payload) : 0, qos, retained);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Publishes a message to the specified topic.
|
||||
* @param topic The topic from __FlashStringHelper to publish to.
|
||||
* @param payload The message to publish.
|
||||
* @param qos The quality of service (\ref group_qos) to publish at. [0, 1, 2].
|
||||
* @param retained Publish the message with the retain flag.
|
||||
* @return true If the publish succeeded.
|
||||
* false If the publish failed, either connection lost or message too large.
|
||||
*/
|
||||
inline bool publish(const __FlashStringHelper* topic, const char* payload, uint8_t qos, bool retained) {
|
||||
return publish(topic, reinterpret_cast<const uint8_t*>(payload), payload ? strlen(payload) : 0, qos, retained);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Publishes a message from __FlashStringHelper to the specified topic from __FlashStringHelper.
|
||||
* @param topic The topic to publish to.
|
||||
* @param payload The message to publish.
|
||||
* @param qos The quality of service (\ref group_qos) to publish at. [0, 1, 2].
|
||||
* @param retained Publish the message with the retain flag.
|
||||
* @return true If the publish succeeded.
|
||||
* false If the publish failed, either connection lost or message too large.
|
||||
*/
|
||||
inline bool publish(const __FlashStringHelper* topic, const __FlashStringHelper* payload, uint8_t qos, bool retained) {
|
||||
return publish_P(topic, reinterpret_cast<const uint8_t*>(payload), payload ? strlen_P(reinterpret_cast<const char*>(payload)) : 0, qos, retained);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Publishes a non retained message to the specified topic using QoS 0.
|
||||
@@ -534,7 +578,9 @@ class PubSubClient : public Print {
|
||||
* @return true If the publish succeeded.
|
||||
* false If the publish failed, either connection lost or message too large.
|
||||
*/
|
||||
bool publish(const char* topic, const uint8_t* payload, size_t plength);
|
||||
inline bool publish(const char* topic, const uint8_t* payload, size_t plength) {
|
||||
return publish(topic, payload, plength, MQTT_QOS0, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Publishes a message to the specified topic using QoS 0.
|
||||
@@ -545,7 +591,9 @@ class PubSubClient : public Print {
|
||||
* @return true If the publish succeeded.
|
||||
* false If the publish failed, either connection lost or message too large.
|
||||
*/
|
||||
bool publish(const char* topic, const uint8_t* payload, size_t plength, bool retained);
|
||||
inline bool publish(const char* topic, const uint8_t* payload, size_t plength, bool retained) {
|
||||
return publish(topic, payload, plength, MQTT_QOS0, retained);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Publishes a message to the specified topic.
|
||||
@@ -559,6 +607,18 @@ class PubSubClient : public Print {
|
||||
*/
|
||||
bool publish(const char* topic, const uint8_t* payload, size_t plength, uint8_t qos, bool retained);
|
||||
|
||||
/**
|
||||
* @brief Publishes a message to the specified topic.
|
||||
* @param topic The topic from __FlashStringHelper to publish to.
|
||||
* @param payload The message to publish.
|
||||
* @param plength The length of the payload.
|
||||
* @param qos The quality of service (\ref group_qos) to publish at. [0, 1, 2].
|
||||
* @param retained Publish the message with the retain flag.
|
||||
* @return true If the publish succeeded.
|
||||
* false If the publish failed, either connection lost or message too large.
|
||||
*/
|
||||
bool publish(const __FlashStringHelper* topic, const uint8_t* payload, size_t plength, uint8_t qos, bool retained);
|
||||
|
||||
/**
|
||||
* @brief Publishes a message stored in PROGMEM to the specified topic using QoS 0.
|
||||
* @param topic The topic to publish to.
|
||||
@@ -567,7 +627,9 @@ class PubSubClient : public Print {
|
||||
* @return true If the publish succeeded.
|
||||
* false If the publish failed, either connection lost or message too large.
|
||||
*/
|
||||
bool publish_P(const char* topic, const char* payload, bool retained);
|
||||
inline bool publish_P(const char* topic, PGM_P payload, bool retained) {
|
||||
return publish_P(topic, payload, MQTT_QOS0, retained);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Publishes a message stored in PROGMEM to the specified topic.
|
||||
@@ -578,7 +640,22 @@ class PubSubClient : public Print {
|
||||
* @return true If the publish succeeded.
|
||||
* false If the publish failed, either connection lost or message too large.
|
||||
*/
|
||||
bool publish_P(const char* topic, const char* payload, uint8_t qos, bool retained);
|
||||
inline bool publish_P(const char* topic, PGM_P payload, uint8_t qos, bool retained) {
|
||||
return publish_P(topic, reinterpret_cast<const uint8_t*>(payload), payload ? strlen_P(payload) : 0, qos, retained);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Publishes a message stored in PROGMEM to the specified topic.
|
||||
* @param topic The topic from __FlashStringHelper to publish to.
|
||||
* @param payload The message to publish.
|
||||
* @param qos The quality of service (\ref group_qos) to publish at. [0, 1, 2].
|
||||
* @param retained Publish the message with the retain flag.
|
||||
* @return true If the publish succeeded.
|
||||
* false If the publish failed, either connection lost or message too large.
|
||||
*/
|
||||
bool publish_P(const __FlashStringHelper* topic, PGM_P payload, uint8_t qos, bool retained) {
|
||||
return publish_P(topic, reinterpret_cast<const uint8_t*>(payload), payload ? strlen_P(payload) : 0, qos, retained);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Publishes a message stored in PROGMEM to the specified topic using QoS 0.
|
||||
@@ -589,7 +666,9 @@ class PubSubClient : public Print {
|
||||
* @return true If the publish succeeded.
|
||||
* false If the publish failed, either connection lost or message too large.
|
||||
*/
|
||||
bool publish_P(const char* topic, const uint8_t* payload, size_t plength, bool retained);
|
||||
inline bool publish_P(const char* topic, const uint8_t* payload, size_t plength, bool retained) {
|
||||
return publish_P(topic, payload, plength, MQTT_QOS0, retained);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Publishes a message stored in PROGMEM to the specified topic.
|
||||
@@ -603,6 +682,18 @@ class PubSubClient : public Print {
|
||||
*/
|
||||
bool publish_P(const char* topic, const uint8_t* payload, size_t plength, uint8_t qos, bool retained);
|
||||
|
||||
/**
|
||||
* @brief Publishes a message stored in PROGMEM to the specified topic.
|
||||
* @param topic The topic from __FlashStringHelper to publish to.
|
||||
* @param payload The message from PROGMEM to publish.
|
||||
* @param plength The length of the payload.
|
||||
* @param qos The quality of service (\ref group_qos) to publish at. [0, 1, 2].
|
||||
* @param retained Publish the message with the retain flag.
|
||||
* @return true If the publish succeeded.
|
||||
* false If the publish failed, either connection lost or message too large.
|
||||
*/
|
||||
bool publish_P(const __FlashStringHelper* topic, const uint8_t* payload, size_t plength, uint8_t qos, bool retained);
|
||||
|
||||
/**
|
||||
* @brief Start to publish a message using QoS 0.
|
||||
* This API:
|
||||
@@ -617,7 +708,9 @@ class PubSubClient : public Print {
|
||||
* @return true If the publish succeeded.
|
||||
* false If the publish failed, either connection lost or message too large.
|
||||
*/
|
||||
bool beginPublish(const char* topic, size_t plength, bool retained);
|
||||
inline bool beginPublish(const char* topic, size_t plength, bool retained) {
|
||||
return beginPublishImpl(false, topic, plength, MQTT_QOS0, retained);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start to publish a message.
|
||||
@@ -634,7 +727,48 @@ class PubSubClient : public Print {
|
||||
* @return true If the publish succeeded.
|
||||
* false If the publish failed, either connection lost or message too large.
|
||||
*/
|
||||
bool beginPublish(const char* topic, size_t plength, uint8_t qos, bool retained);
|
||||
inline bool beginPublish(const char* topic, size_t plength, uint8_t qos, bool retained) {
|
||||
return beginPublishImpl(false, topic, plength, qos, retained);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start to publish a message using a topic from __FlashStringHelper F().
|
||||
* This API:
|
||||
* beginPublish(...)
|
||||
* one or more calls to write(...)
|
||||
* endPublish()
|
||||
* Allows for arbitrarily large payloads to be sent without them having to be copied into
|
||||
* a new buffer and held in memory at one time.
|
||||
* @param topic The topic from __FlashStringHelper to publish to.
|
||||
* @param plength The length of the payload.
|
||||
* @param qos The quality of service (\ref group_qos) to publish at. [0, 1, 2].
|
||||
* @param retained Publish the message with the retain flag.
|
||||
* @return true If the publish succeeded.
|
||||
* false If the publish failed, either connection lost or message too large.
|
||||
*/
|
||||
inline bool beginPublish(const __FlashStringHelper* topic, size_t plength, uint8_t qos, bool retained) {
|
||||
// convert FlashStringHelper in PROGMEM-pointer
|
||||
return beginPublishImpl(true, reinterpret_cast<const char*>(topic), plength, qos, retained);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start to publish a message using a topic in PROGMEM.
|
||||
* This API:
|
||||
* beginPublish_P(...)
|
||||
* one or more calls to write(...)
|
||||
* endPublish()
|
||||
* Allows for arbitrarily large payloads to be sent without them having to be copied into
|
||||
* a new buffer and held in memory at one time.
|
||||
* @param topic The topic in PROGMEM to publish to.
|
||||
* @param plength The length of the payload.
|
||||
* @param qos The quality of service (\ref group_qos) to publish at. [0, 1, 2].
|
||||
* @param retained Publish the message with the retain flag.
|
||||
* @return true If the publish succeeded.
|
||||
* false If the publish failed, either connection lost or message too large.
|
||||
*/
|
||||
inline bool beginPublish_P(PGM_P topic, size_t plength, uint8_t qos, bool retained) {
|
||||
return beginPublishImpl(true, reinterpret_cast<const char*>(topic), plength, qos, retained);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Finish sending a message that was started with a call to beginPublish.
|
||||
@@ -645,21 +779,43 @@ class PubSubClient : public Print {
|
||||
|
||||
/**
|
||||
* @brief Writes a single byte as a component of a publish started with a call to beginPublish.
|
||||
* For performance reasons, this will be appended to the internal buffer,
|
||||
* For performance reasons, this will be appended to the internal buffer,
|
||||
* which will be flushed when full or on a call to endPublish().
|
||||
* @param data A byte to write to the publish payload.
|
||||
* @return The number of bytes written.
|
||||
* @return The number of bytes written (0 or 1). If 0 is returned a write error occurred.
|
||||
*/
|
||||
virtual size_t write(uint8_t data);
|
||||
|
||||
/**
|
||||
* @brief Writes an array of bytes as a component of a publish started with a call to beginPublish.
|
||||
* For performance reasons, this will be appended to the internal buffer,
|
||||
* which will be flushed when full or on a call to endPublish(). * @param buffer The bytes to write.
|
||||
* For performance reasons, this will be appended to the internal buffer,
|
||||
* which will be flushed when full or on a call to endPublish().
|
||||
* @param buf The bytes to write.
|
||||
* @param size The length of the payload to be sent.
|
||||
* @return The number of bytes written.
|
||||
* @return The number of bytes written. If return value is != size a write error occurred.
|
||||
*/
|
||||
virtual size_t write(const uint8_t* buffer, size_t size);
|
||||
virtual size_t write(const uint8_t* buf, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Writes a string in PROGMEM as a component of a publish started with a call to beginPublish.
|
||||
* For performance reasons, this will be appended to the internal buffer,
|
||||
* which will be flushed when full or on a call to endPublish().
|
||||
* @param string The message to write.
|
||||
* @return The number of bytes written. If return value is != string length a write error occurred.
|
||||
*/
|
||||
inline size_t write_P(PGM_P string) {
|
||||
return write_P(reinterpret_cast<const uint8_t*>(string), strlen_P(string));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Writes an array of progmem bytes as a component of a publish started with a call to beginPublish.
|
||||
* For performance reasons, this will be appended to the internal buffer,
|
||||
* which will be flushed when full or on a call to endPublish().
|
||||
* @param buf The bytes to write.
|
||||
* @param size The length of the payload to be sent.
|
||||
* @return The number of bytes written. If return value is != size a write error occurred.
|
||||
*/
|
||||
size_t write_P(const uint8_t* buf, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Subscribes to messages published to the specified topic using QoS 0.
|
||||
@@ -667,7 +823,30 @@ class PubSubClient : public Print {
|
||||
* @return true If sending the subscribe succeeded.
|
||||
* false If sending the subscribe failed, either connection lost or message too large.
|
||||
*/
|
||||
bool subscribe(const char* topic);
|
||||
inline bool subscribe(const char* topic) {
|
||||
return subscribeImpl(false, topic, MQTT_QOS0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Subscribes to messages published to the specified topic from __FlashStringHelper using QoS 0.
|
||||
* @param topic The topic from __FlashStringHelper to subscribe to.
|
||||
* @return true If sending the subscribe succeeded.
|
||||
* false If sending the subscribe failed, either connection lost or message too large.
|
||||
*/
|
||||
inline bool subscribe(const __FlashStringHelper* topic) {
|
||||
// convert FlashStringHelper in PROGMEM-pointer
|
||||
return subscribeImpl(true, reinterpret_cast<const char*>(topic), MQTT_QOS0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Subscribes to messages published to the specified topic in PROGMEM using QoS 0.
|
||||
* @param topic The topic in PROGMEM to subscribe to.
|
||||
* @return true If sending the subscribe succeeded.
|
||||
* false If sending the subscribe failed, either connection lost or message too large.
|
||||
*/
|
||||
inline bool subscribe_P(PGM_P topic) {
|
||||
return subscribeImpl(true, reinterpret_cast<const char*>(topic), MQTT_QOS0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Subscribes to messages published to the specified topic.
|
||||
@@ -676,7 +855,32 @@ class PubSubClient : public Print {
|
||||
* @return true If sending the subscribe succeeded.
|
||||
* false If sending the subscribe failed, either connection lost or message too large.
|
||||
*/
|
||||
bool subscribe(const char* topic, uint8_t qos);
|
||||
inline bool subscribe(const char* topic, uint8_t qos) {
|
||||
return subscribeImpl(false, topic, qos);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Subscribes to messages published to the specified topic from __FlashStringHelper.
|
||||
* @param topic The topic from __FlashStringHelper to subscribe to.
|
||||
* @param qos The qos to subscribe at. [0, 1].
|
||||
* @return true If sending the subscribe succeeded.
|
||||
* false If sending the subscribe failed, either connection lost or message too large.
|
||||
*/
|
||||
inline bool subscribe(const __FlashStringHelper* topic, uint8_t qos) {
|
||||
// convert FlashStringHelper in PROGMEM-pointer
|
||||
return subscribeImpl(true, reinterpret_cast<const char*>(topic), qos);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Subscribes to messages published to the specified topic in PROGMEM.
|
||||
* @param topic The topic in PROGMEM to subscribe to.
|
||||
* @param qos The qos to subscribe at. [0, 1].
|
||||
* @return true If sending the subscribe succeeded.
|
||||
* false If sending the subscribe failed, either connection lost or message too large.
|
||||
*/
|
||||
inline bool subscribe_P(PGM_P topic, uint8_t qos) {
|
||||
return subscribeImpl(true, reinterpret_cast<const char*>(topic), qos);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unsubscribes from the specified topic.
|
||||
@@ -684,7 +888,30 @@ class PubSubClient : public Print {
|
||||
* @return true If sending the unsubscribe succeeded.
|
||||
* false If sending the unsubscribe failed, either connection lost or message too large.
|
||||
*/
|
||||
bool unsubscribe(const char* topic);
|
||||
inline bool unsubscribe(const char* topic) {
|
||||
return unsubscribeImpl(false, topic);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unsubscribes from the specified topic from __FlashStringHelper.
|
||||
* @param topic The topic from __FlashStringHelper to unsubscribe from.
|
||||
* @return true If sending the unsubscribe succeeded.
|
||||
* false If sending the unsubscribe failed, either connection lost or message too large.
|
||||
*/
|
||||
inline bool unsubscribe(const __FlashStringHelper* topic) {
|
||||
// convert FlashStringHelper in PROGMEM-pointer
|
||||
return unsubscribeImpl(true, reinterpret_cast<const char*>(topic));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unsubscribes from the specified topic in PROGMEM.
|
||||
* @param topic The topic in PROGMEM to unsubscribe from.
|
||||
* @return true If sending the unsubscribe succeeded.
|
||||
* false If sending the unsubscribe failed, either connection lost or message too large.
|
||||
*/
|
||||
inline bool unsubscribe_P(PGM_P topic) {
|
||||
return unsubscribeImpl(true, reinterpret_cast<const char*>(topic));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This should be called regularly to allow the client to process incoming messages and maintain its connection to the server.
|
||||
|
||||
@@ -20,9 +20,14 @@ extern void loop(void);
|
||||
unsigned long millis(void);
|
||||
}
|
||||
|
||||
class __FlashStringHelper;
|
||||
#define PROGMEM
|
||||
#define PGM_P const char*
|
||||
#define memcpy_P memcpy
|
||||
#define strlen_P strlen
|
||||
#define strnlen_P strnlen
|
||||
#define pgm_read_byte_near(x) *(x)
|
||||
#define F(x) (reinterpret_cast<const __FlashStringHelper*>(x))
|
||||
|
||||
#define yield(x) {}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ int test_publish_bytes();
|
||||
int test_publish_retained();
|
||||
int test_publish_retained_2();
|
||||
int test_publish_not_connected();
|
||||
int test_publish_long();
|
||||
int test_publish_too_long();
|
||||
int test_publish_P();
|
||||
int test_publish_P_too_long();
|
||||
@@ -22,6 +23,10 @@ int test_publish_qos1();
|
||||
int test_publish_qos2();
|
||||
int test_publish_P_qos1();
|
||||
int test_publish_P_qos2();
|
||||
int test_publish_FlashStringHelper();
|
||||
int test_publish_FlashStringHelper2();
|
||||
int test_publish_P_FlashStringHelper();
|
||||
int test_publish_P_P();
|
||||
|
||||
void callback(_UNUSED_ char* topic, _UNUSED_ uint8_t* payload, _UNUSED_ size_t plength) {
|
||||
// handle message arrived
|
||||
@@ -139,6 +144,49 @@ int test_publish_not_connected() {
|
||||
END_IT
|
||||
}
|
||||
|
||||
int test_publish_long() {
|
||||
IT("publishes with long payload message (> buffer size)");
|
||||
ShimClient shimClient;
|
||||
shimClient.setAllowConnect(true);
|
||||
|
||||
// buffer size 64 bytes - 5 bytes header - 2 bytes topic length = max. 57 bytes topic
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2
|
||||
char topic[] = "123456789012345678901234567890123456789012345678901234567";
|
||||
|
||||
// 0 1 2 3 4 5 6 7 8 9 0 1 2
|
||||
char payload[] = "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
|
||||
size_t plength = strlen(payload);
|
||||
|
||||
byte connack[] = {0x20, 0x02, 0x00, 0x00};
|
||||
shimClient.respond(connack, 4);
|
||||
|
||||
PubSubClient client(server, 1883, callback, shimClient);
|
||||
client.setBufferSize(64);
|
||||
bool rc = client.connect("client_test1");
|
||||
IS_TRUE(rc);
|
||||
|
||||
byte publish[256];
|
||||
publish[0] = 0x30; // PUBLISH, QoS 0, no retain
|
||||
publish[1] = 0xb3; // Remaining length byte 1: 2 + 57 + 120 bytes (topic length bytes + topic length + payload length = 179)
|
||||
publish[2] = 0x01; // Remaining length byte 2
|
||||
publish[3] = 0x00; // Topic length MSB
|
||||
publish[4] = 0x39; // Topic length LSB (57 bytes)
|
||||
memcpy(&publish[5], topic, sizeof(topic) - 1);
|
||||
memcpy(&publish[5 + sizeof(topic) - 1], payload, sizeof(payload) - 1);
|
||||
shimClient.expect(publish, 5 + sizeof(topic) - 1 + sizeof(payload) - 1);
|
||||
|
||||
rc = client.beginPublish(topic, plength, 0, false);
|
||||
IS_TRUE(rc);
|
||||
plength = client.write((uint8_t*)payload, plength);
|
||||
IS_EQUAL(plength, strlen(payload));
|
||||
rc = client.endPublish();
|
||||
IS_TRUE(rc);
|
||||
|
||||
IS_FALSE(shimClient.error());
|
||||
|
||||
END_IT
|
||||
}
|
||||
|
||||
int test_publish_too_long() {
|
||||
IT("publish fails when topic/payload are too long");
|
||||
ShimClient shimClient;
|
||||
@@ -167,7 +215,7 @@ int test_publish_too_long() {
|
||||
}
|
||||
|
||||
int test_publish_P() {
|
||||
IT("publishes using PROGMEM");
|
||||
IT("publishes using PROGMEM payload");
|
||||
ShimClient shimClient;
|
||||
shimClient.setAllowConnect(true);
|
||||
|
||||
@@ -193,7 +241,7 @@ int test_publish_P() {
|
||||
}
|
||||
|
||||
int test_publish_P_too_long() {
|
||||
IT("publish using PROGMEM fails when topic is too long");
|
||||
IT("publish using PROGMEM payload fails when topic is too long");
|
||||
ShimClient shimClient;
|
||||
shimClient.setAllowConnect(true);
|
||||
|
||||
@@ -219,6 +267,112 @@ int test_publish_P_too_long() {
|
||||
END_IT
|
||||
}
|
||||
|
||||
int test_publish_FlashStringHelper() {
|
||||
IT("publishes using FlashStringHelper topic");
|
||||
ShimClient shimClient;
|
||||
shimClient.setAllowConnect(true);
|
||||
|
||||
char payload[] = "12345";
|
||||
|
||||
byte connack[] = {0x20, 0x02, 0x00, 0x00};
|
||||
shimClient.respond(connack, sizeof(connack));
|
||||
|
||||
PubSubClient client(server, 1883, callback, shimClient);
|
||||
bool rc = client.connect("client_test1");
|
||||
IS_TRUE(rc);
|
||||
|
||||
byte publish[] = {0x31, 0x0c, 0x00, 0x05, 't', 'o', 'p', 'i', 'c', '1', '2', '3', '4', '5'};
|
||||
shimClient.expect(publish, sizeof(publish));
|
||||
|
||||
rc = client.publish(F("topic"), payload, MQTT_QOS0, true);
|
||||
IS_TRUE(rc);
|
||||
|
||||
IS_FALSE(shimClient.error());
|
||||
|
||||
END_IT
|
||||
}
|
||||
|
||||
int test_publish_FlashStringHelper2() {
|
||||
IT("publishes using FlashStringHelper topic and payload");
|
||||
ShimClient shimClient;
|
||||
shimClient.setAllowConnect(true);
|
||||
|
||||
char payload[] = "12345";
|
||||
|
||||
byte connack[] = {0x20, 0x02, 0x00, 0x00};
|
||||
shimClient.respond(connack, sizeof(connack));
|
||||
|
||||
PubSubClient client(server, 1883, callback, shimClient);
|
||||
bool rc = client.connect("client_test1");
|
||||
IS_TRUE(rc);
|
||||
|
||||
byte publish[] = {0x31, 0x0c, 0x00, 0x05, 't', 'o', 'p', 'i', 'c', '1', '2', '3', '4', '5'};
|
||||
shimClient.expect(publish, sizeof(publish));
|
||||
|
||||
rc = client.publish(F("topic"), F(payload), MQTT_QOS0, true);
|
||||
IS_TRUE(rc);
|
||||
|
||||
IS_FALSE(shimClient.error());
|
||||
|
||||
END_IT
|
||||
}
|
||||
|
||||
int test_publish_P_FlashStringHelper() {
|
||||
IT("publishes using FlashStringHelper topic and PROGMEM payload");
|
||||
ShimClient shimClient;
|
||||
shimClient.setAllowConnect(true);
|
||||
|
||||
char payload[] PROGMEM = "12345";
|
||||
|
||||
byte connack[] = {0x20, 0x02, 0x00, 0x00};
|
||||
shimClient.respond(connack, sizeof(connack));
|
||||
|
||||
PubSubClient client(server, 1883, callback, shimClient);
|
||||
bool rc = client.connect("client_test1");
|
||||
IS_TRUE(rc);
|
||||
|
||||
byte publish[] = {0x31, 0x0c, 0x00, 0x05, 't', 'o', 'p', 'i', 'c', '1', '2', '3', '4', '5'};
|
||||
shimClient.expect(publish, sizeof(publish));
|
||||
|
||||
rc = client.publish_P(F("topic"), payload, MQTT_QOS0, true);
|
||||
IS_TRUE(rc);
|
||||
|
||||
IS_FALSE(shimClient.error());
|
||||
|
||||
END_IT
|
||||
}
|
||||
|
||||
int test_publish_P_P() {
|
||||
IT("publishes using PROGMEM topic and PROGMEM payload");
|
||||
ShimClient shimClient;
|
||||
shimClient.setAllowConnect(true);
|
||||
|
||||
char topic[] PROGMEM = "topic";
|
||||
char payload[] PROGMEM = "12345";
|
||||
size_t length = strlen_P(payload);
|
||||
|
||||
byte connack[] = {0x20, 0x02, 0x00, 0x00};
|
||||
shimClient.respond(connack, sizeof(connack));
|
||||
|
||||
PubSubClient client(server, 1883, callback, shimClient);
|
||||
bool rc = client.connect("client_test1");
|
||||
IS_TRUE(rc);
|
||||
|
||||
byte publish[] = {0x31, 0x0c, 0x00, 0x05, 't', 'o', 'p', 'i', 'c', '1', '2', '3', '4', '5'};
|
||||
shimClient.expect(publish, sizeof(publish));
|
||||
|
||||
rc = client.beginPublish_P(topic, length, MQTT_QOS0, true);
|
||||
IS_TRUE(rc);
|
||||
length = client.write_P(payload);
|
||||
IS_EQUAL(length, strlen_P(payload));
|
||||
rc = client.endPublish();
|
||||
IS_TRUE(rc);
|
||||
|
||||
IS_FALSE(shimClient.error());
|
||||
|
||||
END_IT
|
||||
}
|
||||
|
||||
int test_publish_empty_topic() {
|
||||
IT("publish fails when topic is empty");
|
||||
ShimClient shimClient;
|
||||
@@ -275,7 +429,7 @@ int test_publish_qos1() {
|
||||
IS_TRUE(rc);
|
||||
|
||||
// Example publish packet for QoS 1 (0x32)
|
||||
byte publish[] = {0x32, 0x10, 0x00, 0x05, 't', 'o', 'p', 'i', 'c', 'p', 'a', 'y', 'l', 'o', 'a', 'd', 0x00, 0x02};
|
||||
byte publish[] = {0x32, 0x10, 0x00, 0x05, 't', 'o', 'p', 'i', 'c', 0x00, 0x02, 'p', 'a', 'y', 'l', 'o', 'a', 'd'};
|
||||
shimClient.expect(publish, sizeof(publish));
|
||||
|
||||
rc = client.publish("topic", "payload", MQTT_QOS1, false);
|
||||
@@ -299,7 +453,7 @@ int test_publish_qos2() {
|
||||
IS_TRUE(rc);
|
||||
|
||||
// Example publish packet for QoS 2 (0x34)
|
||||
byte publish[] = {0x34, 0x10, 0x00, 0x05, 't', 'o', 'p', 'i', 'c', 'p', 'a', 'y', 'l', 'o', 'a', 'd', 0x00, 0x02};
|
||||
byte publish[] = {0x34, 0x10, 0x00, 0x05, 't', 'o', 'p', 'i', 'c', 0x00, 0x02, 'p', 'a', 'y', 'l', 'o', 'a', 'd'};
|
||||
shimClient.expect(publish, sizeof(publish));
|
||||
|
||||
rc = client.publish("topic", "payload", MQTT_QOS2, false);
|
||||
@@ -311,7 +465,7 @@ int test_publish_qos2() {
|
||||
}
|
||||
|
||||
int test_publish_P_qos1() {
|
||||
IT("publishes using PROGMEM with QoS 1 retained");
|
||||
IT("publishes using PROGMEM payload with QoS 1 retained");
|
||||
ShimClient shimClient;
|
||||
shimClient.setAllowConnect(true);
|
||||
|
||||
@@ -325,7 +479,7 @@ int test_publish_P_qos1() {
|
||||
bool rc = client.connect("client_test1");
|
||||
IS_TRUE(rc);
|
||||
|
||||
byte publish[] = {0x33, 0x0e, 0x00, 0x05, 't', 'o', 'p', 'i', 'c', 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x02};
|
||||
byte publish[] = {0x33, 0x0e, 0x00, 0x05, 't', 'o', 'p', 'i', 'c', 0x00, 0x02, 0x01, 0x02, 0x03, 0x04, 0x05};
|
||||
shimClient.expect(publish, sizeof(publish));
|
||||
|
||||
rc = client.publish_P("topic", payload, length, MQTT_QOS1, true);
|
||||
@@ -337,7 +491,7 @@ int test_publish_P_qos1() {
|
||||
}
|
||||
|
||||
int test_publish_P_qos2() {
|
||||
IT("publishes using PROGMEM with QoS 2 retained");
|
||||
IT("publishes using PROGMEM payload with QoS 2 retained");
|
||||
ShimClient shimClient;
|
||||
shimClient.setAllowConnect(true);
|
||||
|
||||
@@ -351,7 +505,7 @@ int test_publish_P_qos2() {
|
||||
bool rc = client.connect("client_test1");
|
||||
IS_TRUE(rc);
|
||||
|
||||
byte publish[] = {0x35, 0x0e, 0x00, 0x05, 't', 'o', 'p', 'i', 'c', 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x02};
|
||||
byte publish[] = {0x35, 0x0e, 0x00, 0x05, 't', 'o', 'p', 'i', 'c', 0x00, 0x02, 0x01, 0x02, 0x03, 0x04, 0x05};
|
||||
shimClient.expect(publish, sizeof(publish));
|
||||
|
||||
rc = client.publish_P("topic", payload, length, MQTT_QOS2, true);
|
||||
@@ -371,6 +525,7 @@ int main() {
|
||||
test_publish_qos1();
|
||||
test_publish_qos2();
|
||||
test_publish_null_payload();
|
||||
test_publish_long();
|
||||
test_publish_not_connected();
|
||||
test_publish_empty_topic();
|
||||
test_publish_too_long();
|
||||
@@ -378,6 +533,10 @@ int main() {
|
||||
test_publish_P_qos1();
|
||||
test_publish_P_qos2();
|
||||
test_publish_P_too_long();
|
||||
test_publish_FlashStringHelper();
|
||||
test_publish_FlashStringHelper2();
|
||||
test_publish_P_FlashStringHelper();
|
||||
test_publish_P_P();
|
||||
|
||||
FINISH
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ int test_receive_oversized_message();
|
||||
int test_resize_buffer();
|
||||
int test_receive_oversized_stream_message();
|
||||
int test_receive_qos1();
|
||||
int test_receive_qos2();
|
||||
|
||||
void reset_callback() {
|
||||
callback_called = false;
|
||||
@@ -330,6 +331,57 @@ int test_receive_qos1() {
|
||||
END_IT
|
||||
}
|
||||
|
||||
int test_receive_qos2() {
|
||||
IT("receives a qos2 message - responds PUBREC then PUBCOMP");
|
||||
reset_callback();
|
||||
|
||||
ShimClient shimClient;
|
||||
shimClient.setAllowConnect(true);
|
||||
|
||||
byte connack[] = {0x20, 0x02, 0x00, 0x00};
|
||||
shimClient.respond(connack, 4);
|
||||
|
||||
PubSubClient client(server, 1883, callback, shimClient);
|
||||
bool rc = client.connect("client_test1");
|
||||
IS_TRUE(rc);
|
||||
|
||||
// QoS 2 PUBLISH from broker (0x34 = MQTTPUBLISH | QoS2 bits)
|
||||
// Fixed header 0x34, remaining length 0x10 (16), topic len 0x0005, topic "topic",
|
||||
// msgId 0x1234, payload "payload"
|
||||
byte publish[] = {0x34, 0x10, 0x0, 0x5, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x34, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64};
|
||||
shimClient.respond(publish, 18);
|
||||
|
||||
// Client must respond with PUBREC (0x50), remaining length 2, msgId 0x1234
|
||||
byte pubrec[] = {0x50, 0x02, 0x12, 0x34};
|
||||
shimClient.expect(pubrec, 4);
|
||||
|
||||
rc = client.loop();
|
||||
IS_TRUE(rc);
|
||||
IS_TRUE(callback_called);
|
||||
IS_TRUE(strcmp(lastTopic, "topic") == 0);
|
||||
IS_TRUE(memcmp(lastPayload, "payload", 7) == 0);
|
||||
IS_TRUE(lastLength == 7);
|
||||
IS_FALSE(shimClient.error());
|
||||
|
||||
reset_callback();
|
||||
|
||||
// Broker sends PUBREL (0x62 = MQTTPUBREL | bit1), remaining length 2, msgId 0x1234
|
||||
byte pubrel[] = {0x62, 0x02, 0x12, 0x34};
|
||||
shimClient.respond(pubrel, 4);
|
||||
|
||||
// Client must respond with PUBCOMP (0x70), remaining length 2, msgId 0x1234
|
||||
byte pubcomp[] = {0x70, 0x02, 0x12, 0x34};
|
||||
shimClient.expect(pubcomp, 4);
|
||||
|
||||
rc = client.loop();
|
||||
IS_TRUE(rc);
|
||||
IS_FALSE(callback_called); // callback must NOT fire again on PUBREL
|
||||
|
||||
IS_FALSE(shimClient.error());
|
||||
|
||||
END_IT
|
||||
}
|
||||
|
||||
int main() {
|
||||
SUITE("Receive");
|
||||
test_receive_callback();
|
||||
@@ -340,6 +392,7 @@ int main() {
|
||||
test_resize_buffer();
|
||||
test_receive_oversized_stream_message();
|
||||
test_receive_qos1();
|
||||
test_receive_qos2();
|
||||
|
||||
FINISH
|
||||
}
|
||||
|
||||
@@ -10,6 +10,10 @@ byte server[] = {172, 16, 0, 2};
|
||||
void callback(char* topic, uint8_t* payload, size_t plength);
|
||||
int test_subscribe_no_qos();
|
||||
int test_subscribe_qos_1();
|
||||
int test_subscribe_P();
|
||||
int test_subscribe_P_qos_1();
|
||||
int test_subscribe_FlashStringHelper();
|
||||
int test_subscribe_FlashStringHelper_qos_1();
|
||||
int test_subscribe_not_connected();
|
||||
int test_subscribe_invalid_qos();
|
||||
int test_subscribe_too_long();
|
||||
@@ -70,6 +74,108 @@ int test_subscribe_qos_1() {
|
||||
END_IT
|
||||
}
|
||||
|
||||
int test_subscribe_P() {
|
||||
IT("subscribe using PROGMEM");
|
||||
ShimClient shimClient;
|
||||
shimClient.setAllowConnect(true);
|
||||
|
||||
byte connack[] = {0x20, 0x02, 0x00, 0x00};
|
||||
shimClient.respond(connack, 4);
|
||||
|
||||
PubSubClient client(server, 1883, callback, shimClient);
|
||||
bool rc = client.connect("client_test1");
|
||||
IS_TRUE(rc);
|
||||
|
||||
byte subscribe[] = {0x82, 0xa, 0x0, 0x2, 0x0, 0x5, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x0};
|
||||
shimClient.expect(subscribe, 12);
|
||||
byte suback[] = {0x90, 0x3, 0x0, 0x2, 0x0};
|
||||
shimClient.respond(suback, 5);
|
||||
|
||||
char topic[] PROGMEM = "topic";
|
||||
rc = client.subscribe_P(topic);
|
||||
IS_TRUE(rc);
|
||||
|
||||
IS_FALSE(shimClient.error());
|
||||
|
||||
END_IT
|
||||
}
|
||||
|
||||
int test_subscribe_P_qos_1() {
|
||||
IT("subscribe using PROGMEM with QoS 1");
|
||||
ShimClient shimClient;
|
||||
shimClient.setAllowConnect(true);
|
||||
|
||||
byte connack[] = {0x20, 0x02, 0x00, 0x00};
|
||||
shimClient.respond(connack, 4);
|
||||
|
||||
PubSubClient client(server, 1883, callback, shimClient);
|
||||
bool rc = client.connect("client_test1");
|
||||
IS_TRUE(rc);
|
||||
|
||||
byte subscribe[] = {0x82, 0xa, 0x0, 0x2, 0x0, 0x5, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x1};
|
||||
shimClient.expect(subscribe, 12);
|
||||
byte suback[] = {0x90, 0x3, 0x0, 0x2, 0x1};
|
||||
shimClient.respond(suback, 5);
|
||||
|
||||
char topic[] PROGMEM = "topic";
|
||||
rc = client.subscribe_P(topic, MQTT_QOS1);
|
||||
IS_TRUE(rc);
|
||||
|
||||
IS_FALSE(shimClient.error());
|
||||
|
||||
END_IT
|
||||
}
|
||||
|
||||
int test_subscribe_FlashStringHelper() {
|
||||
IT("subscribe using FlashStringHelper");
|
||||
ShimClient shimClient;
|
||||
shimClient.setAllowConnect(true);
|
||||
|
||||
byte connack[] = {0x20, 0x02, 0x00, 0x00};
|
||||
shimClient.respond(connack, 4);
|
||||
|
||||
PubSubClient client(server, 1883, callback, shimClient);
|
||||
bool rc = client.connect("client_test1");
|
||||
IS_TRUE(rc);
|
||||
|
||||
byte subscribe[] = {0x82, 0xa, 0x0, 0x2, 0x0, 0x5, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x0};
|
||||
shimClient.expect(subscribe, 12);
|
||||
byte suback[] = {0x90, 0x3, 0x0, 0x2, 0x0};
|
||||
shimClient.respond(suback, 5);
|
||||
|
||||
rc = client.subscribe(F("topic"));
|
||||
IS_TRUE(rc);
|
||||
|
||||
IS_FALSE(shimClient.error());
|
||||
|
||||
END_IT
|
||||
}
|
||||
|
||||
int test_subscribe_FlashStringHelper_qos_1() {
|
||||
IT("subscribe using FlashStringHelper with QoS 1");
|
||||
ShimClient shimClient;
|
||||
shimClient.setAllowConnect(true);
|
||||
|
||||
byte connack[] = {0x20, 0x02, 0x00, 0x00};
|
||||
shimClient.respond(connack, 4);
|
||||
|
||||
PubSubClient client(server, 1883, callback, shimClient);
|
||||
bool rc = client.connect("client_test1");
|
||||
IS_TRUE(rc);
|
||||
|
||||
byte subscribe[] = {0x82, 0xa, 0x0, 0x2, 0x0, 0x5, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x1};
|
||||
shimClient.expect(subscribe, 12);
|
||||
byte suback[] = {0x90, 0x3, 0x0, 0x2, 0x1};
|
||||
shimClient.respond(suback, 5);
|
||||
|
||||
rc = client.subscribe(F("topic"), MQTT_QOS1);
|
||||
IS_TRUE(rc);
|
||||
|
||||
IS_FALSE(shimClient.error());
|
||||
|
||||
END_IT
|
||||
}
|
||||
|
||||
int test_subscribe_not_connected() {
|
||||
IT("subscribe fails when not connected");
|
||||
ShimClient shimClient;
|
||||
@@ -176,6 +282,10 @@ int main() {
|
||||
SUITE("Subscribe");
|
||||
test_subscribe_no_qos();
|
||||
test_subscribe_qos_1();
|
||||
test_subscribe_P();
|
||||
test_subscribe_P_qos_1();
|
||||
test_subscribe_FlashStringHelper();
|
||||
test_subscribe_FlashStringHelper_qos_1();
|
||||
test_subscribe_not_connected();
|
||||
test_subscribe_invalid_qos();
|
||||
test_subscribe_too_long();
|
||||
|
||||
@@ -190,8 +190,8 @@ extra_scripts = ${esp82xx_common.extra_scripts}
|
||||
;platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc152
|
||||
;platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/2904-2115-5.5/framework-arduinoespressif32-release_v5.5-f2a3fa2b.tar.xz
|
||||
|
||||
platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.04.50/platform-espressif32.zip
|
||||
platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/0405-1702-5.5/framework-arduinoespressif32-release_v5.5-f2a3fa2b.tar.xz
|
||||
platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc152
|
||||
platform_packages = framework-arduinoespressif32 @ https://github.com/Jason2866/esp32-arduino-lib-builder/releases/download/1205-1404-5.5/framework-arduinoespressif32-release_v5.5-65012b38.tar.xz
|
||||
|
||||
custom_remove_include = true
|
||||
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
#include "../DataStructs/NWPluginData_base.h"
|
||||
|
||||
#include "../../../src/DataStructs/ESPEasy_EventStruct.h"
|
||||
#include "../../../src/Globals/Settings.h"
|
||||
#include "../../../src/Helpers/StringConverter.h"
|
||||
#include "../../../src/Helpers/Misc.h"
|
||||
#include "../../../src/Helpers/Networking.h"
|
||||
#if FEATURE_STORE_NETWORK_INTERFACE_SETTINGS
|
||||
# include "../../../src/Helpers/_ESPEasy_key_value_store.h"
|
||||
#include "../_NWPlugin_Helper.h"
|
||||
#endif
|
||||
# include "../_NWPlugin_Helper.h"
|
||||
#endif // if FEATURE_STORE_NETWORK_INTERFACE_SETTINGS
|
||||
#ifdef ESP32
|
||||
# include <esp_netif.h>
|
||||
# include <esp_netif_types.h>
|
||||
@@ -46,8 +47,11 @@ NWPluginData_base::NWPluginData_base(
|
||||
NWPluginData_base::~NWPluginData_base()
|
||||
{
|
||||
#if FEATURE_NETWORK_STATS
|
||||
delete _plugin_stats_array;
|
||||
_plugin_stats_array = nullptr;
|
||||
|
||||
if (_plugin_stats_array) {
|
||||
delete _plugin_stats_array;
|
||||
_plugin_stats_array = nullptr;
|
||||
}
|
||||
#endif // if FEATURE_NETWORK_STATS
|
||||
|
||||
#if FEATURE_STORE_NETWORK_INTERFACE_SETTINGS
|
||||
@@ -58,6 +62,7 @@ NWPluginData_base::~NWPluginData_base()
|
||||
}
|
||||
|
||||
#ifdef ESP32
|
||||
|
||||
bool NWPluginData_base::isDefaultRoute() const {
|
||||
if (_netif) {
|
||||
return _netif->isDefault();
|
||||
@@ -65,14 +70,14 @@ bool NWPluginData_base::isDefaultRoute() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // ifdef ESP32
|
||||
|
||||
bool NWPluginData_base::getStaticIPAddresses(IPAddress & ip, IPAddress & gateway, IPAddress & subnetmask, IPAddress & dns ) const
|
||||
bool NWPluginData_base::getStaticIPAddresses(IPAddress& ip, IPAddress& gateway, IPAddress& subnetmask, IPAddress& dns) const
|
||||
{
|
||||
getStaticIPAddress(IPAddressType::IP, ip);
|
||||
getStaticIPAddress(IPAddressType::Gateway, gateway);
|
||||
getStaticIPAddress(IPAddressType::IP, ip);
|
||||
getStaticIPAddress(IPAddressType::Gateway, gateway);
|
||||
getStaticIPAddress(IPAddressType::Subnetmask, subnetmask);
|
||||
getStaticIPAddress(IPAddressType::DNS, dns);
|
||||
getStaticIPAddress(IPAddressType::DNS, dns);
|
||||
|
||||
return IPAddressSet(ip) && IPAddressSet(gateway) && IPAddressSet(subnetmask);
|
||||
}
|
||||
@@ -116,31 +121,35 @@ void NWPluginData_base::initPluginStats(
|
||||
float errorValue,
|
||||
const PluginStats_Config_t& displayConfig)
|
||||
{
|
||||
if (networkStatsVarIndex < INVALID_NETWORK_STATS_VAR_INDEX) {
|
||||
if (_plugin_stats_array == nullptr) {
|
||||
constexpr unsigned size = sizeof(PluginStats_array);
|
||||
void *ptr = special_calloc(1, size);
|
||||
if (!Settings.getNetworkCollectStats(_networkIndex) ||
|
||||
(networkStatsVarIndex >= INVALID_NETWORK_STATS_VAR_INDEX)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ptr != nullptr) {
|
||||
_plugin_stats_array = new (ptr) PluginStats_array();
|
||||
}
|
||||
}
|
||||
if (_plugin_stats_array == nullptr) {
|
||||
constexpr unsigned size = sizeof(PluginStats_array);
|
||||
void *ptr = special_calloc(1, size);
|
||||
|
||||
if (_plugin_stats_array != nullptr) {
|
||||
_plugin_stats_array->initPluginStats(
|
||||
networkStatsVarIndex,
|
||||
label,
|
||||
nrDecimals,
|
||||
errorValue,
|
||||
displayConfig);
|
||||
if (ptr != nullptr) {
|
||||
_plugin_stats_array = new (ptr) PluginStats_array();
|
||||
}
|
||||
}
|
||||
|
||||
if (_plugin_stats_array != nullptr) {
|
||||
_plugin_stats_array->initPluginStats(
|
||||
networkStatsVarIndex,
|
||||
label,
|
||||
nrDecimals,
|
||||
errorValue,
|
||||
displayConfig);
|
||||
}
|
||||
}
|
||||
|
||||
# if FEATURE_NETWORK_TRAFFIC_COUNT
|
||||
|
||||
void NWPluginData_base::initPluginStats_trafficCount(networkStatsVarIndex_t networkStatsVarIndex, bool isTX)
|
||||
{
|
||||
if (!Settings.getNetworkCollectStats(_networkIndex)) { return; }
|
||||
PluginStats_Config_t displayConfig;
|
||||
|
||||
displayConfig.setAxisPosition(PluginStats_Config_t::AxisPosition::Right);
|
||||
@@ -160,13 +169,14 @@ bool NWPluginData_base::initPluginStats()
|
||||
{
|
||||
# if FEATURE_NETWORK_TRAFFIC_COUNT
|
||||
|
||||
// Virtual function has no override in derived class, so only init traffic count
|
||||
initPluginStats_trafficCount(0, true); // TX
|
||||
initPluginStats_trafficCount(1, false); // RX
|
||||
return true;
|
||||
# else // if FEATURE_NETWORK_TRAFFIC_COUNT
|
||||
return false;
|
||||
if (Settings.getNetworkCollectStats(_networkIndex)) {
|
||||
// Virtual function has no override in derived class, so only init traffic count
|
||||
initPluginStats_trafficCount(0, true); // TX
|
||||
initPluginStats_trafficCount(1, false); // RX
|
||||
return true;
|
||||
}
|
||||
# endif // if FEATURE_NETWORK_TRAFFIC_COUNT
|
||||
return false;
|
||||
}
|
||||
|
||||
void NWPluginData_base::clearPluginStats(networkStatsVarIndex_t networkStatsVarIndex)
|
||||
@@ -334,9 +344,9 @@ bool NWPluginData_base::handle_priority_route_changed()
|
||||
if ((_netif != nullptr) && _netif->isDefault()) {
|
||||
auto cache = getNWPluginData_static_runtime();
|
||||
|
||||
if (!cache) {
|
||||
if (NWPlugin::forceDHCP_request(_netif)) {
|
||||
return true;
|
||||
if (!cache) {
|
||||
if (NWPlugin::forceDHCP_request(_netif)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,12 +414,13 @@ PluginStats * NWPluginData_base::getPluginStats(networkStatsVarIndex_t networkSt
|
||||
#endif // if FEATURE_NETWORK_STATS
|
||||
|
||||
#ifdef ESP32
|
||||
/*
|
||||
bool NWPluginData_base::_restore_DNS_cache()
|
||||
{
|
||||
bool res{};
|
||||
|
||||
if ((_netif != nullptr) && _netif->isDefault()) {
|
||||
/*
|
||||
bool NWPluginData_base::_restore_DNS_cache()
|
||||
{
|
||||
bool res{};
|
||||
|
||||
if ((_netif != nullptr) && _netif->isDefault()) {
|
||||
if (NWPlugin::forceDHCP_request(_netif)) { return true; }
|
||||
|
||||
auto cache = getNWPluginData_static_runtime();
|
||||
@@ -433,24 +444,18 @@ bool NWPluginData_base::_restore_DNS_cache()
|
||||
res = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
*/
|
||||
}
|
||||
return res;
|
||||
}
|
||||
*/
|
||||
|
||||
#endif // ifdef ESP32
|
||||
|
||||
#if FEATURE_STORE_NETWORK_INTERFACE_SETTINGS
|
||||
|
||||
bool NWPluginData_base::_load()
|
||||
{
|
||||
return load_nwpluginTaskData_KVS(_kvs, _networkIndex, _nw_data_pluginID);
|
||||
}
|
||||
bool NWPluginData_base::_load() { return load_nwpluginTaskData_KVS(_kvs, _networkIndex, _nw_data_pluginID); }
|
||||
|
||||
bool NWPluginData_base::_store()
|
||||
{
|
||||
return store_nwpluginTaskData_KVS(_kvs, _networkIndex, _nw_data_pluginID);
|
||||
}
|
||||
bool NWPluginData_base::_store() { return store_nwpluginTaskData_KVS(_kvs, _networkIndex, _nw_data_pluginID); }
|
||||
|
||||
#endif // if FEATURE_STORE_NETWORK_INTERFACE_SETTINGS
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "../../../src/Globals/Settings.h"
|
||||
#include "../../../src/Globals/ESPEasy_Scheduler.h"
|
||||
//#include "../../../src/Helpers/Misc.h"
|
||||
#include "../../../src/Helpers/Networking.h"
|
||||
#include "../../../src/Helpers/StringConverter.h"
|
||||
#include "../Globals/NWPlugins.h"
|
||||
|
||||
@@ -2137,6 +2138,9 @@ bool do_NWPluginCall(networkDriverIndex_t networkDriverIndex, NWPlugin::
|
||||
// addLog(LOG_LEVEL_ERROR, strformat(F("Network %d was not (yet) initialized"), event->NetworkIndex + 1));
|
||||
return false;
|
||||
}
|
||||
#if FEATURE_ESPEASY_P2P
|
||||
stopUDPport();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -99,13 +99,14 @@ bool NW001_data_struct_WiFi_STA::init(EventStruct *event)
|
||||
|
||||
{
|
||||
auto runtime_data = getNWPluginData_static_runtime();
|
||||
|
||||
if (runtime_data) {
|
||||
IPAddress ip, gateway, sn, dns;
|
||||
getStaticIPAddresses(ip, gateway, sn, dns);
|
||||
runtime_data->setStaticIP(ip, gateway, sn, dns);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
ESPEasy::net::wifi::initWiFi();
|
||||
return true;
|
||||
@@ -171,6 +172,7 @@ bool NW001_data_struct_WiFi_STA::handle_priority_route_changed()
|
||||
|
||||
bool NW001_data_struct_WiFi_STA::initPluginStats()
|
||||
{
|
||||
if (!Settings.getNetworkCollectStats(_networkIndex)) { return false; }
|
||||
networkStatsVarIndex_t networkStatsVarIndex{};
|
||||
PluginStats_Config_t displayConfig;
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ bool NW002_data_struct_WiFi_AP::init(EventStruct *event)
|
||||
{
|
||||
{
|
||||
auto runtime_data = getNWPluginData_static_runtime();
|
||||
|
||||
if (runtime_data) {
|
||||
IPAddress ip, gateway, sn, dns;
|
||||
getStaticIPAddresses(ip, gateway, sn, dns);
|
||||
@@ -146,26 +147,27 @@ NWPluginData_static_runtime * NW002_data_struct_WiFi_AP::getNWPluginData_static_
|
||||
bool NW002_data_struct_WiFi_AP::getStaticIPAddress(IPAddressType addressType, IPAddress& ip) const
|
||||
{
|
||||
// TODO TD-er: Implement for AP
|
||||
/*
|
||||
IPAddress res;
|
||||
|
||||
switch (addressType)
|
||||
{
|
||||
case IPAddressType::IP: res = IPAddress(Settings.IP);
|
||||
break;
|
||||
case IPAddressType::Gateway: res = IPAddress(Settings.Gateway);
|
||||
break;
|
||||
case IPAddressType::Subnetmask: res = IPAddress(Settings.Subnet);
|
||||
break;
|
||||
case IPAddressType::DNS: res = IPAddress(Settings.DNS);
|
||||
break;
|
||||
}
|
||||
/*
|
||||
IPAddress res;
|
||||
|
||||
if (IPAddressSet(res)) {
|
||||
ip = res;
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
switch (addressType)
|
||||
{
|
||||
case IPAddressType::IP: res = IPAddress(Settings.IP);
|
||||
break;
|
||||
case IPAddressType::Gateway: res = IPAddress(Settings.Gateway);
|
||||
break;
|
||||
case IPAddressType::Subnetmask: res = IPAddress(Settings.Subnet);
|
||||
break;
|
||||
case IPAddressType::DNS: res = IPAddress(Settings.DNS);
|
||||
break;
|
||||
}
|
||||
|
||||
if (IPAddressSet(res)) {
|
||||
ip = res;
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -180,6 +182,7 @@ bool NW002_data_struct_WiFi_AP::handle_priority_route_changed() { return NW002_u
|
||||
|
||||
bool NW002_data_struct_WiFi_AP::initPluginStats()
|
||||
{
|
||||
if (!Settings.getNetworkCollectStats(_networkIndex)) { return false; }
|
||||
networkStatsVarIndex_t networkStatsVarIndex{};
|
||||
PluginStats_Config_t displayConfig;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
# include "../../../src/WebServer/ESPEasy_key_value_store_webform.h"
|
||||
|
||||
# if FEATURE_TASKVALUE_UNIT_OF_MEASURE
|
||||
# include "../../../src/Helpers/ESPEasy_UnitOfMeasure.h"
|
||||
# include "../../../src/Helpers/ESPEasy_UnitOfMeasure.h"
|
||||
# endif // if FEATURE_TASKVALUE_UNIT_OF_MEASURE
|
||||
|
||||
|
||||
@@ -875,7 +875,8 @@ void NW005_begin_modem_task(void *parameter)
|
||||
NW_PLUGIN_INTERFACE.cmd(F("AT&D1"), 9000);
|
||||
digitalWrite(modem_task_data->dtrPin, HIGH);
|
||||
}
|
||||
if (!NW_PLUGIN_INTERFACE.attached()) modem_task_data->modem_init_failed = true;
|
||||
|
||||
if (!NW_PLUGIN_INTERFACE.attached()) { modem_task_data->modem_init_failed = true; }
|
||||
} else {
|
||||
modem_task_data->modem_init_failed = true;
|
||||
}
|
||||
@@ -1047,6 +1048,7 @@ bool NW005_data_struct_PPP_modem::check_connect_failed()
|
||||
{
|
||||
_modem_task_data.modem_init_failed = false;
|
||||
auto stats = getNWPluginData_static_runtime();
|
||||
|
||||
if (stats) {
|
||||
stats->mark_connect_failed();
|
||||
}
|
||||
@@ -1059,6 +1061,7 @@ bool NW005_data_struct_PPP_modem::check_connect_failed()
|
||||
|
||||
bool NW005_data_struct_PPP_modem::initPluginStats()
|
||||
{
|
||||
if (!Settings.getNetworkCollectStats(_networkIndex)) { return false; }
|
||||
networkStatsVarIndex_t networkStatsVarIndex{};
|
||||
PluginStats_Config_t displayConfig;
|
||||
|
||||
@@ -1108,13 +1111,13 @@ bool NW005_data_struct_PPP_modem::record_stats()
|
||||
|
||||
NWPluginData_static_runtime * NW005_data_struct_PPP_modem::getNWPluginData_static_runtime() { return &stats_and_cache; }
|
||||
|
||||
bool NW005_data_struct_PPP_modem::getStaticIPAddress(IPAddressType addressType, IPAddress & ip) const
|
||||
bool NW005_data_struct_PPP_modem::getStaticIPAddress(IPAddressType addressType, IPAddress& ip) const
|
||||
{
|
||||
// No static IP for PPP modem
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
void NW005_data_struct_PPP_modem::onEvent(arduino_event_id_t event, arduino_event_info_t info) {
|
||||
void NW005_data_struct_PPP_modem::onEvent(arduino_event_id_t event, arduino_event_info_t info) {
|
||||
// TODO TD-er: Must store flags from events in static (or global) object to act on it later.
|
||||
switch (event)
|
||||
{
|
||||
|
||||
@@ -58,7 +58,9 @@ bool initNWPluginData(ESPEasy::net::networkIndex_t networkIndex, NWPluginData_ba
|
||||
#endif // if FEATURE_STORE_NETWORK_INTERFACE_SETTINGS
|
||||
#if FEATURE_NETWORK_STATS
|
||||
|
||||
NWPlugin_task_data[networkIndex]->initPluginStats();
|
||||
if (Settings.getNetworkCollectStats(networkIndex)) {
|
||||
NWPlugin_task_data[networkIndex]->initPluginStats();
|
||||
}
|
||||
#endif // if FEATURE_NETWORK_STATS
|
||||
|
||||
} else {
|
||||
|
||||
@@ -394,7 +394,13 @@
|
||||
#define DEFAULT_ENABLE_TIMING_STATS false
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef DEFAULT_NETWORK_COLLECT_STATS_BITS
|
||||
#ifdef PLUGIN_BUILD_MAX_ESP32
|
||||
#define DEFAULT_NETWORK_COLLECT_STATS_BITS 0xFF
|
||||
#else
|
||||
#define DEFAULT_NETWORK_COLLECT_STATS_BITS 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// --- Advanced Settings ---------------------------------------------------------------------------------
|
||||
#if defined(ESP32)
|
||||
|
||||
@@ -506,6 +506,13 @@ public:
|
||||
|
||||
void setNetworkInterfaceStartupDelay(ESPEasy::net::networkIndex_t index, uint32_t delay_ms);
|
||||
|
||||
# if FEATURE_NETWORK_STATS
|
||||
bool getNetworkCollectStats(ESPEasy::net::networkIndex_t index) const;
|
||||
|
||||
void setNetworkCollectStats(ESPEasy::net::networkIndex_t index, bool enabled);
|
||||
#endif
|
||||
|
||||
|
||||
uint32_t PID = 0;
|
||||
int Version = 0;
|
||||
int16_t Build = 0;
|
||||
@@ -581,7 +588,7 @@ public:
|
||||
|
||||
uint32_t ConnectionFailuresThreshold = 0;
|
||||
int16_t TimeZone = 0;
|
||||
boolean MQTTRetainFlag_unused = false;
|
||||
uint8_t NetworkCollectStats_bits = DEFAULT_NETWORK_COLLECT_STATS_BITS;
|
||||
uint8_t InitSPI = 0; //0 = disabled, 1= enabled but for ESP32 there is option 2= SPI2 9 = User defined, see src/src/WebServer/HardwarePage.h enum SPI_Options_e
|
||||
// FIXME TD-er: Must change to cpluginID_t, but then also another check must be added since changing the pluginID_t will also render settings incompatible
|
||||
uint8_t Protocol[CONTROLLER_MAX] = {0};
|
||||
|
||||
@@ -747,7 +747,9 @@ void SettingsStruct_tmpl<N_TASKS>::clearMisc() {
|
||||
SyslogPort = 514;
|
||||
VariousBits_3._all_bits = 0;
|
||||
ConnectionFailuresThreshold = 0;
|
||||
MQTTRetainFlag_unused = false;
|
||||
#if FEATURE_NETWORK_STATS
|
||||
NetworkCollectStats_bits = DEFAULT_NETWORK_COLLECT_STATS_BITS;
|
||||
#endif
|
||||
InitSPI = DEFAULT_SPI;
|
||||
deepSleepOnFail = false;
|
||||
UseValueLogger = false;
|
||||
@@ -1621,4 +1623,24 @@ void SettingsStruct_tmpl<N_TASKS>::setNetworkInterfaceStartupDelay(ESPEasy::net:
|
||||
}
|
||||
|
||||
|
||||
# if FEATURE_NETWORK_STATS
|
||||
|
||||
template<uint32_t N_TASKS>
|
||||
bool SettingsStruct_tmpl<N_TASKS>::getNetworkCollectStats(ESPEasy::net::networkIndex_t index) const
|
||||
{
|
||||
if (validNetworkIndex(index)) { return bitRead(NetworkCollectStats_bits, index); }
|
||||
return false;
|
||||
}
|
||||
|
||||
template<uint32_t N_TASKS>
|
||||
void SettingsStruct_tmpl<N_TASKS>::setNetworkCollectStats(ESPEasy::net::networkIndex_t index, bool enabled)
|
||||
{
|
||||
if (validNetworkIndex(index)) {
|
||||
bitWrite(NetworkCollectStats_bits, index, enabled);
|
||||
}
|
||||
}
|
||||
|
||||
# endif // if FEATURE_NETWORK_STATS
|
||||
|
||||
|
||||
#endif // ifndef DATASTRUCTS_SETTINGSSTRUCT_CPP
|
||||
|
||||
@@ -65,6 +65,7 @@ extern bool MQTTclient_must_send_LWT_connected;
|
||||
extern bool MQTTclient_connected;
|
||||
extern int mqtt_reconnect_count;
|
||||
extern LongTermTimer MQTTclient_next_connect_attempt;
|
||||
|
||||
#endif // if FEATURE_MQTT
|
||||
|
||||
#ifdef USES_P037
|
||||
|
||||
@@ -295,10 +295,13 @@ void ResetFactory(bool formatFS)
|
||||
// advanced Settings
|
||||
// Settings.UseRules = DEFAULT_USE_RULES;
|
||||
Settings.ControllerEnabled[0] = DEFAULT_CONTROLLER_ENABLED;
|
||||
Settings.MQTTRetainFlag_unused = DEFAULT_MQTT_RETAIN;
|
||||
Settings.MessageDelay_unused = DEFAULT_MQTT_DELAY;
|
||||
Settings.MQTTUseUnitNameAsClientId_unused = DEFAULT_MQTT_USE_UNITNAME_AS_CLIENTID;
|
||||
|
||||
#if FEATURE_NETWORK_STATS
|
||||
Settings.NetworkCollectStats_bits = DEFAULT_NETWORK_COLLECT_STATS_BITS;
|
||||
#endif
|
||||
|
||||
// allow to set default latitude and longitude
|
||||
#ifdef DEFAULT_LATITUDE
|
||||
Settings.Latitude = DEFAULT_LATITUDE;
|
||||
|
||||
@@ -392,7 +392,7 @@ bool BuildFixes()
|
||||
safe_strncpy(ControllerSettings->ClientID, clientid, sizeof(ControllerSettings->ClientID));
|
||||
|
||||
ControllerSettings->mqtt_uniqueMQTTclientIdReconnect(Settings.uniqueMQTTclientIdReconnect_unused());
|
||||
ControllerSettings->mqtt_retainFlag(Settings.MQTTRetainFlag_unused);
|
||||
ControllerSettings->mqtt_retainFlag(DEFAULT_MQTT_RETAIN);
|
||||
SaveControllerSettings(controller_idx, *ControllerSettings);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -509,7 +509,7 @@ bool ESPEasy_time::systemTimePresent() const {
|
||||
|
||||
bool ESPEasy_time::getNtpTime(double& unixTime_d)
|
||||
{
|
||||
if (!Settings.UseNTP() || !ESPEasy::net::NetworkConnected()) {
|
||||
if (!Settings.UseNTP() || !ESPEasy::net::NetworkConnected(true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include "../Helpers/Hardware_I2C.h"
|
||||
#include "../Helpers/StringConverter.h"
|
||||
|
||||
#include "../Helpers/I2C_access.h"
|
||||
|
||||
#if FEATURE_I2C_MULTIPLE
|
||||
# include "../WebServer/Markup_Forms.h"
|
||||
#endif // if FEATURE_I2C_MULTIPLE
|
||||
|
||||
@@ -154,9 +154,19 @@ void sendUDP(uint8_t unit, const uint8_t *data, uint8_t size)
|
||||
/*********************************************************************************************\
|
||||
Update UDP port (ESPEasy propiertary protocol)
|
||||
\*********************************************************************************************/
|
||||
uint16_t lastUsedUDPPort = 0;
|
||||
|
||||
void stopUDPport()
|
||||
{
|
||||
if (lastUsedUDPPort == 0) return;
|
||||
if (ESPEasy::net::NetworkConnected(true)) {
|
||||
portUDP.stop();
|
||||
}
|
||||
lastUsedUDPPort = 0;
|
||||
}
|
||||
|
||||
void updateUDPport(bool force)
|
||||
{
|
||||
static uint16_t lastUsedUDPPort = 0;
|
||||
|
||||
if (!force && (Settings.UDPPort == lastUsedUDPPort)) {
|
||||
return;
|
||||
@@ -169,7 +179,8 @@ void updateUDPport(bool force)
|
||||
//const bool connected = ESPEasy::net::NetworkConnected();
|
||||
if (!connected || (Settings.UDPPort != lastUsedUDPPort)) {
|
||||
if (lastUsedUDPPort != 0) {
|
||||
portUDP.stop();
|
||||
if (connected)
|
||||
portUDP.stop();
|
||||
lastUsedUDPPort = 0;
|
||||
#ifndef BUILD_NO_DEBUG
|
||||
addLogMove(LOG_LEVEL_INFO, concat(F("UDP : Stop listening on port "), Settings.UDPPort));
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
/*********************************************************************************************\
|
||||
Update UDP port (ESPEasy propiertary protocol)
|
||||
\*********************************************************************************************/
|
||||
void stopUDPport();
|
||||
void updateUDPport(bool force);
|
||||
|
||||
|
||||
|
||||
@@ -408,7 +408,7 @@ void processMQTTdelayQueue() {
|
||||
}
|
||||
|
||||
void updateMQTTclient_connected() {
|
||||
const bool actual_MQTTclient_connected = ESPEasy::net::NetworkConnected() && MQTTclient.connected();
|
||||
const bool actual_MQTTclient_connected = ESPEasy::net::NetworkConnected(true) && MQTTclient.connected();
|
||||
if (MQTTclient_connected != actual_MQTTclient_connected) {
|
||||
MQTTclient_connected = actual_MQTTclient_connected;
|
||||
if (!actual_MQTTclient_connected) mqtt.stop(); // Make sure PubSubClient isn't trying to do a graceful disconnect
|
||||
@@ -456,7 +456,7 @@ void updateMQTTclient_connected() {
|
||||
void runPeriodicalMQTT() {
|
||||
START_TIMER
|
||||
// MQTT_KEEPALIVE = 15 seconds.
|
||||
if (!NetworkConnected(10)) {
|
||||
if (!ESPEasy::net::NetworkConnected()) {
|
||||
updateMQTTclient_connected();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -107,10 +107,6 @@ void handle_advanced() {
|
||||
Settings.ArduinoOTAEnable = isFormItemChecked(F("arduinootaenable"));
|
||||
Settings.UseRTOSMultitasking = isFormItemChecked(F("usertosmultitasking"));
|
||||
|
||||
// MQTT settings now moved to the controller settings.
|
||||
// Settings.MQTTRetainFlag_unused = isFormItemChecked(F("mqttretainflag"));
|
||||
// Settings.MQTTUseUnitNameAsClientId = isFormItemChecked(F("mqttuseunitnameasclientid"));
|
||||
// Settings.uniqueMQTTclientIdReconnect(isFormItemChecked(F("uniquemqttclientidreconnect")));
|
||||
Settings.Latitude = getFormItemFloat(F("latitude"));
|
||||
Settings.Longitude = getFormItemFloat(F("longitude"));
|
||||
#ifdef WEBSERVER_NEW_RULES
|
||||
@@ -199,18 +195,6 @@ void handle_advanced() {
|
||||
addFormCheckBox(F("SendToHTTP wait for ack"), F("sendtohttp_ack"), Settings.SendToHttp_ack());
|
||||
addFormCheckBox(F("SendToHTTP Follow Redirects"), F("sendtohttp_redir"), Settings.SendToHTTP_follow_redirects());
|
||||
|
||||
/*
|
||||
// MQTT settings now moved to the controller settings.
|
||||
addFormSubHeader(F("Controller Settings"));
|
||||
|
||||
addFormNumericBox(F("Message Interval"), F("messagedelay"), Settings.MessageDelay_unused, 0, INT_MAX);
|
||||
addUnit(F("ms"));
|
||||
|
||||
addFormCheckBox(F("MQTT Retain Msg"), F("mqttretainflag"), Settings.MQTTRetainFlag_unused);
|
||||
addFormCheckBox(F("MQTT use unit name as ClientId"), F("mqttuseunitnameasclientid"), Settings.MQTTUseUnitNameAsClientId);
|
||||
addFormCheckBox(F("MQTT change ClientId at reconnect"), F("uniquemqttclientidreconnect"), Settings.uniqueMQTTclientIdReconnect_unused());
|
||||
*/
|
||||
|
||||
addFormSubHeader(F("Time Source"));
|
||||
|
||||
addFormCheckBox(F("Use NTP"), F("usentp"), Settings.UseNTP());
|
||||
|
||||
@@ -172,6 +172,9 @@ void handle_networks_CopySubmittedSettings_NWPluginCall(ESPEasy::net::networkInd
|
||||
|
||||
# if FEATURE_USE_IPV6
|
||||
Settings.setNetworkEnabled_IPv6(networkindex, isFormItemChecked(F("en_ipv6")));
|
||||
# endif
|
||||
# if FEATURE_NETWORK_STATS
|
||||
Settings.setNetworkCollectStats(networkindex, isFormItemChecked(F("collect_netw_stats")));
|
||||
# endif
|
||||
Settings.setNetworkInterfaceStartupDelay(networkindex, getFormItemInt(F("delay_start")));
|
||||
String dummy;
|
||||
@@ -197,9 +200,9 @@ void handle_networks_ShowAllNetworksTable()
|
||||
html_table_header(F("Hostname/SSID"));
|
||||
html_table_header(F("HW Address"));
|
||||
html_table_header(F("IP"));
|
||||
# ifdef ESP32
|
||||
# ifdef ESP32
|
||||
html_table_header(F("Port"));
|
||||
# endif
|
||||
# endif
|
||||
|
||||
for (ESPEasy::net::networkIndex_t x = 0; x < MAX_NR_NETWORKS_IN_TABLE; x++)
|
||||
{
|
||||
@@ -415,6 +418,10 @@ void handle_networks_NetworkSettingsPage(ESPEasy::net::networkIndex_t networkind
|
||||
}
|
||||
# endif // if FEATURE_USE_IPV6
|
||||
|
||||
# if FEATURE_NETWORK_STATS
|
||||
addFormCheckBox(F("Collect Network Stats"), F("collect_netw_stats"), Settings.getNetworkCollectStats(networkindex));
|
||||
# endif // if FEATURE_NETWORK_STATS
|
||||
|
||||
String str;
|
||||
ESPEasy::net::NWPluginCall(NWPlugin::Function::NWPLUGIN_WEBFORM_LOAD, &TempEvent, str);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user