mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-23 18:56:38 +00:00
Merge branch 'development' of github.com:arendst/Tasmota into pr_tm1638
This commit is contained in:
commit
b6cb5f203b
10
CHANGELOG.md
10
CHANGELOG.md
@ -3,6 +3,13 @@ All notable changes to this project will be documented in this file.
|
|||||||
|
|
||||||
## [Unreleased] - Development
|
## [Unreleased] - Development
|
||||||
|
|
||||||
|
## [9.3.1.2]
|
||||||
|
### Added
|
||||||
|
- Commands ``MqttKeepAlive 1..100`` to set Mqtt Keep Alive timer (default 30) and ``MqttTimeout 1..100`` to set Mqtt Socket Timeout (default 4) (#5341)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- PubSubClient library from EspEasy v2.7.12 to Tasmota v2.8.12
|
||||||
|
|
||||||
## [9.3.1.1]
|
## [9.3.1.1]
|
||||||
### Added
|
### Added
|
||||||
- Support for CSE7761 energy monitor as used in ESP32 based Sonoff Dual R3 Pow (#10793)
|
- Support for CSE7761 energy monitor as used in ESP32 based Sonoff Dual R3 Pow (#10793)
|
||||||
@ -18,8 +25,7 @@ All notable changes to this project will be documented in this file.
|
|||||||
- ESP32 Extent BLE (#11212)
|
- ESP32 Extent BLE (#11212)
|
||||||
- ESP32 support for WS2812 hardware driver via RMT or I2S
|
- ESP32 support for WS2812 hardware driver via RMT or I2S
|
||||||
- ESP32 support for secondary I2C controller
|
- ESP32 support for secondary I2C controller
|
||||||
- Add support for MPU6686 on primary or secondary I2C bus
|
- Support for MPU6686 on primary or secondary I2C bus
|
||||||
|
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- ESP32 core library from v1.0.5-rc6 to v1.0.5
|
- ESP32 core library from v1.0.5-rc6 to v1.0.5
|
||||||
|
@ -78,8 +78,9 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
|
|||||||
|
|
||||||
[Complete list](BUILDS.md) of available feature and sensors.
|
[Complete list](BUILDS.md) of available feature and sensors.
|
||||||
|
|
||||||
## Changelog v9.3.1.1
|
## Changelog v9.3.1.2
|
||||||
### Added
|
### Added
|
||||||
|
- Commands ``MqttKeepAlive 1..100`` to set Mqtt Keep Alive timer (default 30) and ``MqttTimeout 1..100`` to set Mqtt Socket Timeout (default 4) [#5341](https://github.com/arendst/Tasmota/issues/5341)
|
||||||
- Command ``Sensor80 1 <0..7>`` to control MFRC522 RFID antenna gain from 18dB (0) to 48dB (7) [#11073](https://github.com/arendst/Tasmota/issues/11073)
|
- Command ``Sensor80 1 <0..7>`` to control MFRC522 RFID antenna gain from 18dB (0) to 48dB (7) [#11073](https://github.com/arendst/Tasmota/issues/11073)
|
||||||
- Support for SML VBUS [#11125](https://github.com/arendst/Tasmota/issues/11125)
|
- Support for SML VBUS [#11125](https://github.com/arendst/Tasmota/issues/11125)
|
||||||
- Support for NEC and OPTOMA LCD/DLP Projector serial power control by Jan Bubík [#11145](https://github.com/arendst/Tasmota/issues/11145)
|
- Support for NEC and OPTOMA LCD/DLP Projector serial power control by Jan Bubík [#11145](https://github.com/arendst/Tasmota/issues/11145)
|
||||||
@ -93,6 +94,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
|
|||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- TasmotaSerial library from v3.2.0 to v3.3.0
|
- TasmotaSerial library from v3.2.0 to v3.3.0
|
||||||
|
- PubSubClient library from EspEasy v2.7.12 to Tasmota v2.8.12
|
||||||
- ESP32 core library from v1.0.5-rc6 to v1.0.5
|
- ESP32 core library from v1.0.5-rc6 to v1.0.5
|
||||||
- TuyaMcu dimmer timeout [#11121](https://github.com/arendst/Tasmota/issues/11121)
|
- TuyaMcu dimmer timeout [#11121](https://github.com/arendst/Tasmota/issues/11121)
|
||||||
- Rename epaper 42 commands [#11222](https://github.com/arendst/Tasmota/issues/11222)
|
- Rename epaper 42 commands [#11222](https://github.com/arendst/Tasmota/issues/11222)
|
||||||
|
@ -1 +0,0 @@
|
|||||||
tests/bin
|
|
5
lib/default/pubsubclient-2.8.12/.gitignore
vendored
Normal file
5
lib/default/pubsubclient-2.8.12/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
tests/bin
|
||||||
|
.pioenvs
|
||||||
|
.piolibdeps
|
||||||
|
.clang_complete
|
||||||
|
.gcc-flags.json
|
@ -1,3 +1,12 @@
|
|||||||
|
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
|
2.7
|
||||||
* Fix remaining-length handling to prevent buffer overrun
|
* Fix remaining-length handling to prevent buffer overrun
|
||||||
* Add large-payload API - beginPublish/write/publish/endPublish
|
* Add large-payload API - beginPublish/write/publish/endPublish
|
@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2008-2015 Nicholas O'Leary
|
Copyright (c) 2008-2020 Nicholas O'Leary
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
@ -13,10 +13,12 @@ Full API documentation is available here: https://pubsubclient.knolleary.net
|
|||||||
## Limitations
|
## Limitations
|
||||||
|
|
||||||
- It can only publish QoS 0 messages. It can subscribe at QoS 0 or QoS 1.
|
- It can only publish QoS 0 messages. It can subscribe at QoS 0 or QoS 1.
|
||||||
- The maximum message size, including header, is **128 bytes** by default. This
|
- The maximum message size, including header, is **256 bytes** by default. This
|
||||||
is configurable via `MQTT_MAX_PACKET_SIZE` in `PubSubClient.h`.
|
is configurable via `MQTT_MAX_PACKET_SIZE` in `PubSubClient.h` or can be changed
|
||||||
|
by calling `PubSubClient::setBufferSize(size)`.
|
||||||
- The keepalive interval is set to 15 seconds by default. This is configurable
|
- The keepalive interval is set to 15 seconds by default. This is configurable
|
||||||
via `MQTT_KEEPALIVE` in `PubSubClient.h`.
|
via `MQTT_KEEPALIVE` in `PubSubClient.h` or can be changed by calling
|
||||||
|
`PubSubClient::setKeepAlive(keepAlive)`.
|
||||||
- The client uses MQTT 3.1.1 by default. It can be changed to use MQTT 3.1 by
|
- 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`.
|
changing value of `MQTT_VERSION` in `PubSubClient.h`.
|
||||||
|
|
@ -27,9 +27,9 @@ void setup()
|
|||||||
{
|
{
|
||||||
Ethernet.begin(mac, ip);
|
Ethernet.begin(mac, ip);
|
||||||
// Note - the default maximum packet size is 128 bytes. If the
|
// Note - the default maximum packet size is 128 bytes. If the
|
||||||
// combined length of clientId, username and password exceed this,
|
// combined length of clientId, username and password exceed this use the
|
||||||
// you will need to increase the value of MQTT_MAX_PACKET_SIZE in
|
// following to increase the buffer size:
|
||||||
// PubSubClient.h
|
// client.setBufferSize(255);
|
||||||
|
|
||||||
if (client.connect("arduinoClient", "testuser", "testpass")) {
|
if (client.connect("arduinoClient", "testuser", "testpass")) {
|
||||||
client.publish("outTopic","hello world");
|
client.publish("outTopic","hello world");
|
@ -1,26 +1,21 @@
|
|||||||
/*
|
/*
|
||||||
Basic ESP8266 MQTT example
|
Basic ESP8266 MQTT example
|
||||||
|
|
||||||
This sketch demonstrates the capabilities of the pubsub library in combination
|
This sketch demonstrates the capabilities of the pubsub library in combination
|
||||||
with the ESP8266 board/library.
|
with the ESP8266 board/library.
|
||||||
|
|
||||||
It connects to an MQTT server then:
|
It connects to an MQTT server then:
|
||||||
- publishes "hello world" to the topic "outTopic" every two seconds
|
- publishes "hello world" to the topic "outTopic" every two seconds
|
||||||
- subscribes to the topic "inTopic", printing out any messages
|
- subscribes to the topic "inTopic", printing out any messages
|
||||||
it receives. NB - it assumes the received payloads are strings not binary
|
it receives. NB - it assumes the received payloads are strings not binary
|
||||||
- If the first character of the topic "inTopic" is an 1, switch ON the ESP Led,
|
- If the first character of the topic "inTopic" is an 1, switch ON the ESP Led,
|
||||||
else switch it off
|
else switch it off
|
||||||
|
|
||||||
It will reconnect to the server if the connection is lost using a blocking
|
It will reconnect to the server if the connection is lost using a blocking
|
||||||
reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
|
reconnect function. See the 'mqtt_reconnect_nonblocking' example for how to
|
||||||
achieve the same result without blocking the main loop.
|
achieve the same result without blocking the main loop.
|
||||||
|
|
||||||
To install the ESP8266 board, (using Arduino 1.6.4+):
|
To install the ESP8266 board, (using Arduino 1.6.4+):
|
||||||
- Add the following 3rd party board manager under "File -> Preferences -> Additional Boards Manager URLs":
|
- Add the following 3rd party board manager under "File -> Preferences -> Additional Boards Manager URLs":
|
||||||
http://arduino.esp8266.com/stable/package_esp8266com_index.json
|
http://arduino.esp8266.com/stable/package_esp8266com_index.json
|
||||||
- Open the "Tools -> Board -> Board Manager" and click install for the ESP8266"
|
- Open the "Tools -> Board -> Board Manager" and click install for the ESP8266"
|
||||||
- Select your ESP8266 in "Tools -> Board"
|
- Select your ESP8266 in "Tools -> Board"
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ESP8266WiFi.h>
|
#include <ESP8266WiFi.h>
|
||||||
@ -34,8 +29,9 @@ const char* mqtt_server = "broker.mqtt-dashboard.com";
|
|||||||
|
|
||||||
WiFiClient espClient;
|
WiFiClient espClient;
|
||||||
PubSubClient client(espClient);
|
PubSubClient client(espClient);
|
||||||
long lastMsg = 0;
|
unsigned long lastMsg = 0;
|
||||||
char msg[50];
|
#define MSG_BUFFER_SIZE (50)
|
||||||
|
char msg[MSG_BUFFER_SIZE];
|
||||||
int value = 0;
|
int value = 0;
|
||||||
|
|
||||||
void setup_wifi() {
|
void setup_wifi() {
|
||||||
@ -46,6 +42,7 @@ void setup_wifi() {
|
|||||||
Serial.print("Connecting to ");
|
Serial.print("Connecting to ");
|
||||||
Serial.println(ssid);
|
Serial.println(ssid);
|
||||||
|
|
||||||
|
WiFi.mode(WIFI_STA);
|
||||||
WiFi.begin(ssid, password);
|
WiFi.begin(ssid, password);
|
||||||
|
|
||||||
while (WiFi.status() != WL_CONNECTED) {
|
while (WiFi.status() != WL_CONNECTED) {
|
||||||
@ -120,11 +117,11 @@ void loop() {
|
|||||||
}
|
}
|
||||||
client.loop();
|
client.loop();
|
||||||
|
|
||||||
long now = millis();
|
unsigned long now = millis();
|
||||||
if (now - lastMsg > 2000) {
|
if (now - lastMsg > 2000) {
|
||||||
lastMsg = now;
|
lastMsg = now;
|
||||||
++value;
|
++value;
|
||||||
snprintf (msg, 50, "hello world #%ld", value);
|
snprintf (msg, MSG_BUFFER_SIZE, "hello world #%ld", value);
|
||||||
Serial.print("Publish message: ");
|
Serial.print("Publish message: ");
|
||||||
Serial.println(msg);
|
Serial.println(msg);
|
||||||
client.publish("outTopic", msg);
|
client.publish("outTopic", msg);
|
@ -27,6 +27,9 @@ setServer KEYWORD2
|
|||||||
setCallback KEYWORD2
|
setCallback KEYWORD2
|
||||||
setClient KEYWORD2
|
setClient KEYWORD2
|
||||||
setStream KEYWORD2
|
setStream KEYWORD2
|
||||||
|
setKeepAlive KEYWORD2
|
||||||
|
setBufferSize KEYWORD2
|
||||||
|
setSocketTimeout KEYWORD2
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
# Constants (LITERAL1)
|
# Constants (LITERAL1)
|
@ -6,9 +6,13 @@
|
|||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/knolleary/pubsubclient.git"
|
"url": "https://github.com/knolleary/pubsubclient.git"
|
||||||
},
|
},
|
||||||
"version": "2.7",
|
"version": "2.8",
|
||||||
"exclude": "tests",
|
"exclude": "tests",
|
||||||
"examples": "examples/*/*.ino",
|
"examples": "examples/*/*.ino",
|
||||||
"frameworks": "arduino",
|
"frameworks": "arduino",
|
||||||
"platforms": ["espressif8266", "espressif32"]
|
"platforms": [
|
||||||
|
"atmelavr",
|
||||||
|
"espressif8266",
|
||||||
|
"espressif32"
|
||||||
|
]
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
name=PubSubClient
|
name=PubSubClient
|
||||||
version=2.7
|
version=2.8
|
||||||
author=Nick O'Leary <nick.oleary@gmail.com>
|
author=Nick O'Leary <nick.oleary@gmail.com>
|
||||||
maintainer=Nick O'Leary <nick.oleary@gmail.com>
|
maintainer=Nick O'Leary <nick.oleary@gmail.com>
|
||||||
sentence=A client library for MQTT messaging.
|
sentence=A client library for MQTT messaging.
|
@ -12,12 +12,20 @@ PubSubClient::PubSubClient() {
|
|||||||
this->_client = NULL;
|
this->_client = NULL;
|
||||||
this->stream = NULL;
|
this->stream = NULL;
|
||||||
setCallback(NULL);
|
setCallback(NULL);
|
||||||
|
this->bufferSize = 0;
|
||||||
|
setBufferSize(MQTT_MAX_PACKET_SIZE);
|
||||||
|
setKeepAlive(MQTT_KEEPALIVE);
|
||||||
|
setSocketTimeout(MQTT_SOCKET_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
PubSubClient::PubSubClient(Client& client) {
|
PubSubClient::PubSubClient(Client& client) {
|
||||||
this->_state = MQTT_DISCONNECTED;
|
this->_state = MQTT_DISCONNECTED;
|
||||||
setClient(client);
|
setClient(client);
|
||||||
this->stream = NULL;
|
this->stream = NULL;
|
||||||
|
this->bufferSize = 0;
|
||||||
|
setBufferSize(MQTT_MAX_PACKET_SIZE);
|
||||||
|
setKeepAlive(MQTT_KEEPALIVE);
|
||||||
|
setSocketTimeout(MQTT_SOCKET_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
PubSubClient::PubSubClient(IPAddress addr, uint16_t port, Client& client) {
|
PubSubClient::PubSubClient(IPAddress addr, uint16_t port, Client& client) {
|
||||||
@ -25,12 +33,20 @@ PubSubClient::PubSubClient(IPAddress addr, uint16_t port, Client& client) {
|
|||||||
setServer(addr, port);
|
setServer(addr, port);
|
||||||
setClient(client);
|
setClient(client);
|
||||||
this->stream = NULL;
|
this->stream = NULL;
|
||||||
|
this->bufferSize = 0;
|
||||||
|
setBufferSize(MQTT_MAX_PACKET_SIZE);
|
||||||
|
setKeepAlive(MQTT_KEEPALIVE);
|
||||||
|
setSocketTimeout(MQTT_SOCKET_TIMEOUT);
|
||||||
}
|
}
|
||||||
PubSubClient::PubSubClient(IPAddress addr, uint16_t port, Client& client, Stream& stream) {
|
PubSubClient::PubSubClient(IPAddress addr, uint16_t port, Client& client, Stream& stream) {
|
||||||
this->_state = MQTT_DISCONNECTED;
|
this->_state = MQTT_DISCONNECTED;
|
||||||
setServer(addr,port);
|
setServer(addr,port);
|
||||||
setClient(client);
|
setClient(client);
|
||||||
setStream(stream);
|
setStream(stream);
|
||||||
|
this->bufferSize = 0;
|
||||||
|
setBufferSize(MQTT_MAX_PACKET_SIZE);
|
||||||
|
setKeepAlive(MQTT_KEEPALIVE);
|
||||||
|
setSocketTimeout(MQTT_SOCKET_TIMEOUT);
|
||||||
}
|
}
|
||||||
PubSubClient::PubSubClient(IPAddress addr, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) {
|
PubSubClient::PubSubClient(IPAddress addr, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) {
|
||||||
this->_state = MQTT_DISCONNECTED;
|
this->_state = MQTT_DISCONNECTED;
|
||||||
@ -38,6 +54,10 @@ PubSubClient::PubSubClient(IPAddress addr, uint16_t port, MQTT_CALLBACK_SIGNATUR
|
|||||||
setCallback(callback);
|
setCallback(callback);
|
||||||
setClient(client);
|
setClient(client);
|
||||||
this->stream = NULL;
|
this->stream = NULL;
|
||||||
|
this->bufferSize = 0;
|
||||||
|
setBufferSize(MQTT_MAX_PACKET_SIZE);
|
||||||
|
setKeepAlive(MQTT_KEEPALIVE);
|
||||||
|
setSocketTimeout(MQTT_SOCKET_TIMEOUT);
|
||||||
}
|
}
|
||||||
PubSubClient::PubSubClient(IPAddress addr, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) {
|
PubSubClient::PubSubClient(IPAddress addr, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) {
|
||||||
this->_state = MQTT_DISCONNECTED;
|
this->_state = MQTT_DISCONNECTED;
|
||||||
@ -45,6 +65,10 @@ PubSubClient::PubSubClient(IPAddress addr, uint16_t port, MQTT_CALLBACK_SIGNATUR
|
|||||||
setCallback(callback);
|
setCallback(callback);
|
||||||
setClient(client);
|
setClient(client);
|
||||||
setStream(stream);
|
setStream(stream);
|
||||||
|
this->bufferSize = 0;
|
||||||
|
setBufferSize(MQTT_MAX_PACKET_SIZE);
|
||||||
|
setKeepAlive(MQTT_KEEPALIVE);
|
||||||
|
setSocketTimeout(MQTT_SOCKET_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, Client& client) {
|
PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, Client& client) {
|
||||||
@ -52,12 +76,20 @@ PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, Client& client) {
|
|||||||
setServer(ip, port);
|
setServer(ip, port);
|
||||||
setClient(client);
|
setClient(client);
|
||||||
this->stream = NULL;
|
this->stream = NULL;
|
||||||
|
this->bufferSize = 0;
|
||||||
|
setBufferSize(MQTT_MAX_PACKET_SIZE);
|
||||||
|
setKeepAlive(MQTT_KEEPALIVE);
|
||||||
|
setSocketTimeout(MQTT_SOCKET_TIMEOUT);
|
||||||
}
|
}
|
||||||
PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, Client& client, Stream& stream) {
|
PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, Client& client, Stream& stream) {
|
||||||
this->_state = MQTT_DISCONNECTED;
|
this->_state = MQTT_DISCONNECTED;
|
||||||
setServer(ip,port);
|
setServer(ip,port);
|
||||||
setClient(client);
|
setClient(client);
|
||||||
setStream(stream);
|
setStream(stream);
|
||||||
|
this->bufferSize = 0;
|
||||||
|
setBufferSize(MQTT_MAX_PACKET_SIZE);
|
||||||
|
setKeepAlive(MQTT_KEEPALIVE);
|
||||||
|
setSocketTimeout(MQTT_SOCKET_TIMEOUT);
|
||||||
}
|
}
|
||||||
PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) {
|
PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) {
|
||||||
this->_state = MQTT_DISCONNECTED;
|
this->_state = MQTT_DISCONNECTED;
|
||||||
@ -65,6 +97,10 @@ PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, MQTT_CALLBACK_SIGNATURE,
|
|||||||
setCallback(callback);
|
setCallback(callback);
|
||||||
setClient(client);
|
setClient(client);
|
||||||
this->stream = NULL;
|
this->stream = NULL;
|
||||||
|
this->bufferSize = 0;
|
||||||
|
setBufferSize(MQTT_MAX_PACKET_SIZE);
|
||||||
|
setKeepAlive(MQTT_KEEPALIVE);
|
||||||
|
setSocketTimeout(MQTT_SOCKET_TIMEOUT);
|
||||||
}
|
}
|
||||||
PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) {
|
PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) {
|
||||||
this->_state = MQTT_DISCONNECTED;
|
this->_state = MQTT_DISCONNECTED;
|
||||||
@ -72,6 +108,10 @@ PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, MQTT_CALLBACK_SIGNATURE,
|
|||||||
setCallback(callback);
|
setCallback(callback);
|
||||||
setClient(client);
|
setClient(client);
|
||||||
setStream(stream);
|
setStream(stream);
|
||||||
|
this->bufferSize = 0;
|
||||||
|
setBufferSize(MQTT_MAX_PACKET_SIZE);
|
||||||
|
setKeepAlive(MQTT_KEEPALIVE);
|
||||||
|
setSocketTimeout(MQTT_SOCKET_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
PubSubClient::PubSubClient(const char* domain, uint16_t port, Client& client) {
|
PubSubClient::PubSubClient(const char* domain, uint16_t port, Client& client) {
|
||||||
@ -79,12 +119,20 @@ PubSubClient::PubSubClient(const char* domain, uint16_t port, Client& client) {
|
|||||||
setServer(domain,port);
|
setServer(domain,port);
|
||||||
setClient(client);
|
setClient(client);
|
||||||
this->stream = NULL;
|
this->stream = NULL;
|
||||||
|
this->bufferSize = 0;
|
||||||
|
setBufferSize(MQTT_MAX_PACKET_SIZE);
|
||||||
|
setKeepAlive(MQTT_KEEPALIVE);
|
||||||
|
setSocketTimeout(MQTT_SOCKET_TIMEOUT);
|
||||||
}
|
}
|
||||||
PubSubClient::PubSubClient(const char* domain, uint16_t port, Client& client, Stream& stream) {
|
PubSubClient::PubSubClient(const char* domain, uint16_t port, Client& client, Stream& stream) {
|
||||||
this->_state = MQTT_DISCONNECTED;
|
this->_state = MQTT_DISCONNECTED;
|
||||||
setServer(domain,port);
|
setServer(domain,port);
|
||||||
setClient(client);
|
setClient(client);
|
||||||
setStream(stream);
|
setStream(stream);
|
||||||
|
this->bufferSize = 0;
|
||||||
|
setBufferSize(MQTT_MAX_PACKET_SIZE);
|
||||||
|
setKeepAlive(MQTT_KEEPALIVE);
|
||||||
|
setSocketTimeout(MQTT_SOCKET_TIMEOUT);
|
||||||
}
|
}
|
||||||
PubSubClient::PubSubClient(const char* domain, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) {
|
PubSubClient::PubSubClient(const char* domain, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client) {
|
||||||
this->_state = MQTT_DISCONNECTED;
|
this->_state = MQTT_DISCONNECTED;
|
||||||
@ -92,6 +140,10 @@ PubSubClient::PubSubClient(const char* domain, uint16_t port, MQTT_CALLBACK_SIGN
|
|||||||
setCallback(callback);
|
setCallback(callback);
|
||||||
setClient(client);
|
setClient(client);
|
||||||
this->stream = NULL;
|
this->stream = NULL;
|
||||||
|
this->bufferSize = 0;
|
||||||
|
setBufferSize(MQTT_MAX_PACKET_SIZE);
|
||||||
|
setKeepAlive(MQTT_KEEPALIVE);
|
||||||
|
setSocketTimeout(MQTT_SOCKET_TIMEOUT);
|
||||||
}
|
}
|
||||||
PubSubClient::PubSubClient(const char* domain, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) {
|
PubSubClient::PubSubClient(const char* domain, uint16_t port, MQTT_CALLBACK_SIGNATURE, Client& client, Stream& stream) {
|
||||||
this->_state = MQTT_DISCONNECTED;
|
this->_state = MQTT_DISCONNECTED;
|
||||||
@ -99,6 +151,14 @@ PubSubClient::PubSubClient(const char* domain, uint16_t port, MQTT_CALLBACK_SIGN
|
|||||||
setCallback(callback);
|
setCallback(callback);
|
||||||
setClient(client);
|
setClient(client);
|
||||||
setStream(stream);
|
setStream(stream);
|
||||||
|
this->bufferSize = 0;
|
||||||
|
setBufferSize(MQTT_MAX_PACKET_SIZE);
|
||||||
|
setKeepAlive(MQTT_KEEPALIVE);
|
||||||
|
setSocketTimeout(MQTT_SOCKET_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
PubSubClient::~PubSubClient() {
|
||||||
|
free(this->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean PubSubClient::connect(const char *id) {
|
boolean PubSubClient::connect(const char *id) {
|
||||||
@ -121,18 +181,29 @@ boolean PubSubClient::connect(const char *id, const char *user, const char *pass
|
|||||||
if (!connected()) {
|
if (!connected()) {
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
|
// Start Tasmota patch
|
||||||
if (_client == nullptr) {
|
if (_client == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (_client->connected()) {
|
// End Tasmota patch
|
||||||
|
|
||||||
|
if(_client->connected()) {
|
||||||
result = 1;
|
result = 1;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
// Start Tasmota patch
|
||||||
|
// if (domain != NULL) {
|
||||||
|
// result = _client->connect(this->domain, this->port);
|
||||||
|
|
||||||
if (domain.length() != 0) {
|
if (domain.length() != 0) {
|
||||||
result = _client->connect(this->domain.c_str(), this->port);
|
result = _client->connect(this->domain.c_str(), this->port);
|
||||||
|
// End Tasmota patch
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
result = _client->connect(this->ip, this->port);
|
result = _client->connect(this->ip, this->port);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == 1) {
|
if (result == 1) {
|
||||||
nextMsgId = 1;
|
nextMsgId = 1;
|
||||||
// Leave room in the buffer for header and variable length field
|
// Leave room in the buffer for header and variable length field
|
||||||
@ -147,7 +218,7 @@ boolean PubSubClient::connect(const char *id, const char *user, const char *pass
|
|||||||
#define MQTT_HEADER_VERSION_LENGTH 7
|
#define MQTT_HEADER_VERSION_LENGTH 7
|
||||||
#endif
|
#endif
|
||||||
for (j = 0;j<MQTT_HEADER_VERSION_LENGTH;j++) {
|
for (j = 0;j<MQTT_HEADER_VERSION_LENGTH;j++) {
|
||||||
buffer[length++] = d[j];
|
this->buffer[length++] = d[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t v;
|
uint8_t v;
|
||||||
@ -167,45 +238,48 @@ boolean PubSubClient::connect(const char *id, const char *user, const char *pass
|
|||||||
v = v|(0x80>>1);
|
v = v|(0x80>>1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this->buffer[length++] = v;
|
||||||
|
|
||||||
buffer[length++] = v;
|
this->buffer[length++] = ((this->keepAlive) >> 8);
|
||||||
|
this->buffer[length++] = ((this->keepAlive) & 0xFF);
|
||||||
buffer[length++] = ((MQTT_KEEPALIVE) >> 8);
|
|
||||||
buffer[length++] = ((MQTT_KEEPALIVE) & 0xFF);
|
|
||||||
|
|
||||||
CHECK_STRING_LENGTH(length,id)
|
CHECK_STRING_LENGTH(length,id)
|
||||||
length = writeString(id,buffer,length);
|
length = writeString(id,this->buffer,length);
|
||||||
if (willTopic) {
|
if (willTopic) {
|
||||||
CHECK_STRING_LENGTH(length,willTopic)
|
CHECK_STRING_LENGTH(length,willTopic)
|
||||||
length = writeString(willTopic,buffer,length);
|
length = writeString(willTopic,this->buffer,length);
|
||||||
CHECK_STRING_LENGTH(length,willMessage)
|
CHECK_STRING_LENGTH(length,willMessage)
|
||||||
length = writeString(willMessage,buffer,length);
|
length = writeString(willMessage,this->buffer,length);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(user != NULL) {
|
if(user != NULL) {
|
||||||
CHECK_STRING_LENGTH(length,user)
|
CHECK_STRING_LENGTH(length,user)
|
||||||
length = writeString(user,buffer,length);
|
length = writeString(user,this->buffer,length);
|
||||||
if(pass != NULL) {
|
if(pass != NULL) {
|
||||||
CHECK_STRING_LENGTH(length,pass)
|
CHECK_STRING_LENGTH(length,pass)
|
||||||
length = writeString(pass,buffer,length);
|
length = writeString(pass,this->buffer,length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
write(MQTTCONNECT,buffer,length-MQTT_MAX_HEADER_SIZE);
|
write(MQTTCONNECT,this->buffer,length-MQTT_MAX_HEADER_SIZE);
|
||||||
|
|
||||||
lastInActivity = lastOutActivity = millis();
|
lastInActivity = lastOutActivity = millis();
|
||||||
|
|
||||||
while (!_client->available()) {
|
while (!_client->available()) {
|
||||||
|
|
||||||
|
// Start Tasmota patch
|
||||||
delay(0); // Prevent watchdog crashes
|
delay(0); // Prevent watchdog crashes
|
||||||
|
// End Tasmota patch
|
||||||
|
|
||||||
unsigned long t = millis();
|
unsigned long t = millis();
|
||||||
if (t-lastInActivity >= ((int32_t) MQTT_SOCKET_TIMEOUT*1000UL)) {
|
if (t-lastInActivity >= ((int32_t) this->socketTimeout*1000UL)) {
|
||||||
_state = MQTT_CONNECTION_TIMEOUT;
|
_state = MQTT_CONNECTION_TIMEOUT;
|
||||||
_client->stop();
|
_client->stop();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint8_t llen;
|
uint8_t llen;
|
||||||
uint16_t len = readPacket(&llen);
|
uint32_t len = readPacket(&llen);
|
||||||
|
|
||||||
if (len == 4) {
|
if (len == 4) {
|
||||||
if (buffer[3] == 0) {
|
if (buffer[3] == 0) {
|
||||||
@ -228,14 +302,24 @@ boolean PubSubClient::connect(const char *id, const char *user, const char *pass
|
|||||||
|
|
||||||
// reads a byte into result
|
// reads a byte into result
|
||||||
boolean PubSubClient::readByte(uint8_t * result) {
|
boolean PubSubClient::readByte(uint8_t * result) {
|
||||||
|
|
||||||
|
// Start Tasmota patch
|
||||||
if (_client == nullptr) {
|
if (_client == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
// End Tasmota patch
|
||||||
|
|
||||||
uint32_t previousMillis = millis();
|
uint32_t previousMillis = millis();
|
||||||
while(!_client->available()) {
|
while(!_client->available()) {
|
||||||
|
|
||||||
|
// Start Tasmota patch
|
||||||
|
// yield();
|
||||||
|
|
||||||
delay(1); // Prevent watchdog crashes
|
delay(1); // Prevent watchdog crashes
|
||||||
|
// End Tasmota patch
|
||||||
|
|
||||||
uint32_t currentMillis = millis();
|
uint32_t currentMillis = millis();
|
||||||
if(currentMillis - previousMillis >= ((int32_t) MQTT_SOCKET_TIMEOUT * 1000)){
|
if(currentMillis - previousMillis >= ((int32_t) this->socketTimeout * 1000)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,15 +338,15 @@ boolean PubSubClient::readByte(uint8_t * result, uint16_t * index){
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t PubSubClient::readPacket(uint8_t* lengthLength) {
|
uint32_t PubSubClient::readPacket(uint8_t* lengthLength) {
|
||||||
uint16_t len = 0;
|
uint16_t len = 0;
|
||||||
if(!readByte(buffer, &len)) return 0;
|
if(!readByte(this->buffer, &len)) return 0;
|
||||||
bool isPublish = (buffer[0]&0xF0) == MQTTPUBLISH;
|
bool isPublish = (this->buffer[0]&0xF0) == MQTTPUBLISH;
|
||||||
uint32_t multiplier = 1;
|
uint32_t multiplier = 1;
|
||||||
uint16_t length = 0;
|
uint32_t length = 0;
|
||||||
uint8_t digit = 0;
|
uint8_t digit = 0;
|
||||||
uint16_t skip = 0;
|
uint16_t skip = 0;
|
||||||
uint8_t start = 0;
|
uint32_t start = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (len == 5) {
|
if (len == 5) {
|
||||||
@ -272,59 +356,75 @@ uint16_t PubSubClient::readPacket(uint8_t* lengthLength) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(!readByte(&digit)) return 0;
|
if(!readByte(&digit)) return 0;
|
||||||
buffer[len++] = digit;
|
this->buffer[len++] = digit;
|
||||||
length += (digit & 127) * multiplier;
|
length += (digit & 127) * multiplier;
|
||||||
multiplier *= 128;
|
multiplier <<=7; //multiplier *= 128
|
||||||
} while ((digit & 128) != 0 && len < (MQTT_MAX_PACKET_SIZE -2));
|
|
||||||
|
// Start Tasmota patch
|
||||||
|
// } while ((digit & 128) != 0);
|
||||||
|
|
||||||
|
} while ((digit & 128) != 0 && len < (this->bufferSize -2));
|
||||||
|
// End Tasmota patch
|
||||||
|
|
||||||
*lengthLength = len-1;
|
*lengthLength = len-1;
|
||||||
|
|
||||||
if (isPublish) {
|
if (isPublish) {
|
||||||
// Read in topic length to calculate bytes to skip over for Stream writing
|
// Read in topic length to calculate bytes to skip over for Stream writing
|
||||||
if(!readByte(buffer, &len)) return 0;
|
if(!readByte(this->buffer, &len)) return 0;
|
||||||
if(!readByte(buffer, &len)) return 0;
|
if(!readByte(this->buffer, &len)) return 0;
|
||||||
skip = (buffer[*lengthLength+1]<<8)+buffer[*lengthLength+2];
|
skip = (this->buffer[*lengthLength+1]<<8)+this->buffer[*lengthLength+2];
|
||||||
start = 2;
|
start = 2;
|
||||||
if (buffer[0]&MQTTQOS1) {
|
if (this->buffer[0]&MQTTQOS1) {
|
||||||
// skip message id
|
// skip message id
|
||||||
skip += 2;
|
skip += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
uint32_t idx = len;
|
||||||
|
|
||||||
for (uint16_t i = start;i<length;i++) {
|
for (uint32_t i = start;i<length;i++) {
|
||||||
if(!readByte(&digit)) return 0;
|
if(!readByte(&digit)) return 0;
|
||||||
if (this->stream) {
|
if (this->stream) {
|
||||||
if (isPublish && len-*lengthLength-2>skip) {
|
if (isPublish && idx-*lengthLength-2>skip) {
|
||||||
this->stream->write(digit);
|
this->stream->write(digit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (len < MQTT_MAX_PACKET_SIZE) {
|
|
||||||
buffer[len] = digit;
|
if (len < this->bufferSize) {
|
||||||
}
|
this->buffer[len] = digit;
|
||||||
len++;
|
len++;
|
||||||
}
|
}
|
||||||
|
idx++;
|
||||||
if (!this->stream && len > MQTT_MAX_PACKET_SIZE) {
|
|
||||||
len = 0; // This will cause the packet to be ignored.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this->stream && idx > this->bufferSize) {
|
||||||
|
len = 0; // This will cause the packet to be ignored.
|
||||||
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean PubSubClient::loop() {
|
boolean PubSubClient::loop() {
|
||||||
if (connected()) {
|
if (connected()) {
|
||||||
unsigned long t = millis();
|
unsigned long t = millis();
|
||||||
if ((t - lastInActivity > MQTT_KEEPALIVE*1000UL) || (t - lastOutActivity > MQTT_KEEPALIVE*1000UL)) {
|
if ((t - lastInActivity > this->keepAlive*1000UL) || (t - lastOutActivity > this->keepAlive*1000UL)) {
|
||||||
if (pingOutstanding) {
|
if (pingOutstanding) {
|
||||||
this->_state = MQTT_CONNECTION_TIMEOUT;
|
this->_state = MQTT_CONNECTION_TIMEOUT;
|
||||||
_client->stop();
|
_client->stop();
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
buffer[0] = MQTTPINGREQ;
|
this->buffer[0] = MQTTPINGREQ;
|
||||||
buffer[1] = 0;
|
this->buffer[1] = 0;
|
||||||
if (_client->write(buffer,2) != 0) {
|
|
||||||
|
// Start Tasmota patch
|
||||||
|
// _client->write(this->buffer,2);
|
||||||
|
// lastOutActivity = t;
|
||||||
|
// lastInActivity = t;
|
||||||
|
|
||||||
|
if (_client->write(this->buffer,2) != 0) {
|
||||||
lastOutActivity = t;
|
lastOutActivity = t;
|
||||||
lastInActivity = t;
|
lastInActivity = t;
|
||||||
}
|
}
|
||||||
|
// End Tasmota patch
|
||||||
|
|
||||||
pingOutstanding = true;
|
pingOutstanding = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -335,35 +435,42 @@ boolean PubSubClient::loop() {
|
|||||||
uint8_t *payload;
|
uint8_t *payload;
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
lastInActivity = t;
|
lastInActivity = t;
|
||||||
uint8_t type = buffer[0]&0xF0;
|
uint8_t type = this->buffer[0]&0xF0;
|
||||||
if (type == MQTTPUBLISH) {
|
if (type == MQTTPUBLISH) {
|
||||||
if (callback) {
|
if (callback) {
|
||||||
uint16_t tl = (buffer[llen+1]<<8)+buffer[llen+2]; /* topic length in bytes */
|
uint16_t tl = (this->buffer[llen+1]<<8)+this->buffer[llen+2]; /* topic length in bytes */
|
||||||
memmove(buffer+llen+2,buffer+llen+3,tl); /* move topic inside buffer 1 byte to front */
|
memmove(this->buffer+llen+2,this->buffer+llen+3,tl); /* move topic inside buffer 1 byte to front */
|
||||||
buffer[llen+2+tl] = 0; /* end the topic as a 'C' string with \x00 */
|
this->buffer[llen+2+tl] = 0; /* end the topic as a 'C' string with \x00 */
|
||||||
char *topic = (char*) buffer+llen+2;
|
char *topic = (char*) this->buffer+llen+2;
|
||||||
// msgId only present for QOS>0
|
// msgId only present for QOS>0
|
||||||
if ((buffer[0]&0x06) == MQTTQOS1) {
|
if ((this->buffer[0]&0x06) == MQTTQOS1) {
|
||||||
msgId = (buffer[llen+3+tl]<<8)+buffer[llen+3+tl+1];
|
msgId = (this->buffer[llen+3+tl]<<8)+this->buffer[llen+3+tl+1];
|
||||||
payload = buffer+llen+3+tl+2;
|
payload = this->buffer+llen+3+tl+2;
|
||||||
callback(topic,payload,len-llen-3-tl-2);
|
callback(topic,payload,len-llen-3-tl-2);
|
||||||
|
|
||||||
buffer[0] = MQTTPUBACK;
|
this->buffer[0] = MQTTPUBACK;
|
||||||
buffer[1] = 2;
|
this->buffer[1] = 2;
|
||||||
buffer[2] = (msgId >> 8);
|
this->buffer[2] = (msgId >> 8);
|
||||||
buffer[3] = (msgId & 0xFF);
|
this->buffer[3] = (msgId & 0xFF);
|
||||||
if (_client->write(buffer,4) != 0) {
|
|
||||||
|
// Start Tasmota patch
|
||||||
|
// _client->write(this->buffer,4);
|
||||||
|
// lastOutActivity = t;
|
||||||
|
|
||||||
|
if (_client->write(this->buffer,4) != 0) {
|
||||||
lastOutActivity = t;
|
lastOutActivity = t;
|
||||||
}
|
}
|
||||||
|
// End Tasmota patch
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
payload = buffer+llen+3+tl;
|
payload = this->buffer+llen+3+tl;
|
||||||
callback(topic,payload,len-llen-3-tl);
|
callback(topic,payload,len-llen-3-tl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (type == MQTTPINGREQ) {
|
} else if (type == MQTTPINGREQ) {
|
||||||
buffer[0] = MQTTPINGRESP;
|
this->buffer[0] = MQTTPINGRESP;
|
||||||
buffer[1] = 0;
|
this->buffer[1] = 0;
|
||||||
_client->write(buffer,2);
|
_client->write(this->buffer,2);
|
||||||
} else if (type == MQTTPINGRESP) {
|
} else if (type == MQTTPINGRESP) {
|
||||||
pingOutstanding = false;
|
pingOutstanding = false;
|
||||||
}
|
}
|
||||||
@ -378,13 +485,11 @@ boolean PubSubClient::loop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean PubSubClient::publish(const char* topic, const char* payload) {
|
boolean PubSubClient::publish(const char* topic, const char* payload) {
|
||||||
size_t plength = (payload != nullptr) ? strlen(payload) : 0;
|
return publish(topic,(const uint8_t*)payload, payload ? strnlen(payload, this->bufferSize) : 0,false);
|
||||||
return publish(topic,(const uint8_t*)payload,plength,false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean PubSubClient::publish(const char* topic, const char* payload, boolean retained) {
|
boolean PubSubClient::publish(const char* topic, const char* payload, boolean retained) {
|
||||||
size_t plength = (payload != nullptr) ? strlen(payload) : 0;
|
return publish(topic,(const uint8_t*)payload, payload ? strnlen(payload, this->bufferSize) : 0,retained);
|
||||||
return publish(topic,(const uint8_t*)payload,plength,retained);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean PubSubClient::publish(const char* topic, const uint8_t* payload, unsigned int plength) {
|
boolean PubSubClient::publish(const char* topic, const uint8_t* payload, unsigned int plength) {
|
||||||
@ -393,29 +498,32 @@ boolean PubSubClient::publish(const char* topic, const uint8_t* payload, unsigne
|
|||||||
|
|
||||||
boolean PubSubClient::publish(const char* topic, const uint8_t* payload, unsigned int plength, boolean retained) {
|
boolean PubSubClient::publish(const char* topic, const uint8_t* payload, unsigned int plength, boolean retained) {
|
||||||
if (connected()) {
|
if (connected()) {
|
||||||
if (MQTT_MAX_PACKET_SIZE < MQTT_MAX_HEADER_SIZE + 2+strlen(topic) + plength) {
|
if (this->bufferSize < MQTT_MAX_HEADER_SIZE + 2+strnlen(topic, this->bufferSize) + plength) {
|
||||||
// Too long
|
// Too long
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Leave room in the buffer for header and variable length field
|
// Leave room in the buffer for header and variable length field
|
||||||
uint16_t length = MQTT_MAX_HEADER_SIZE;
|
uint16_t length = MQTT_MAX_HEADER_SIZE;
|
||||||
length = writeString(topic,buffer,length);
|
length = writeString(topic,this->buffer,length);
|
||||||
|
|
||||||
|
// Add payload
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
for (i=0;i<plength;i++) {
|
for (i=0;i<plength;i++) {
|
||||||
buffer[length++] = payload[i];
|
this->buffer[length++] = payload[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write the header
|
||||||
uint8_t header = MQTTPUBLISH;
|
uint8_t header = MQTTPUBLISH;
|
||||||
if (retained) {
|
if (retained) {
|
||||||
header |= 1;
|
header |= 1;
|
||||||
}
|
}
|
||||||
return write(header,buffer,length-MQTT_MAX_HEADER_SIZE);
|
return write(header,this->buffer,length-MQTT_MAX_HEADER_SIZE);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean PubSubClient::publish_P(const char* topic, const char* payload, boolean retained) {
|
boolean PubSubClient::publish_P(const char* topic, const char* payload, boolean retained) {
|
||||||
size_t plength = (payload != nullptr) ? strlen(payload) : 0;
|
return publish_P(topic, (const uint8_t*)payload, payload ? strnlen(payload, this->bufferSize) : 0, retained);
|
||||||
return publish_P(topic, (const uint8_t*)payload, plength, retained);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean PubSubClient::publish_P(const char* topic, const uint8_t* payload, unsigned int plength, boolean retained) {
|
boolean PubSubClient::publish_P(const char* topic, const uint8_t* payload, unsigned int plength, boolean retained) {
|
||||||
@ -427,42 +535,48 @@ boolean PubSubClient::publish_P(const char* topic, const uint8_t* payload, unsig
|
|||||||
unsigned int i;
|
unsigned int i;
|
||||||
uint8_t header;
|
uint8_t header;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
|
int expectedLength;
|
||||||
|
|
||||||
if (!connected()) {
|
if (!connected()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
tlen = strlen(topic);
|
tlen = strnlen(topic, this->bufferSize);
|
||||||
|
|
||||||
header = MQTTPUBLISH;
|
header = MQTTPUBLISH;
|
||||||
if (retained) {
|
if (retained) {
|
||||||
header |= 1;
|
header |= 1;
|
||||||
}
|
}
|
||||||
buffer[pos++] = header;
|
this->buffer[pos++] = header;
|
||||||
len = plength + 2 + tlen;
|
len = plength + 2 + tlen;
|
||||||
do {
|
do {
|
||||||
digit = len % 128;
|
digit = len & 127; //digit = len %128
|
||||||
len = len / 128;
|
len >>= 7; //len = len / 128
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
digit |= 0x80;
|
digit |= 0x80;
|
||||||
}
|
}
|
||||||
buffer[pos++] = digit;
|
this->buffer[pos++] = digit;
|
||||||
llen++;
|
llen++;
|
||||||
} while(len>0);
|
} while(len>0);
|
||||||
|
|
||||||
pos = writeString(topic,buffer,pos);
|
pos = writeString(topic,this->buffer,pos);
|
||||||
|
|
||||||
rc += _client->write(buffer,pos);
|
rc += _client->write(this->buffer,pos);
|
||||||
|
|
||||||
for (i=0;i<plength;i++) {
|
for (i=0;i<plength;i++) {
|
||||||
rc += _client->write((char)pgm_read_byte_near(payload + i));
|
rc += _client->write((char)pgm_read_byte_near(payload + i));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Start Tasmota patch
|
||||||
|
// lastOutActivity = millis();
|
||||||
|
|
||||||
if (rc > 0) {
|
if (rc > 0) {
|
||||||
lastOutActivity = millis();
|
lastOutActivity = millis();
|
||||||
}
|
}
|
||||||
|
// End Tasmota patch
|
||||||
|
|
||||||
|
expectedLength = 1 + llen + 2 + tlen + plength;
|
||||||
|
|
||||||
// Header (1 byte) + llen + identifier (2 bytes) + topic len + payload len
|
|
||||||
const unsigned int expectedLength = 1 + llen + 2 + tlen + plength;
|
|
||||||
return (rc == expectedLength);
|
return (rc == expectedLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,16 +584,22 @@ boolean PubSubClient::beginPublish(const char* topic, unsigned int plength, bool
|
|||||||
if (connected()) {
|
if (connected()) {
|
||||||
// Send the header and variable length field
|
// Send the header and variable length field
|
||||||
uint16_t length = MQTT_MAX_HEADER_SIZE;
|
uint16_t length = MQTT_MAX_HEADER_SIZE;
|
||||||
length = writeString(topic,buffer,length);
|
length = writeString(topic,this->buffer,length);
|
||||||
uint8_t header = MQTTPUBLISH;
|
uint8_t header = MQTTPUBLISH;
|
||||||
if (retained) {
|
if (retained) {
|
||||||
header |= 1;
|
header |= 1;
|
||||||
}
|
}
|
||||||
size_t hlen = buildHeader(header, buffer, plength+length-MQTT_MAX_HEADER_SIZE);
|
size_t hlen = buildHeader(header, this->buffer, plength+length-MQTT_MAX_HEADER_SIZE);
|
||||||
uint16_t rc = _client->write(buffer+(MQTT_MAX_HEADER_SIZE-hlen),length-(MQTT_MAX_HEADER_SIZE-hlen));
|
uint16_t rc = _client->write(this->buffer+(MQTT_MAX_HEADER_SIZE-hlen),length-(MQTT_MAX_HEADER_SIZE-hlen));
|
||||||
|
|
||||||
|
// Start Tasmota patch
|
||||||
|
// lastOutActivity = millis();
|
||||||
|
|
||||||
if (rc > 0) {
|
if (rc > 0) {
|
||||||
lastOutActivity = millis();
|
lastOutActivity = millis();
|
||||||
}
|
}
|
||||||
|
// End Tasmota patch
|
||||||
|
|
||||||
return (rc == (length-(MQTT_MAX_HEADER_SIZE-hlen)));
|
return (rc == (length-(MQTT_MAX_HEADER_SIZE-hlen)));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -490,6 +610,11 @@ int PubSubClient::endPublish() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t PubSubClient::write(uint8_t data) {
|
size_t PubSubClient::write(uint8_t data) {
|
||||||
|
|
||||||
|
// Start Tasmota patch
|
||||||
|
// lastOutActivity = millis();
|
||||||
|
// return _client->write(data);
|
||||||
|
|
||||||
if (_client == nullptr) {
|
if (_client == nullptr) {
|
||||||
lastOutActivity = millis();
|
lastOutActivity = millis();
|
||||||
return 0;
|
return 0;
|
||||||
@ -499,9 +624,16 @@ size_t PubSubClient::write(uint8_t data) {
|
|||||||
lastOutActivity = millis();
|
lastOutActivity = millis();
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
|
// End Tasmota patch
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t PubSubClient::write(const uint8_t *buffer, size_t size) {
|
size_t PubSubClient::write(const uint8_t *buffer, size_t size) {
|
||||||
|
|
||||||
|
// Start Tasmota patch
|
||||||
|
// lastOutActivity = millis();
|
||||||
|
// return _client->write(buffer,size);
|
||||||
|
|
||||||
if (_client == nullptr) {
|
if (_client == nullptr) {
|
||||||
lastOutActivity = millis();
|
lastOutActivity = millis();
|
||||||
return 0;
|
return 0;
|
||||||
@ -511,6 +643,8 @@ size_t PubSubClient::write(const uint8_t *buffer, size_t size) {
|
|||||||
lastOutActivity = millis();
|
lastOutActivity = millis();
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
|
// End Tasmota patch
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t PubSubClient::buildHeader(uint8_t header, uint8_t* buf, uint16_t length) {
|
size_t PubSubClient::buildHeader(uint8_t header, uint8_t* buf, uint16_t length) {
|
||||||
@ -520,8 +654,9 @@ size_t PubSubClient::buildHeader(uint8_t header, uint8_t* buf, uint16_t length)
|
|||||||
uint8_t pos = 0;
|
uint8_t pos = 0;
|
||||||
uint16_t len = length;
|
uint16_t len = length;
|
||||||
do {
|
do {
|
||||||
digit = len % 128;
|
|
||||||
len = len / 128;
|
digit = len & 127; //digit = len %128
|
||||||
|
len >>= 7; //len = len / 128
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
digit |= 0x80;
|
digit |= 0x80;
|
||||||
}
|
}
|
||||||
@ -546,7 +681,6 @@ boolean PubSubClient::write(uint8_t header, uint8_t* buf, uint16_t length) {
|
|||||||
uint8_t bytesToWrite;
|
uint8_t bytesToWrite;
|
||||||
boolean result = true;
|
boolean result = true;
|
||||||
while((bytesRemaining > 0) && result) {
|
while((bytesRemaining > 0) && result) {
|
||||||
delay(0); // Prevent watchdog crashes
|
|
||||||
bytesToWrite = (bytesRemaining > MQTT_MAX_TRANSFER_SIZE)?MQTT_MAX_TRANSFER_SIZE:bytesRemaining;
|
bytesToWrite = (bytesRemaining > MQTT_MAX_TRANSFER_SIZE)?MQTT_MAX_TRANSFER_SIZE:bytesRemaining;
|
||||||
rc = _client->write(writeBuf,bytesToWrite);
|
rc = _client->write(writeBuf,bytesToWrite);
|
||||||
result = (rc == bytesToWrite);
|
result = (rc == bytesToWrite);
|
||||||
@ -556,9 +690,15 @@ boolean PubSubClient::write(uint8_t header, uint8_t* buf, uint16_t length) {
|
|||||||
return result;
|
return result;
|
||||||
#else
|
#else
|
||||||
rc = _client->write(buf+(MQTT_MAX_HEADER_SIZE-hlen),length+hlen);
|
rc = _client->write(buf+(MQTT_MAX_HEADER_SIZE-hlen),length+hlen);
|
||||||
|
|
||||||
|
// Start Tasmota patch
|
||||||
|
// lastOutActivity = millis();
|
||||||
|
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
lastOutActivity = millis();
|
lastOutActivity = millis();
|
||||||
}
|
}
|
||||||
|
// End Tasmota patch
|
||||||
|
|
||||||
return (rc == hlen+length);
|
return (rc == hlen+length);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -568,10 +708,14 @@ boolean PubSubClient::subscribe(const char* topic) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean PubSubClient::subscribe(const char* topic, uint8_t qos) {
|
boolean PubSubClient::subscribe(const char* topic, uint8_t qos) {
|
||||||
|
size_t topicLength = strnlen(topic, this->bufferSize);
|
||||||
|
if (topic == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (qos > 1) {
|
if (qos > 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (MQTT_MAX_PACKET_SIZE < 9 + strlen(topic)) {
|
if (this->bufferSize < 9 + topicLength) {
|
||||||
// Too long
|
// Too long
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -582,17 +726,21 @@ boolean PubSubClient::subscribe(const char* topic, uint8_t qos) {
|
|||||||
if (nextMsgId == 0) {
|
if (nextMsgId == 0) {
|
||||||
nextMsgId = 1;
|
nextMsgId = 1;
|
||||||
}
|
}
|
||||||
buffer[length++] = (nextMsgId >> 8);
|
this->buffer[length++] = (nextMsgId >> 8);
|
||||||
buffer[length++] = (nextMsgId & 0xFF);
|
this->buffer[length++] = (nextMsgId & 0xFF);
|
||||||
length = writeString((char*)topic, buffer,length);
|
length = writeString((char*)topic, this->buffer,length);
|
||||||
buffer[length++] = qos;
|
this->buffer[length++] = qos;
|
||||||
return write(MQTTSUBSCRIBE|MQTTQOS1,buffer,length-MQTT_MAX_HEADER_SIZE);
|
return write(MQTTSUBSCRIBE|MQTTQOS1,this->buffer,length-MQTT_MAX_HEADER_SIZE);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean PubSubClient::unsubscribe(const char* topic) {
|
boolean PubSubClient::unsubscribe(const char* topic) {
|
||||||
if (MQTT_MAX_PACKET_SIZE < 9 + strlen(topic)) {
|
size_t topicLength = strnlen(topic, this->bufferSize);
|
||||||
|
if (topic == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this->bufferSize < 9 + topicLength) {
|
||||||
// Too long
|
// Too long
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -602,25 +750,34 @@ boolean PubSubClient::unsubscribe(const char* topic) {
|
|||||||
if (nextMsgId == 0) {
|
if (nextMsgId == 0) {
|
||||||
nextMsgId = 1;
|
nextMsgId = 1;
|
||||||
}
|
}
|
||||||
buffer[length++] = (nextMsgId >> 8);
|
this->buffer[length++] = (nextMsgId >> 8);
|
||||||
buffer[length++] = (nextMsgId & 0xFF);
|
this->buffer[length++] = (nextMsgId & 0xFF);
|
||||||
length = writeString(topic, buffer,length);
|
length = writeString(topic, this->buffer,length);
|
||||||
return write(MQTTUNSUBSCRIBE|MQTTQOS1,buffer,length-MQTT_MAX_HEADER_SIZE);
|
return write(MQTTUNSUBSCRIBE|MQTTQOS1,this->buffer,length-MQTT_MAX_HEADER_SIZE);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PubSubClient::disconnect(bool disconnect_package) {
|
void PubSubClient::disconnect(bool disconnect_package) {
|
||||||
buffer[0] = MQTTDISCONNECT;
|
this->buffer[0] = MQTTDISCONNECT;
|
||||||
buffer[1] = 0;
|
this->buffer[1] = 0;
|
||||||
|
|
||||||
|
// Start Tasmota patch
|
||||||
|
// _client->write(this->buffer,2);
|
||||||
|
// _state = MQTT_DISCONNECTED;
|
||||||
|
// _client->flush();
|
||||||
|
// _client->stop();
|
||||||
|
|
||||||
if (_client != nullptr) {
|
if (_client != nullptr) {
|
||||||
if (disconnect_package) {
|
if (disconnect_package) {
|
||||||
_client->write(buffer,2);
|
_client->write(this->buffer,2);
|
||||||
}
|
}
|
||||||
_client->flush();
|
_client->flush();
|
||||||
_client->stop();
|
_client->stop();
|
||||||
}
|
}
|
||||||
_state = MQTT_DISCONNECTED;
|
_state = MQTT_DISCONNECTED;
|
||||||
|
// End Tasmota patch
|
||||||
|
|
||||||
lastInActivity = lastOutActivity = millis();
|
lastInActivity = lastOutActivity = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -628,7 +785,7 @@ uint16_t PubSubClient::writeString(const char* string, uint8_t* buf, uint16_t po
|
|||||||
const char* idp = string;
|
const char* idp = string;
|
||||||
uint16_t i = 0;
|
uint16_t i = 0;
|
||||||
pos += 2;
|
pos += 2;
|
||||||
while (*idp && pos < (MQTT_MAX_PACKET_SIZE - 2)) {
|
while (*idp) {
|
||||||
buf[pos++] = *idp++;
|
buf[pos++] = *idp++;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
@ -639,19 +796,27 @@ uint16_t PubSubClient::writeString(const char* string, uint8_t* buf, uint16_t po
|
|||||||
|
|
||||||
|
|
||||||
boolean PubSubClient::connected() {
|
boolean PubSubClient::connected() {
|
||||||
|
boolean rc;
|
||||||
if (_client == NULL ) {
|
if (_client == NULL ) {
|
||||||
|
|
||||||
|
// Start Tasmota patch
|
||||||
this->_state = MQTT_DISCONNECTED;
|
this->_state = MQTT_DISCONNECTED;
|
||||||
return false;
|
// End Tasmota patch
|
||||||
}
|
|
||||||
if (_client->connected() == 0) {
|
rc = false;
|
||||||
bool lastStateConnected = this->_state == MQTT_CONNECTED;
|
} else {
|
||||||
this->disconnect();
|
rc = (int)_client->connected();
|
||||||
if (lastStateConnected) {
|
if (!rc) {
|
||||||
|
if (this->_state == MQTT_CONNECTED) {
|
||||||
this->_state = MQTT_CONNECTION_LOST;
|
this->_state = MQTT_CONNECTION_LOST;
|
||||||
|
_client->flush();
|
||||||
|
_client->stop();
|
||||||
}
|
}
|
||||||
return false;
|
} else {
|
||||||
}
|
|
||||||
return this->_state == MQTT_CONNECTED;
|
return this->_state == MQTT_CONNECTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
PubSubClient& PubSubClient::setServer(uint8_t * ip, uint16_t port) {
|
PubSubClient& PubSubClient::setServer(uint8_t * ip, uint16_t port) {
|
||||||
@ -662,7 +827,13 @@ PubSubClient& PubSubClient::setServer(uint8_t * ip, uint16_t port) {
|
|||||||
PubSubClient& PubSubClient::setServer(IPAddress ip, uint16_t port) {
|
PubSubClient& PubSubClient::setServer(IPAddress ip, uint16_t port) {
|
||||||
this->ip = ip;
|
this->ip = ip;
|
||||||
this->port = port;
|
this->port = port;
|
||||||
|
|
||||||
|
// Start Tasmota patch
|
||||||
|
// this->domain = NULL;
|
||||||
|
|
||||||
this->domain = "";
|
this->domain = "";
|
||||||
|
// End Tasmota patch
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -690,3 +861,34 @@ PubSubClient& PubSubClient::setStream(Stream& stream){
|
|||||||
int PubSubClient::state() {
|
int PubSubClient::state() {
|
||||||
return this->_state;
|
return this->_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean PubSubClient::setBufferSize(uint16_t size) {
|
||||||
|
if (size == 0) {
|
||||||
|
// Cannot set it back to 0
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this->bufferSize == 0) {
|
||||||
|
this->buffer = (uint8_t*)malloc(size);
|
||||||
|
} else {
|
||||||
|
uint8_t* newBuffer = (uint8_t*)realloc(this->buffer, size);
|
||||||
|
if (newBuffer != NULL) {
|
||||||
|
this->buffer = newBuffer;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->bufferSize = size;
|
||||||
|
return (this->buffer != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t PubSubClient::getBufferSize() {
|
||||||
|
return this->bufferSize;
|
||||||
|
}
|
||||||
|
PubSubClient& PubSubClient::setKeepAlive(uint16_t keepAlive) {
|
||||||
|
this->keepAlive = keepAlive;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
PubSubClient& PubSubClient::setSocketTimeout(uint16_t timeout) {
|
||||||
|
this->socketTimeout = timeout;
|
||||||
|
return *this;
|
||||||
|
}
|
@ -21,24 +21,20 @@
|
|||||||
#define MQTT_VERSION MQTT_VERSION_3_1_1
|
#define MQTT_VERSION MQTT_VERSION_3_1_1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// MQTT_MAX_PACKET_SIZE : Maximum packet size
|
// MQTT_MAX_PACKET_SIZE : Maximum packet size. Override with setBufferSize().
|
||||||
#ifndef MQTT_MAX_PACKET_SIZE
|
#ifndef MQTT_MAX_PACKET_SIZE
|
||||||
//#define MQTT_MAX_PACKET_SIZE 128
|
//#define MQTT_MAX_PACKET_SIZE 256
|
||||||
//#define MQTT_MAX_PACKET_SIZE 1000 // Tasmota v5.11.1c
|
|
||||||
#define MQTT_MAX_PACKET_SIZE 1200 // Tasmota v8.1.0.8
|
#define MQTT_MAX_PACKET_SIZE 1200 // Tasmota v8.1.0.8
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// MQTT_KEEPALIVE : keepAlive interval in Seconds
|
// MQTT_KEEPALIVE : keepAlive interval in Seconds. Override with setKeepAlive()
|
||||||
// Keepalive timeout for default MQTT Broker is 10s
|
|
||||||
#ifndef MQTT_KEEPALIVE
|
#ifndef MQTT_KEEPALIVE
|
||||||
//#define MQTT_KEEPALIVE 10
|
#define MQTT_KEEPALIVE 15
|
||||||
#define MQTT_KEEPALIVE 30 // Tasmota v6.5.0.14 enabling AWS-iot
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// MQTT_SOCKET_TIMEOUT: socket timeout interval in Seconds
|
// MQTT_SOCKET_TIMEOUT: socket timeout interval in Seconds. Override with setSocketTimeout()
|
||||||
#ifndef MQTT_SOCKET_TIMEOUT
|
#ifndef MQTT_SOCKET_TIMEOUT
|
||||||
//#define MQTT_SOCKET_TIMEOUT 15
|
#define MQTT_SOCKET_TIMEOUT 15
|
||||||
#define MQTT_SOCKET_TIMEOUT 4 // Tasmota 20210120
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// MQTT_MAX_TRANSFER_SIZE : limit how much data is passed to the network client
|
// MQTT_MAX_TRANSFER_SIZE : limit how much data is passed to the network client
|
||||||
@ -88,18 +84,21 @@
|
|||||||
#define MQTT_CALLBACK_SIGNATURE void (*callback)(char*, uint8_t*, unsigned int)
|
#define MQTT_CALLBACK_SIGNATURE void (*callback)(char*, uint8_t*, unsigned int)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CHECK_STRING_LENGTH(l,s) if (l+2+strlen(s) > MQTT_MAX_PACKET_SIZE) {_client->stop();return false;}
|
#define CHECK_STRING_LENGTH(l,s) if (l+2+strnlen(s, this->bufferSize) > this->bufferSize) {_client->stop();return false;}
|
||||||
|
|
||||||
class PubSubClient : public Print {
|
class PubSubClient : public Print {
|
||||||
private:
|
private:
|
||||||
Client* _client;
|
Client* _client;
|
||||||
uint8_t buffer[MQTT_MAX_PACKET_SIZE];
|
uint8_t* buffer;
|
||||||
|
uint16_t bufferSize;
|
||||||
|
uint16_t keepAlive;
|
||||||
|
uint16_t socketTimeout;
|
||||||
uint16_t nextMsgId;
|
uint16_t nextMsgId;
|
||||||
unsigned long lastOutActivity;
|
unsigned long lastOutActivity;
|
||||||
unsigned long lastInActivity;
|
unsigned long lastInActivity;
|
||||||
bool pingOutstanding;
|
bool pingOutstanding;
|
||||||
MQTT_CALLBACK_SIGNATURE;
|
MQTT_CALLBACK_SIGNATURE;
|
||||||
uint16_t readPacket(uint8_t*);
|
uint32_t readPacket(uint8_t*);
|
||||||
boolean readByte(uint8_t * result);
|
boolean readByte(uint8_t * result);
|
||||||
boolean readByte(uint8_t * result, uint16_t * index);
|
boolean readByte(uint8_t * result, uint16_t * index);
|
||||||
boolean write(uint8_t header, uint8_t* buf, uint16_t length);
|
boolean write(uint8_t header, uint8_t* buf, uint16_t length);
|
||||||
@ -110,7 +109,13 @@ private:
|
|||||||
// (MQTT_MAX_HEADER_SIZE - <returned size>) bytes into the buffer
|
// (MQTT_MAX_HEADER_SIZE - <returned size>) bytes into the buffer
|
||||||
size_t buildHeader(uint8_t header, uint8_t* buf, uint16_t length);
|
size_t buildHeader(uint8_t header, uint8_t* buf, uint16_t length);
|
||||||
IPAddress ip;
|
IPAddress ip;
|
||||||
|
|
||||||
|
// Start Tasmota patch
|
||||||
|
// const char* domain;
|
||||||
|
|
||||||
String domain;
|
String domain;
|
||||||
|
// End Tasmota patch
|
||||||
|
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
Stream* stream;
|
Stream* stream;
|
||||||
int _state;
|
int _state;
|
||||||
@ -129,7 +134,8 @@ public:
|
|||||||
PubSubClient(const char*, uint16_t, Client& client, Stream&);
|
PubSubClient(const char*, uint16_t, Client& client, Stream&);
|
||||||
PubSubClient(const char*, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client);
|
PubSubClient(const char*, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client);
|
||||||
PubSubClient(const char*, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&);
|
PubSubClient(const char*, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&);
|
||||||
virtual ~PubSubClient() {}
|
|
||||||
|
~PubSubClient();
|
||||||
|
|
||||||
PubSubClient& setServer(IPAddress ip, uint16_t port);
|
PubSubClient& setServer(IPAddress ip, uint16_t port);
|
||||||
PubSubClient& setServer(uint8_t * ip, uint16_t port);
|
PubSubClient& setServer(uint8_t * ip, uint16_t port);
|
||||||
@ -137,13 +143,24 @@ public:
|
|||||||
PubSubClient& setCallback(MQTT_CALLBACK_SIGNATURE);
|
PubSubClient& setCallback(MQTT_CALLBACK_SIGNATURE);
|
||||||
PubSubClient& setClient(Client& client);
|
PubSubClient& setClient(Client& client);
|
||||||
PubSubClient& setStream(Stream& stream);
|
PubSubClient& setStream(Stream& stream);
|
||||||
|
PubSubClient& setKeepAlive(uint16_t keepAlive);
|
||||||
|
PubSubClient& setSocketTimeout(uint16_t timeout);
|
||||||
|
|
||||||
|
boolean setBufferSize(uint16_t size);
|
||||||
|
uint16_t getBufferSize();
|
||||||
|
|
||||||
boolean connect(const char* id);
|
boolean connect(const char* id);
|
||||||
boolean connect(const char* id, const char* user, const char* pass);
|
boolean connect(const char* id, const char* user, const char* pass);
|
||||||
boolean connect(const char* id, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage);
|
boolean connect(const char* id, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage);
|
||||||
boolean connect(const char* id, const char* user, const char* pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage);
|
boolean connect(const char* id, const char* user, const char* pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage);
|
||||||
boolean connect(const char* id, const char* user, const char* pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage, boolean cleanSession);
|
boolean connect(const char* id, const char* user, const char* pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage, boolean cleanSession);
|
||||||
|
|
||||||
|
// Start Tasmota patch
|
||||||
|
// void disconnect();
|
||||||
|
|
||||||
void disconnect(bool disconnect_package = false);
|
void disconnect(bool disconnect_package = false);
|
||||||
|
// End Tasmota patch
|
||||||
|
|
||||||
boolean publish(const char* topic, const char* payload);
|
boolean publish(const char* topic, const char* payload);
|
||||||
boolean publish(const char* topic, const char* payload, boolean retained);
|
boolean publish(const char* topic, const char* payload, boolean retained);
|
||||||
boolean publish(const char* topic, const uint8_t * payload, unsigned int plength);
|
boolean publish(const char* topic, const uint8_t * payload, unsigned int plength);
|
||||||
@ -173,6 +190,7 @@ public:
|
|||||||
boolean loop();
|
boolean loop();
|
||||||
boolean connected();
|
boolean connected();
|
||||||
int state();
|
int state();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -280,6 +280,38 @@ int test_connect_disconnect_connect() {
|
|||||||
END_IT
|
END_IT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int test_connect_custom_keepalive() {
|
||||||
|
IT("sends a properly formatted connect packet with custom keepalive value");
|
||||||
|
ShimClient shimClient;
|
||||||
|
|
||||||
|
shimClient.setAllowConnect(true);
|
||||||
|
byte expectServer[] = { 172, 16, 0, 2 };
|
||||||
|
shimClient.expectConnect(expectServer,1883);
|
||||||
|
|
||||||
|
// Set keepalive to 300secs == 0x01 0x2c
|
||||||
|
byte connect[] = {0x10,0x18,0x0,0x4,0x4d,0x51,0x54,0x54,0x4,0x2,0x01,0x2c,0x0,0xc,0x63,0x6c,0x69,0x65,0x6e,0x74,0x5f,0x74,0x65,0x73,0x74,0x31};
|
||||||
|
byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
|
||||||
|
|
||||||
|
shimClient.expect(connect,26);
|
||||||
|
shimClient.respond(connack,4);
|
||||||
|
|
||||||
|
PubSubClient client(server, 1883, callback, shimClient);
|
||||||
|
int state = client.state();
|
||||||
|
IS_TRUE(state == MQTT_DISCONNECTED);
|
||||||
|
|
||||||
|
client.setKeepAlive(300);
|
||||||
|
|
||||||
|
int rc = client.connect((char*)"client_test1");
|
||||||
|
IS_TRUE(rc);
|
||||||
|
IS_FALSE(shimClient.error());
|
||||||
|
|
||||||
|
state = client.state();
|
||||||
|
IS_TRUE(state == MQTT_CONNECTED);
|
||||||
|
|
||||||
|
END_IT
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
SUITE("Connect");
|
SUITE("Connect");
|
||||||
@ -298,5 +330,7 @@ int main()
|
|||||||
test_connect_with_will();
|
test_connect_with_will();
|
||||||
test_connect_with_will_username_password();
|
test_connect_with_will_username_password();
|
||||||
test_connect_disconnect_connect();
|
test_connect_disconnect_connect();
|
||||||
|
|
||||||
|
test_connect_custom_keepalive();
|
||||||
FINISH
|
FINISH
|
||||||
}
|
}
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
class Buffer {
|
class Buffer {
|
||||||
private:
|
private:
|
||||||
uint8_t buffer[1024];
|
uint8_t buffer[2048];
|
||||||
uint16_t pos;
|
uint16_t pos;
|
||||||
uint16_t length;
|
uint16_t length;
|
||||||
|
|
@ -134,6 +134,7 @@ int test_publish_too_long() {
|
|||||||
shimClient.respond(connack,4);
|
shimClient.respond(connack,4);
|
||||||
|
|
||||||
PubSubClient client(server, 1883, callback, shimClient);
|
PubSubClient client(server, 1883, callback, shimClient);
|
||||||
|
client.setBufferSize(128);
|
||||||
int rc = client.connect((char*)"client_test1");
|
int rc = client.connect((char*)"client_test1");
|
||||||
IS_TRUE(rc);
|
IS_TRUE(rc);
|
||||||
|
|
@ -20,6 +20,7 @@ void reset_callback() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void callback(char* topic, byte* payload, unsigned int length) {
|
void callback(char* topic, byte* payload, unsigned int length) {
|
||||||
|
TRACE("Callback received topic=[" << topic << "] length=" << length << "\n")
|
||||||
callback_called = true;
|
callback_called = true;
|
||||||
strcpy(lastTopic,topic);
|
strcpy(lastTopic,topic);
|
||||||
memcpy(lastPayload,payload,length);
|
memcpy(lastPayload,payload,length);
|
||||||
@ -102,10 +103,15 @@ int test_receive_max_sized_message() {
|
|||||||
shimClient.respond(connack,4);
|
shimClient.respond(connack,4);
|
||||||
|
|
||||||
PubSubClient client(server, 1883, callback, shimClient);
|
PubSubClient client(server, 1883, callback, shimClient);
|
||||||
|
int length = 80; // If this is changed to > 128 then the publish packet below
|
||||||
|
// is no longer valid as it assumes the remaining length
|
||||||
|
// is a single-byte. Don't make that mistake like I just
|
||||||
|
// did and lose a whole evening tracking down the issue.
|
||||||
|
client.setBufferSize(length);
|
||||||
int rc = client.connect((char*)"client_test1");
|
int rc = client.connect((char*)"client_test1");
|
||||||
IS_TRUE(rc);
|
IS_TRUE(rc);
|
||||||
|
|
||||||
int length = MQTT_MAX_PACKET_SIZE;
|
|
||||||
byte publish[] = {0x30,length-2,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64};
|
byte publish[] = {0x30,length-2,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64};
|
||||||
byte bigPublish[length];
|
byte bigPublish[length];
|
||||||
memset(bigPublish,'A',length);
|
memset(bigPublish,'A',length);
|
||||||
@ -137,11 +143,13 @@ int test_receive_oversized_message() {
|
|||||||
byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
|
byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
|
||||||
shimClient.respond(connack,4);
|
shimClient.respond(connack,4);
|
||||||
|
|
||||||
|
int length = 80; // See comment in test_receive_max_sized_message before changing this value
|
||||||
|
|
||||||
PubSubClient client(server, 1883, callback, shimClient);
|
PubSubClient client(server, 1883, callback, shimClient);
|
||||||
|
client.setBufferSize(length-1);
|
||||||
int rc = client.connect((char*)"client_test1");
|
int rc = client.connect((char*)"client_test1");
|
||||||
IS_TRUE(rc);
|
IS_TRUE(rc);
|
||||||
|
|
||||||
int length = MQTT_MAX_PACKET_SIZE+1;
|
|
||||||
byte publish[] = {0x30,length-2,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64};
|
byte publish[] = {0x30,length-2,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64};
|
||||||
byte bigPublish[length];
|
byte bigPublish[length];
|
||||||
memset(bigPublish,'A',length);
|
memset(bigPublish,'A',length);
|
||||||
@ -188,9 +196,58 @@ int test_drop_invalid_remaining_length_message() {
|
|||||||
END_IT
|
END_IT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int test_resize_buffer() {
|
||||||
|
IT("receives a message larger than the default maximum");
|
||||||
|
reset_callback();
|
||||||
|
|
||||||
|
ShimClient shimClient;
|
||||||
|
shimClient.setAllowConnect(true);
|
||||||
|
|
||||||
|
byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
|
||||||
|
shimClient.respond(connack,4);
|
||||||
|
|
||||||
|
int length = 80; // See comment in test_receive_max_sized_message before changing this value
|
||||||
|
|
||||||
|
PubSubClient client(server, 1883, callback, shimClient);
|
||||||
|
client.setBufferSize(length-1);
|
||||||
|
int rc = client.connect((char*)"client_test1");
|
||||||
|
IS_TRUE(rc);
|
||||||
|
|
||||||
|
byte publish[] = {0x30,length-2,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64};
|
||||||
|
byte bigPublish[length];
|
||||||
|
memset(bigPublish,'A',length);
|
||||||
|
bigPublish[length] = 'B';
|
||||||
|
memcpy(bigPublish,publish,16);
|
||||||
|
// Send it twice
|
||||||
|
shimClient.respond(bigPublish,length);
|
||||||
|
shimClient.respond(bigPublish,length);
|
||||||
|
|
||||||
|
rc = client.loop();
|
||||||
|
IS_TRUE(rc);
|
||||||
|
|
||||||
|
// First message fails as it is too big
|
||||||
|
IS_FALSE(callback_called);
|
||||||
|
|
||||||
|
// Resize the buffer
|
||||||
|
client.setBufferSize(length);
|
||||||
|
|
||||||
|
rc = client.loop();
|
||||||
|
IS_TRUE(rc);
|
||||||
|
|
||||||
|
IS_TRUE(callback_called);
|
||||||
|
|
||||||
|
IS_TRUE(strcmp(lastTopic,"topic")==0);
|
||||||
|
IS_TRUE(lastLength == length-9);
|
||||||
|
IS_TRUE(memcmp(lastPayload,bigPublish+9,lastLength)==0);
|
||||||
|
|
||||||
|
IS_FALSE(shimClient.error());
|
||||||
|
|
||||||
|
END_IT
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int test_receive_oversized_stream_message() {
|
int test_receive_oversized_stream_message() {
|
||||||
IT("drops an oversized message");
|
IT("receive an oversized streamed message");
|
||||||
reset_callback();
|
reset_callback();
|
||||||
|
|
||||||
Stream stream;
|
Stream stream;
|
||||||
@ -201,11 +258,13 @@ int test_receive_oversized_stream_message() {
|
|||||||
byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
|
byte connack[] = { 0x20, 0x02, 0x00, 0x00 };
|
||||||
shimClient.respond(connack,4);
|
shimClient.respond(connack,4);
|
||||||
|
|
||||||
|
int length = 80; // See comment in test_receive_max_sized_message before changing this value
|
||||||
|
|
||||||
PubSubClient client(server, 1883, callback, shimClient, stream);
|
PubSubClient client(server, 1883, callback, shimClient, stream);
|
||||||
|
client.setBufferSize(length-1);
|
||||||
int rc = client.connect((char*)"client_test1");
|
int rc = client.connect((char*)"client_test1");
|
||||||
IS_TRUE(rc);
|
IS_TRUE(rc);
|
||||||
|
|
||||||
int length = MQTT_MAX_PACKET_SIZE+1;
|
|
||||||
byte publish[] = {0x30,length-2,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64};
|
byte publish[] = {0x30,length-2,0x0,0x5,0x74,0x6f,0x70,0x69,0x63,0x70,0x61,0x79,0x6c,0x6f,0x61,0x64};
|
||||||
|
|
||||||
byte bigPublish[length];
|
byte bigPublish[length];
|
||||||
@ -222,7 +281,8 @@ int test_receive_oversized_stream_message() {
|
|||||||
|
|
||||||
IS_TRUE(callback_called);
|
IS_TRUE(callback_called);
|
||||||
IS_TRUE(strcmp(lastTopic,"topic")==0);
|
IS_TRUE(strcmp(lastTopic,"topic")==0);
|
||||||
IS_TRUE(lastLength == length-9);
|
|
||||||
|
IS_TRUE(lastLength == length-10);
|
||||||
|
|
||||||
IS_FALSE(stream.error());
|
IS_FALSE(stream.error());
|
||||||
IS_FALSE(shimClient.error());
|
IS_FALSE(shimClient.error());
|
||||||
@ -272,6 +332,7 @@ int main()
|
|||||||
test_receive_max_sized_message();
|
test_receive_max_sized_message();
|
||||||
test_drop_invalid_remaining_length_message();
|
test_drop_invalid_remaining_length_message();
|
||||||
test_receive_oversized_message();
|
test_receive_oversized_message();
|
||||||
|
test_resize_buffer();
|
||||||
test_receive_oversized_stream_message();
|
test_receive_oversized_stream_message();
|
||||||
test_receive_qos1();
|
test_receive_qos1();
|
||||||
|
|
@ -106,6 +106,7 @@ int test_subscribe_too_long() {
|
|||||||
shimClient.respond(connack,4);
|
shimClient.respond(connack,4);
|
||||||
|
|
||||||
PubSubClient client(server, 1883, callback, shimClient);
|
PubSubClient client(server, 1883, callback, shimClient);
|
||||||
|
client.setBufferSize(128);
|
||||||
int rc = client.connect((char*)"client_test1");
|
int rc = client.connect((char*)"client_test1");
|
||||||
IS_TRUE(rc);
|
IS_TRUE(rc);
|
||||||
|
|
@ -366,6 +366,8 @@
|
|||||||
#define D_CMND_MQTTCLIENT "MqttClient"
|
#define D_CMND_MQTTCLIENT "MqttClient"
|
||||||
#define D_CMND_MQTTUSER "MqttUser"
|
#define D_CMND_MQTTUSER "MqttUser"
|
||||||
#define D_CMND_MQTTPASSWORD "MqttPassword"
|
#define D_CMND_MQTTPASSWORD "MqttPassword"
|
||||||
|
#define D_CMND_MQTTKEEPALIVE "MqttKeepAlive"
|
||||||
|
#define D_CMND_MQTTTIMEOUT "MqttTimeout"
|
||||||
#define D_CMND_TLSKEY "TLSKey"
|
#define D_CMND_TLSKEY "TLSKey"
|
||||||
#define D_CMND_FULLTOPIC "FullTopic"
|
#define D_CMND_FULLTOPIC "FullTopic"
|
||||||
#define D_CMND_PREFIX "Prefix"
|
#define D_CMND_PREFIX "Prefix"
|
||||||
|
@ -101,6 +101,9 @@
|
|||||||
// -- MQTT ----------------------------------------
|
// -- MQTT ----------------------------------------
|
||||||
#define MQTT_USE true // [SetOption3] Select default MQTT use (false = Off, true = On)
|
#define MQTT_USE true // [SetOption3] Select default MQTT use (false = Off, true = On)
|
||||||
|
|
||||||
|
#define MQTT_KEEPALIVE 30 // [MqttKeepAlive]
|
||||||
|
#define MQTT_SOCKET_TIMEOUT 4 // [MqttTimeout]
|
||||||
|
|
||||||
#define MQTT_HOST "" // [MqttHost]
|
#define MQTT_HOST "" // [MqttHost]
|
||||||
#define MQTT_FINGERPRINT1 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 // [MqttFingerprint1] (auto-learn)
|
#define MQTT_FINGERPRINT1 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 // [MqttFingerprint1] (auto-learn)
|
||||||
#define MQTT_FINGERPRINT2 0xDA,0x39,0xA3,0xEE,0x5E,0x6B,0x4B,0x0D,0x32,0x55,0xBF,0xEF,0x95,0x60,0x18,0x90,0xAF,0xD8,0x07,0x09 // [MqttFingerprint2] (invalid)
|
#define MQTT_FINGERPRINT2 0xDA,0x39,0xA3,0xEE,0x5E,0x6B,0x4B,0x0D,0x32,0x55,0xBF,0xEF,0x95,0x60,0x18,0x90,0xAF,0xD8,0x07,0x09 // [MqttFingerprint2] (invalid)
|
||||||
|
@ -488,7 +488,12 @@ struct {
|
|||||||
|
|
||||||
power_t interlock[MAX_INTERLOCKS_SET]; // 4D0 MAX_INTERLOCKS = MAX_RELAYS / 2
|
power_t interlock[MAX_INTERLOCKS_SET]; // 4D0 MAX_INTERLOCKS = MAX_RELAYS / 2
|
||||||
|
|
||||||
uint8_t free_508[41]; // 508
|
uint8_t free_508[36]; // 508
|
||||||
|
|
||||||
|
uint16_t mqtt_keepalive; // 52C
|
||||||
|
uint16_t mqtt_socket_timeout; // 52E
|
||||||
|
|
||||||
|
uint8_t free_530[1]; // 530
|
||||||
|
|
||||||
uint8_t ina219_mode; // 531
|
uint8_t ina219_mode; // 531
|
||||||
uint16_t pulse_timer[MAX_PULSETIMERS]; // 532
|
uint16_t pulse_timer[MAX_PULSETIMERS]; // 532
|
||||||
|
@ -864,6 +864,8 @@ void SettingsDefaultSet2(void) {
|
|||||||
memcpy_P(Settings.mqtt_fingerprint[1], default_fingerprint2, sizeof(default_fingerprint2));
|
memcpy_P(Settings.mqtt_fingerprint[1], default_fingerprint2, sizeof(default_fingerprint2));
|
||||||
Settings.tele_period = TELE_PERIOD;
|
Settings.tele_period = TELE_PERIOD;
|
||||||
Settings.mqttlog_level = MQTT_LOG_LEVEL;
|
Settings.mqttlog_level = MQTT_LOG_LEVEL;
|
||||||
|
Settings.mqtt_keepalive = MQTT_KEEPALIVE;
|
||||||
|
Settings.mqtt_socket_timeout = MQTT_SOCKET_TIMEOUT;
|
||||||
|
|
||||||
// Energy
|
// Energy
|
||||||
flag.no_power_on_check |= ENERGY_VOLTAGE_ALWAYS;
|
flag.no_power_on_check |= ENERGY_VOLTAGE_ALWAYS;
|
||||||
@ -1244,6 +1246,10 @@ void SettingsDelta(void) {
|
|||||||
if (Settings.version < 0x09020007) {
|
if (Settings.version < 0x09020007) {
|
||||||
*(uint32_t *)&Settings.device_group_tie = 0x04030201;
|
*(uint32_t *)&Settings.device_group_tie = 0x04030201;
|
||||||
}
|
}
|
||||||
|
if (Settings.version < 0x09030102) {
|
||||||
|
Settings.mqtt_keepalive = MQTT_KEEPALIVE;
|
||||||
|
Settings.mqtt_socket_timeout = MQTT_SOCKET_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
Settings.version = VERSION;
|
Settings.version = VERSION;
|
||||||
SettingsSave(1);
|
SettingsSave(1);
|
||||||
|
@ -2125,7 +2125,7 @@ void SyslogAsync(bool refresh) {
|
|||||||
static uint32_t syslog_host_hash = 0; // Syslog host name hash
|
static uint32_t syslog_host_hash = 0; // Syslog host name hash
|
||||||
static uint32_t index = 1;
|
static uint32_t index = 1;
|
||||||
|
|
||||||
if (!TasmotaGlobal.syslog_level) { return; }
|
if (!TasmotaGlobal.syslog_level || TasmotaGlobal.global_state.network_down) { return; }
|
||||||
if (refresh && !NeedLogRefresh(TasmotaGlobal.syslog_level, index)) { return; }
|
if (refresh && !NeedLogRefresh(TasmotaGlobal.syslog_level, index)) { return; }
|
||||||
|
|
||||||
char* line;
|
char* line;
|
||||||
@ -2137,8 +2137,16 @@ void SyslogAsync(bool refresh) {
|
|||||||
if (mxtime > 0) {
|
if (mxtime > 0) {
|
||||||
uint32_t current_hash = GetHash(SettingsText(SET_SYSLOG_HOST), strlen(SettingsText(SET_SYSLOG_HOST)));
|
uint32_t current_hash = GetHash(SettingsText(SET_SYSLOG_HOST), strlen(SettingsText(SET_SYSLOG_HOST)));
|
||||||
if (syslog_host_hash != current_hash) {
|
if (syslog_host_hash != current_hash) {
|
||||||
|
IPAddress temp_syslog_host_addr;
|
||||||
|
int ok = WiFi.hostByName(SettingsText(SET_SYSLOG_HOST), temp_syslog_host_addr); // If sleep enabled this might result in exception so try to do it once using hash
|
||||||
|
if (!ok || (0xFFFFFFFF == (uint32_t)temp_syslog_host_addr)) { // 255.255.255.255 is assumed a DNS problem
|
||||||
|
TasmotaGlobal.syslog_level = 0;
|
||||||
|
TasmotaGlobal.syslog_timer = SYSLOG_TIMER;
|
||||||
|
AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION "Loghost DNS resolve failed (%s). " D_RETRY_IN " %d " D_UNIT_SECOND), SettingsText(SET_SYSLOG_HOST), SYSLOG_TIMER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
syslog_host_hash = current_hash;
|
syslog_host_hash = current_hash;
|
||||||
WiFi.hostByName(SettingsText(SET_SYSLOG_HOST), syslog_host_addr); // If sleep enabled this might result in exception so try to do it once using hash
|
syslog_host_addr = temp_syslog_host_addr;
|
||||||
}
|
}
|
||||||
if (!PortUdp.beginPacket(syslog_host_addr, Settings.syslog_port)) {
|
if (!PortUdp.beginPacket(syslog_host_addr, Settings.syslog_port)) {
|
||||||
TasmotaGlobal.syslog_level = 0;
|
TasmotaGlobal.syslog_level = 0;
|
||||||
|
@ -529,9 +529,9 @@ void CmndStatus(void)
|
|||||||
|
|
||||||
if (((0 == payload) || (6 == payload)) && Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT
|
if (((0 == payload) || (6 == payload)) && Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT
|
||||||
Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS6_MQTT "\":{\"" D_CMND_MQTTHOST "\":\"%s\",\"" D_CMND_MQTTPORT "\":%d,\"" D_CMND_MQTTCLIENT D_JSON_MASK "\":\"%s\",\""
|
Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS6_MQTT "\":{\"" D_CMND_MQTTHOST "\":\"%s\",\"" D_CMND_MQTTPORT "\":%d,\"" D_CMND_MQTTCLIENT D_JSON_MASK "\":\"%s\",\""
|
||||||
D_CMND_MQTTCLIENT "\":\"%s\",\"" D_CMND_MQTTUSER "\":\"%s\",\"" D_JSON_MQTT_COUNT "\":%d,\"MAX_PACKET_SIZE\":%d,\"KEEPALIVE\":%d}}"),
|
D_CMND_MQTTCLIENT "\":\"%s\",\"" D_CMND_MQTTUSER "\":\"%s\",\"" D_JSON_MQTT_COUNT "\":%d,\"MAX_PACKET_SIZE\":%d,\"KEEPALIVE\":%d,\"SOCKET_TIMEOUT\":%d}}"),
|
||||||
SettingsText(SET_MQTT_HOST), Settings.mqtt_port, EscapeJSONString(SettingsText(SET_MQTT_CLIENT)).c_str(),
|
SettingsText(SET_MQTT_HOST), Settings.mqtt_port, EscapeJSONString(SettingsText(SET_MQTT_CLIENT)).c_str(),
|
||||||
TasmotaGlobal.mqtt_client, EscapeJSONString(SettingsText(SET_MQTT_USER)).c_str(), MqttConnectCount(), MQTT_MAX_PACKET_SIZE, MQTT_KEEPALIVE);
|
TasmotaGlobal.mqtt_client, EscapeJSONString(SettingsText(SET_MQTT_USER)).c_str(), MqttConnectCount(), MQTT_MAX_PACKET_SIZE, Settings.mqtt_keepalive, Settings.mqtt_socket_timeout);
|
||||||
MqttPublishPrefixTopic_P(STAT, PSTR(D_CMND_STATUS "6"));
|
MqttPublishPrefixTopic_P(STAT, PSTR(D_CMND_STATUS "6"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,8 +270,8 @@ const uint16_t LOG_BUFFER_SIZE = 4000; // Max number of characters in lo
|
|||||||
#ifndef MQTT_KEEPALIVE
|
#ifndef MQTT_KEEPALIVE
|
||||||
#define MQTT_KEEPALIVE 30 // Seconds
|
#define MQTT_KEEPALIVE 30 // Seconds
|
||||||
#endif
|
#endif
|
||||||
#ifndef MQTT_TIMEOUT
|
#ifndef MQTT_SOCKET_TIMEOUT
|
||||||
#define MQTT_TIMEOUT 10000 // milli seconds
|
#define MQTT_SOCKET_TIMEOUT 4 // Seconds
|
||||||
#endif
|
#endif
|
||||||
#ifndef MQTT_CLEAN_SESSION
|
#ifndef MQTT_CLEAN_SESSION
|
||||||
#define MQTT_CLEAN_SESSION 1 // 0 = No clean session, 1 = Clean session (default)
|
#define MQTT_CLEAN_SESSION 1 // 0 = No clean session, 1 = Clean session (default)
|
||||||
|
@ -20,6 +20,6 @@
|
|||||||
#ifndef _TASMOTA_VERSION_H_
|
#ifndef _TASMOTA_VERSION_H_
|
||||||
#define _TASMOTA_VERSION_H_
|
#define _TASMOTA_VERSION_H_
|
||||||
|
|
||||||
const uint32_t VERSION = 0x09030101;
|
const uint32_t VERSION = 0x09030102;
|
||||||
|
|
||||||
#endif // _TASMOTA_VERSION_H_
|
#endif // _TASMOTA_VERSION_H_
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
#define MQTT_WIFI_CLIENT_TIMEOUT 200 // Wifi TCP connection timeout (default is 5000 mSec)
|
#define MQTT_WIFI_CLIENT_TIMEOUT 200 // Wifi TCP connection timeout (default is 5000 mSec)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define USE_MQTT_NEW_PUBSUBCLIENT
|
||||||
|
|
||||||
// #define DEBUG_DUMP_TLS // allow dumping of TLS Flash keys
|
// #define DEBUG_DUMP_TLS // allow dumping of TLS Flash keys
|
||||||
|
|
||||||
#ifdef USE_MQTT_TLS
|
#ifdef USE_MQTT_TLS
|
||||||
@ -42,7 +44,7 @@ const char kMqttCommands[] PROGMEM = "|" // No prefix
|
|||||||
#if defined(USE_MQTT_TLS) && !defined(USE_MQTT_TLS_CA_CERT)
|
#if defined(USE_MQTT_TLS) && !defined(USE_MQTT_TLS_CA_CERT)
|
||||||
D_CMND_MQTTFINGERPRINT "|"
|
D_CMND_MQTTFINGERPRINT "|"
|
||||||
#endif
|
#endif
|
||||||
D_CMND_MQTTUSER "|" D_CMND_MQTTPASSWORD "|"
|
D_CMND_MQTTUSER "|" D_CMND_MQTTPASSWORD "|" D_CMND_MQTTKEEPALIVE "|" D_CMND_MQTTTIMEOUT "|"
|
||||||
#if defined(USE_MQTT_TLS) && defined(USE_MQTT_AWS_IOT)
|
#if defined(USE_MQTT_TLS) && defined(USE_MQTT_AWS_IOT)
|
||||||
D_CMND_TLSKEY "|"
|
D_CMND_TLSKEY "|"
|
||||||
#endif
|
#endif
|
||||||
@ -68,7 +70,7 @@ void (* const MqttCommand[])(void) PROGMEM = {
|
|||||||
#if defined(USE_MQTT_TLS) && !defined(USE_MQTT_TLS_CA_CERT)
|
#if defined(USE_MQTT_TLS) && !defined(USE_MQTT_TLS_CA_CERT)
|
||||||
&CmndMqttFingerprint,
|
&CmndMqttFingerprint,
|
||||||
#endif
|
#endif
|
||||||
&CmndMqttUser, &CmndMqttPassword,
|
&CmndMqttUser, &CmndMqttPassword, &CmndMqttKeepAlive, &CmndMqttTimeout,
|
||||||
#if defined(USE_MQTT_TLS) && defined(USE_MQTT_AWS_IOT)
|
#if defined(USE_MQTT_TLS) && defined(USE_MQTT_AWS_IOT)
|
||||||
&CmndTlsKey,
|
&CmndTlsKey,
|
||||||
#endif
|
#endif
|
||||||
@ -209,6 +211,9 @@ void MqttInit(void) {
|
|||||||
#else // USE_MQTT_TLS
|
#else // USE_MQTT_TLS
|
||||||
MqttClient.setClient(EspClient);
|
MqttClient.setClient(EspClient);
|
||||||
#endif // USE_MQTT_TLS
|
#endif // USE_MQTT_TLS
|
||||||
|
|
||||||
|
MqttClient.setKeepAlive(Settings.mqtt_keepalive);
|
||||||
|
MqttClient.setSocketTimeout(Settings.mqtt_socket_timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MqttIsConnected(void) {
|
bool MqttIsConnected(void) {
|
||||||
@ -311,7 +316,7 @@ void MqttUnsubscribe(const char *topic) {
|
|||||||
void MqttPublishLoggingAsync(bool refresh) {
|
void MqttPublishLoggingAsync(bool refresh) {
|
||||||
static uint32_t index = 1;
|
static uint32_t index = 1;
|
||||||
|
|
||||||
if (!Settings.mqttlog_level || !Settings.flag.mqtt_enabled) { return; } // SetOption3 - Enable MQTT
|
if (!Settings.mqttlog_level || !Settings.flag.mqtt_enabled || !Mqtt.connected) { return; } // SetOption3 - Enable MQTT
|
||||||
if (refresh && !NeedLogRefresh(Settings.mqttlog_level, index)) { return; }
|
if (refresh && !NeedLogRefresh(Settings.mqttlog_level, index)) { return; }
|
||||||
|
|
||||||
char* line;
|
char* line;
|
||||||
@ -829,6 +834,26 @@ void CmndMqttPassword(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CmndMqttKeepAlive(void) {
|
||||||
|
if ((XdrvMailbox.payload >= 1) && (XdrvMailbox.payload <= 100)) {
|
||||||
|
Settings.mqtt_keepalive = XdrvMailbox.payload;
|
||||||
|
#ifdef USE_MQTT_NEW_PUBSUBCLIENT
|
||||||
|
MqttClient.setKeepAlive(Settings.mqtt_keepalive);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
ResponseCmndNumber(Settings.mqtt_keepalive);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CmndMqttTimeout(void) {
|
||||||
|
if ((XdrvMailbox.payload >= 1) && (XdrvMailbox.payload <= 100)) {
|
||||||
|
Settings.mqtt_socket_timeout = XdrvMailbox.payload;
|
||||||
|
#ifdef USE_MQTT_NEW_PUBSUBCLIENT
|
||||||
|
MqttClient.setSocketTimeout(Settings.mqtt_socket_timeout);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
ResponseCmndNumber(Settings.mqtt_socket_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
void CmndMqttlog(void) {
|
void CmndMqttlog(void) {
|
||||||
if ((XdrvMailbox.payload >= LOG_LEVEL_NONE) && (XdrvMailbox.payload <= LOG_LEVEL_DEBUG_MORE)) {
|
if ((XdrvMailbox.payload >= LOG_LEVEL_NONE) && (XdrvMailbox.payload <= LOG_LEVEL_DEBUG_MORE)) {
|
||||||
Settings.mqttlog_level = XdrvMailbox.payload;
|
Settings.mqttlog_level = XdrvMailbox.payload;
|
||||||
|
@ -57,6 +57,7 @@ String FormatMetricName(const char *metric) { // cleanup spaces and uppercases
|
|||||||
String formatted = metric;
|
String formatted = metric;
|
||||||
formatted.toLowerCase();
|
formatted.toLowerCase();
|
||||||
formatted.replace(" ", "_");
|
formatted.replace(" ", "_");
|
||||||
|
formatted.replace(".", "_");
|
||||||
return formatted;
|
return formatted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user