mirror of https://github.com/arendst/Tasmota.git
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
|
||||
|
||||
## [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]
|
||||
### Added
|
||||
- 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 support for WS2812 hardware driver via RMT or I2S
|
||||
- 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
|
||||
- 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.
|
||||
|
||||
## Changelog v9.3.1.1
|
||||
## Changelog v9.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](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)
|
||||
- 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)
|
||||
|
@ -93,6 +94,7 @@ The attached binaries can also be downloaded from http://ota.tasmota.com/tasmota
|
|||
|
||||
### Changed
|
||||
- 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
|
||||
- TuyaMcu dimmer timeout [#11121](https://github.com/arendst/Tasmota/issues/11121)
|
||||
- Rename epaper 42 commands [#11222](https://github.com/arendst/Tasmota/issues/11222)
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
tests/bin
|
|
@ -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
|
||||
* Fix remaining-length handling to prevent buffer overrun
|
||||
* 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
|
||||
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
|
||||
|
||||
- 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
|
||||
is configurable via `MQTT_MAX_PACKET_SIZE` in `PubSubClient.h`.
|
||||
- The maximum message size, including header, is **256 bytes** by default. This
|
||||
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
|
||||
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
|
||||
changing value of `MQTT_VERSION` in `PubSubClient.h`.
|
||||
|
|
@ -27,9 +27,9 @@ 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,
|
||||
// you will need to increase the value of MQTT_MAX_PACKET_SIZE in
|
||||
// PubSubClient.h
|
||||
// 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("outTopic","hello world");
|
|
@ -1,26 +1,21 @@
|
|||
/*
|
||||
Basic ESP8266 MQTT example
|
||||
|
||||
This sketch demonstrates the capabilities of the pubsub library in combination
|
||||
with the ESP8266 board/library.
|
||||
|
||||
It connects to an MQTT server then:
|
||||
- publishes "hello world" to the topic "outTopic" every two seconds
|
||||
- subscribes to the topic "inTopic", printing out any messages
|
||||
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,
|
||||
else switch it off
|
||||
|
||||
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
|
||||
achieve the same result without blocking the main loop.
|
||||
|
||||
To install the ESP8266 board, (using Arduino 1.6.4+):
|
||||
- Add the following 3rd party board manager under "File -> Preferences -> Additional Boards Manager URLs":
|
||||
http://arduino.esp8266.com/stable/package_esp8266com_index.json
|
||||
- Open the "Tools -> Board -> Board Manager" and click install for the ESP8266"
|
||||
- Select your ESP8266 in "Tools -> Board"
|
||||
|
||||
*/
|
||||
|
||||
#include <ESP8266WiFi.h>
|
||||
|
@ -34,8 +29,9 @@ const char* mqtt_server = "broker.mqtt-dashboard.com";
|
|||
|
||||
WiFiClient espClient;
|
||||
PubSubClient client(espClient);
|
||||
long lastMsg = 0;
|
||||
char msg[50];
|
||||
unsigned long lastMsg = 0;
|
||||
#define MSG_BUFFER_SIZE (50)
|
||||
char msg[MSG_BUFFER_SIZE];
|
||||
int value = 0;
|
||||
|
||||
void setup_wifi() {
|
||||
|
@ -46,6 +42,7 @@ void setup_wifi() {
|
|||
Serial.print("Connecting to ");
|
||||
Serial.println(ssid);
|
||||
|
||||
WiFi.mode(WIFI_STA);
|
||||
WiFi.begin(ssid, password);
|
||||
|
||||
while (WiFi.status() != WL_CONNECTED) {
|
||||
|
@ -120,11 +117,11 @@ void loop() {
|
|||
}
|
||||
client.loop();
|
||||
|
||||
long now = millis();
|
||||
unsigned long now = millis();
|
||||
if (now - lastMsg > 2000) {
|
||||
lastMsg = now;
|
||||
++value;
|
||||
snprintf (msg, 50, "hello world #%ld", value);
|
||||
snprintf (msg, MSG_BUFFER_SIZE, "hello world #%ld", value);
|
||||
Serial.print("Publish message: ");
|
||||
Serial.println(msg);
|
||||
client.publish("outTopic", msg);
|
|
@ -27,6 +27,9 @@ setServer KEYWORD2
|
|||
setCallback KEYWORD2
|
||||
setClient KEYWORD2
|
||||
setStream KEYWORD2
|
||||
setKeepAlive KEYWORD2
|
||||
setBufferSize KEYWORD2
|
||||
setSocketTimeout KEYWORD2
|
||||
|
||||
#######################################
|
||||
# Constants (LITERAL1)
|
|
@ -6,9 +6,13 @@
|
|||
"type": "git",
|
||||
"url": "https://github.com/knolleary/pubsubclient.git"
|
||||
},
|
||||
"version": "2.7",
|
||||
"version": "2.8",
|
||||
"exclude": "tests",
|
||||
"examples": "examples/*/*.ino",
|
||||
"frameworks": "arduino",
|
||||
"platforms": ["espressif8266", "espressif32"]
|
||||
"platforms": [
|
||||
"atmelavr",
|
||||
"espressif8266",
|
||||
"espressif32"
|
||||
]
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
name=PubSubClient
|
||||
version=2.7
|
||||
version=2.8
|
||||
author=Nick O'Leary <nick.oleary@gmail.com>
|
||||
maintainer=Nick O'Leary <nick.oleary@gmail.com>
|
||||
sentence=A client library for MQTT messaging.
|
|
@ -12,12 +12,20 @@ PubSubClient::PubSubClient() {
|
|||
this->_client = NULL;
|
||||
this->stream = NULL;
|
||||
setCallback(NULL);
|
||||
this->bufferSize = 0;
|
||||
setBufferSize(MQTT_MAX_PACKET_SIZE);
|
||||
setKeepAlive(MQTT_KEEPALIVE);
|
||||
setSocketTimeout(MQTT_SOCKET_TIMEOUT);
|
||||
}
|
||||
|
||||
PubSubClient::PubSubClient(Client& client) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
setClient(client);
|
||||
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) {
|
||||
|
@ -25,12 +33,20 @@ PubSubClient::PubSubClient(IPAddress addr, uint16_t port, Client& client) {
|
|||
setServer(addr, port);
|
||||
setClient(client);
|
||||
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) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
setServer(addr,port);
|
||||
setClient(client);
|
||||
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) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
|
@ -38,6 +54,10 @@ PubSubClient::PubSubClient(IPAddress addr, uint16_t port, MQTT_CALLBACK_SIGNATUR
|
|||
setCallback(callback);
|
||||
setClient(client);
|
||||
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) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
|
@ -45,6 +65,10 @@ PubSubClient::PubSubClient(IPAddress addr, uint16_t port, MQTT_CALLBACK_SIGNATUR
|
|||
setCallback(callback);
|
||||
setClient(client);
|
||||
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) {
|
||||
|
@ -52,12 +76,20 @@ PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, Client& client) {
|
|||
setServer(ip, port);
|
||||
setClient(client);
|
||||
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) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
setServer(ip,port);
|
||||
setClient(client);
|
||||
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) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
|
@ -65,6 +97,10 @@ PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, MQTT_CALLBACK_SIGNATURE,
|
|||
setCallback(callback);
|
||||
setClient(client);
|
||||
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) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
|
@ -72,6 +108,10 @@ PubSubClient::PubSubClient(uint8_t *ip, uint16_t port, MQTT_CALLBACK_SIGNATURE,
|
|||
setCallback(callback);
|
||||
setClient(client);
|
||||
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) {
|
||||
|
@ -79,12 +119,20 @@ PubSubClient::PubSubClient(const char* domain, uint16_t port, Client& client) {
|
|||
setServer(domain,port);
|
||||
setClient(client);
|
||||
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) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
setServer(domain,port);
|
||||
setClient(client);
|
||||
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) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
|
@ -92,6 +140,10 @@ PubSubClient::PubSubClient(const char* domain, uint16_t port, MQTT_CALLBACK_SIGN
|
|||
setCallback(callback);
|
||||
setClient(client);
|
||||
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) {
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
|
@ -99,6 +151,14 @@ PubSubClient::PubSubClient(const char* domain, uint16_t port, MQTT_CALLBACK_SIGN
|
|||
setCallback(callback);
|
||||
setClient(client);
|
||||
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) {
|
||||
|
@ -121,18 +181,29 @@ boolean PubSubClient::connect(const char *id, const char *user, const char *pass
|
|||
if (!connected()) {
|
||||
int result = 0;
|
||||
|
||||
// Start Tasmota patch
|
||||
if (_client == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (_client->connected()) {
|
||||
// End Tasmota patch
|
||||
|
||||
if(_client->connected()) {
|
||||
result = 1;
|
||||
} else {
|
||||
|
||||
// Start Tasmota patch
|
||||
// if (domain != NULL) {
|
||||
// result = _client->connect(this->domain, this->port);
|
||||
|
||||
if (domain.length() != 0) {
|
||||
result = _client->connect(this->domain.c_str(), this->port);
|
||||
// End Tasmota patch
|
||||
|
||||
} else {
|
||||
result = _client->connect(this->ip, this->port);
|
||||
}
|
||||
}
|
||||
|
||||
if (result == 1) {
|
||||
nextMsgId = 1;
|
||||
// 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
|
||||
#endif
|
||||
for (j = 0;j<MQTT_HEADER_VERSION_LENGTH;j++) {
|
||||
buffer[length++] = d[j];
|
||||
this->buffer[length++] = d[j];
|
||||
}
|
||||
|
||||
uint8_t v;
|
||||
|
@ -167,45 +238,48 @@ boolean PubSubClient::connect(const char *id, const char *user, const char *pass
|
|||
v = v|(0x80>>1);
|
||||
}
|
||||
}
|
||||
this->buffer[length++] = v;
|
||||
|
||||
buffer[length++] = v;
|
||||
|
||||
buffer[length++] = ((MQTT_KEEPALIVE) >> 8);
|
||||
buffer[length++] = ((MQTT_KEEPALIVE) & 0xFF);
|
||||
this->buffer[length++] = ((this->keepAlive) >> 8);
|
||||
this->buffer[length++] = ((this->keepAlive) & 0xFF);
|
||||
|
||||
CHECK_STRING_LENGTH(length,id)
|
||||
length = writeString(id,buffer,length);
|
||||
length = writeString(id,this->buffer,length);
|
||||
if (willTopic) {
|
||||
CHECK_STRING_LENGTH(length,willTopic)
|
||||
length = writeString(willTopic,buffer,length);
|
||||
length = writeString(willTopic,this->buffer,length);
|
||||
CHECK_STRING_LENGTH(length,willMessage)
|
||||
length = writeString(willMessage,buffer,length);
|
||||
length = writeString(willMessage,this->buffer,length);
|
||||
}
|
||||
|
||||
if(user != NULL) {
|
||||
CHECK_STRING_LENGTH(length,user)
|
||||
length = writeString(user,buffer,length);
|
||||
length = writeString(user,this->buffer,length);
|
||||
if(pass != NULL) {
|
||||
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();
|
||||
|
||||
while (!_client->available()) {
|
||||
|
||||
// Start Tasmota patch
|
||||
delay(0); // Prevent watchdog crashes
|
||||
// End Tasmota patch
|
||||
|
||||
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;
|
||||
_client->stop();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
uint8_t llen;
|
||||
uint16_t len = readPacket(&llen);
|
||||
uint32_t len = readPacket(&llen);
|
||||
|
||||
if (len == 4) {
|
||||
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
|
||||
boolean PubSubClient::readByte(uint8_t * result) {
|
||||
|
||||
// Start Tasmota patch
|
||||
if (_client == nullptr) {
|
||||
return false;
|
||||
}
|
||||
// End Tasmota patch
|
||||
|
||||
uint32_t previousMillis = millis();
|
||||
while(!_client->available()) {
|
||||
|
||||
// Start Tasmota patch
|
||||
// yield();
|
||||
|
||||
delay(1); // Prevent watchdog crashes
|
||||
// End Tasmota patch
|
||||
|
||||
uint32_t currentMillis = millis();
|
||||
if(currentMillis - previousMillis >= ((int32_t) MQTT_SOCKET_TIMEOUT * 1000)){
|
||||
if(currentMillis - previousMillis >= ((int32_t) this->socketTimeout * 1000)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -254,15 +338,15 @@ boolean PubSubClient::readByte(uint8_t * result, uint16_t * index){
|
|||
return false;
|
||||
}
|
||||
|
||||
uint16_t PubSubClient::readPacket(uint8_t* lengthLength) {
|
||||
uint32_t PubSubClient::readPacket(uint8_t* lengthLength) {
|
||||
uint16_t len = 0;
|
||||
if(!readByte(buffer, &len)) return 0;
|
||||
bool isPublish = (buffer[0]&0xF0) == MQTTPUBLISH;
|
||||
if(!readByte(this->buffer, &len)) return 0;
|
||||
bool isPublish = (this->buffer[0]&0xF0) == MQTTPUBLISH;
|
||||
uint32_t multiplier = 1;
|
||||
uint16_t length = 0;
|
||||
uint32_t length = 0;
|
||||
uint8_t digit = 0;
|
||||
uint16_t skip = 0;
|
||||
uint8_t start = 0;
|
||||
uint32_t start = 0;
|
||||
|
||||
do {
|
||||
if (len == 5) {
|
||||
|
@ -272,59 +356,75 @@ uint16_t PubSubClient::readPacket(uint8_t* lengthLength) {
|
|||
return 0;
|
||||
}
|
||||
if(!readByte(&digit)) return 0;
|
||||
buffer[len++] = digit;
|
||||
this->buffer[len++] = digit;
|
||||
length += (digit & 127) * multiplier;
|
||||
multiplier *= 128;
|
||||
} while ((digit & 128) != 0 && len < (MQTT_MAX_PACKET_SIZE -2));
|
||||
multiplier <<=7; //multiplier *= 128
|
||||
|
||||
// Start Tasmota patch
|
||||
// } while ((digit & 128) != 0);
|
||||
|
||||
} while ((digit & 128) != 0 && len < (this->bufferSize -2));
|
||||
// End Tasmota patch
|
||||
|
||||
*lengthLength = len-1;
|
||||
|
||||
if (isPublish) {
|
||||
// Read in topic length to calculate bytes to skip over for Stream writing
|
||||
if(!readByte(buffer, &len)) return 0;
|
||||
if(!readByte(buffer, &len)) return 0;
|
||||
skip = (buffer[*lengthLength+1]<<8)+buffer[*lengthLength+2];
|
||||
if(!readByte(this->buffer, &len)) return 0;
|
||||
if(!readByte(this->buffer, &len)) return 0;
|
||||
skip = (this->buffer[*lengthLength+1]<<8)+this->buffer[*lengthLength+2];
|
||||
start = 2;
|
||||
if (buffer[0]&MQTTQOS1) {
|
||||
if (this->buffer[0]&MQTTQOS1) {
|
||||
// skip message id
|
||||
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 (this->stream) {
|
||||
if (isPublish && len-*lengthLength-2>skip) {
|
||||
if (isPublish && idx-*lengthLength-2>skip) {
|
||||
this->stream->write(digit);
|
||||
}
|
||||
}
|
||||
if (len < MQTT_MAX_PACKET_SIZE) {
|
||||
buffer[len] = digit;
|
||||
}
|
||||
|
||||
if (len < this->bufferSize) {
|
||||
this->buffer[len] = digit;
|
||||
len++;
|
||||
}
|
||||
|
||||
if (!this->stream && len > MQTT_MAX_PACKET_SIZE) {
|
||||
len = 0; // This will cause the packet to be ignored.
|
||||
idx++;
|
||||
}
|
||||
|
||||
if (!this->stream && idx > this->bufferSize) {
|
||||
len = 0; // This will cause the packet to be ignored.
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
boolean PubSubClient::loop() {
|
||||
if (connected()) {
|
||||
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) {
|
||||
this->_state = MQTT_CONNECTION_TIMEOUT;
|
||||
_client->stop();
|
||||
return false;
|
||||
} else {
|
||||
buffer[0] = MQTTPINGREQ;
|
||||
buffer[1] = 0;
|
||||
if (_client->write(buffer,2) != 0) {
|
||||
this->buffer[0] = MQTTPINGREQ;
|
||||
this->buffer[1] = 0;
|
||||
|
||||
// Start Tasmota patch
|
||||
// _client->write(this->buffer,2);
|
||||
// lastOutActivity = t;
|
||||
// lastInActivity = t;
|
||||
|
||||
if (_client->write(this->buffer,2) != 0) {
|
||||
lastOutActivity = t;
|
||||
lastInActivity = t;
|
||||
}
|
||||
// End Tasmota patch
|
||||
|
||||
pingOutstanding = true;
|
||||
}
|
||||
}
|
||||
|
@ -335,35 +435,42 @@ boolean PubSubClient::loop() {
|
|||
uint8_t *payload;
|
||||
if (len > 0) {
|
||||
lastInActivity = t;
|
||||
uint8_t type = buffer[0]&0xF0;
|
||||
uint8_t type = this->buffer[0]&0xF0;
|
||||
if (type == MQTTPUBLISH) {
|
||||
if (callback) {
|
||||
uint16_t tl = (buffer[llen+1]<<8)+buffer[llen+2]; /* topic length in bytes */
|
||||
memmove(buffer+llen+2,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 */
|
||||
char *topic = (char*) buffer+llen+2;
|
||||
uint16_t tl = (this->buffer[llen+1]<<8)+this->buffer[llen+2]; /* topic length in bytes */
|
||||
memmove(this->buffer+llen+2,this->buffer+llen+3,tl); /* move topic inside buffer 1 byte to front */
|
||||
this->buffer[llen+2+tl] = 0; /* end the topic as a 'C' string with \x00 */
|
||||
char *topic = (char*) this->buffer+llen+2;
|
||||
// msgId only present for QOS>0
|
||||
if ((buffer[0]&0x06) == MQTTQOS1) {
|
||||
msgId = (buffer[llen+3+tl]<<8)+buffer[llen+3+tl+1];
|
||||
payload = buffer+llen+3+tl+2;
|
||||
if ((this->buffer[0]&0x06) == MQTTQOS1) {
|
||||
msgId = (this->buffer[llen+3+tl]<<8)+this->buffer[llen+3+tl+1];
|
||||
payload = this->buffer+llen+3+tl+2;
|
||||
callback(topic,payload,len-llen-3-tl-2);
|
||||
|
||||
buffer[0] = MQTTPUBACK;
|
||||
buffer[1] = 2;
|
||||
buffer[2] = (msgId >> 8);
|
||||
buffer[3] = (msgId & 0xFF);
|
||||
if (_client->write(buffer,4) != 0) {
|
||||
this->buffer[0] = MQTTPUBACK;
|
||||
this->buffer[1] = 2;
|
||||
this->buffer[2] = (msgId >> 8);
|
||||
this->buffer[3] = (msgId & 0xFF);
|
||||
|
||||
// Start Tasmota patch
|
||||
// _client->write(this->buffer,4);
|
||||
// lastOutActivity = t;
|
||||
|
||||
if (_client->write(this->buffer,4) != 0) {
|
||||
lastOutActivity = t;
|
||||
}
|
||||
// End Tasmota patch
|
||||
|
||||
} else {
|
||||
payload = buffer+llen+3+tl;
|
||||
payload = this->buffer+llen+3+tl;
|
||||
callback(topic,payload,len-llen-3-tl);
|
||||
}
|
||||
}
|
||||
} else if (type == MQTTPINGREQ) {
|
||||
buffer[0] = MQTTPINGRESP;
|
||||
buffer[1] = 0;
|
||||
_client->write(buffer,2);
|
||||
this->buffer[0] = MQTTPINGRESP;
|
||||
this->buffer[1] = 0;
|
||||
_client->write(this->buffer,2);
|
||||
} else if (type == MQTTPINGRESP) {
|
||||
pingOutstanding = false;
|
||||
}
|
||||
|
@ -378,13 +485,11 @@ boolean PubSubClient::loop() {
|
|||
}
|
||||
|
||||
boolean PubSubClient::publish(const char* topic, const char* payload) {
|
||||
size_t plength = (payload != nullptr) ? strlen(payload) : 0;
|
||||
return publish(topic,(const uint8_t*)payload,plength,false);
|
||||
return publish(topic,(const uint8_t*)payload, payload ? strnlen(payload, this->bufferSize) : 0,false);
|
||||
}
|
||||
|
||||
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,plength,retained);
|
||||
return publish(topic,(const uint8_t*)payload, payload ? strnlen(payload, this->bufferSize) : 0,retained);
|
||||
}
|
||||
|
||||
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) {
|
||||
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
|
||||
return false;
|
||||
}
|
||||
// Leave room in the buffer for header and variable length field
|
||||
uint16_t length = MQTT_MAX_HEADER_SIZE;
|
||||
length = writeString(topic,buffer,length);
|
||||
length = writeString(topic,this->buffer,length);
|
||||
|
||||
// Add payload
|
||||
uint16_t i;
|
||||
for (i=0;i<plength;i++) {
|
||||
buffer[length++] = payload[i];
|
||||
this->buffer[length++] = payload[i];
|
||||
}
|
||||
|
||||
// Write the header
|
||||
uint8_t header = MQTTPUBLISH;
|
||||
if (retained) {
|
||||
header |= 1;
|
||||
}
|
||||
return write(header,buffer,length-MQTT_MAX_HEADER_SIZE);
|
||||
return write(header,this->buffer,length-MQTT_MAX_HEADER_SIZE);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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, plength, retained);
|
||||
return publish_P(topic, (const uint8_t*)payload, payload ? strnlen(payload, this->bufferSize) : 0, 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;
|
||||
uint8_t header;
|
||||
unsigned int len;
|
||||
int expectedLength;
|
||||
|
||||
if (!connected()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
tlen = strlen(topic);
|
||||
tlen = strnlen(topic, this->bufferSize);
|
||||
|
||||
header = MQTTPUBLISH;
|
||||
if (retained) {
|
||||
header |= 1;
|
||||
}
|
||||
buffer[pos++] = header;
|
||||
this->buffer[pos++] = header;
|
||||
len = plength + 2 + tlen;
|
||||
do {
|
||||
digit = len % 128;
|
||||
len = len / 128;
|
||||
digit = len & 127; //digit = len %128
|
||||
len >>= 7; //len = len / 128
|
||||
if (len > 0) {
|
||||
digit |= 0x80;
|
||||
}
|
||||
buffer[pos++] = digit;
|
||||
this->buffer[pos++] = digit;
|
||||
llen++;
|
||||
} 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++) {
|
||||
rc += _client->write((char)pgm_read_byte_near(payload + i));
|
||||
}
|
||||
|
||||
// Start Tasmota patch
|
||||
// lastOutActivity = millis();
|
||||
|
||||
if (rc > 0) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -470,16 +584,22 @@ boolean PubSubClient::beginPublish(const char* topic, unsigned int plength, bool
|
|||
if (connected()) {
|
||||
// Send the header and variable length field
|
||||
uint16_t length = MQTT_MAX_HEADER_SIZE;
|
||||
length = writeString(topic,buffer,length);
|
||||
length = writeString(topic,this->buffer,length);
|
||||
uint8_t header = MQTTPUBLISH;
|
||||
if (retained) {
|
||||
header |= 1;
|
||||
}
|
||||
size_t hlen = buildHeader(header, buffer, plength+length-MQTT_MAX_HEADER_SIZE);
|
||||
uint16_t rc = _client->write(buffer+(MQTT_MAX_HEADER_SIZE-hlen),length-(MQTT_MAX_HEADER_SIZE-hlen));
|
||||
size_t hlen = buildHeader(header, this->buffer, plength+length-MQTT_MAX_HEADER_SIZE);
|
||||
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) {
|
||||
lastOutActivity = millis();
|
||||
}
|
||||
// End Tasmota patch
|
||||
|
||||
return (rc == (length-(MQTT_MAX_HEADER_SIZE-hlen)));
|
||||
}
|
||||
return false;
|
||||
|
@ -490,6 +610,11 @@ int PubSubClient::endPublish() {
|
|||
}
|
||||
|
||||
size_t PubSubClient::write(uint8_t data) {
|
||||
|
||||
// Start Tasmota patch
|
||||
// lastOutActivity = millis();
|
||||
// return _client->write(data);
|
||||
|
||||
if (_client == nullptr) {
|
||||
lastOutActivity = millis();
|
||||
return 0;
|
||||
|
@ -499,9 +624,16 @@ size_t PubSubClient::write(uint8_t data) {
|
|||
lastOutActivity = millis();
|
||||
}
|
||||
return rc;
|
||||
// End Tasmota patch
|
||||
|
||||
}
|
||||
|
||||
size_t PubSubClient::write(const uint8_t *buffer, size_t size) {
|
||||
|
||||
// Start Tasmota patch
|
||||
// lastOutActivity = millis();
|
||||
// return _client->write(buffer,size);
|
||||
|
||||
if (_client == nullptr) {
|
||||
lastOutActivity = millis();
|
||||
return 0;
|
||||
|
@ -511,6 +643,8 @@ size_t PubSubClient::write(const uint8_t *buffer, size_t size) {
|
|||
lastOutActivity = millis();
|
||||
}
|
||||
return rc;
|
||||
// End Tasmota patch
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
uint16_t len = length;
|
||||
do {
|
||||
digit = len % 128;
|
||||
len = len / 128;
|
||||
|
||||
digit = len & 127; //digit = len %128
|
||||
len >>= 7; //len = len / 128
|
||||
if (len > 0) {
|
||||
digit |= 0x80;
|
||||
}
|
||||
|
@ -546,7 +681,6 @@ boolean PubSubClient::write(uint8_t header, uint8_t* buf, uint16_t length) {
|
|||
uint8_t bytesToWrite;
|
||||
boolean result = true;
|
||||
while((bytesRemaining > 0) && result) {
|
||||
delay(0); // Prevent watchdog crashes
|
||||
bytesToWrite = (bytesRemaining > MQTT_MAX_TRANSFER_SIZE)?MQTT_MAX_TRANSFER_SIZE:bytesRemaining;
|
||||
rc = _client->write(writeBuf,bytesToWrite);
|
||||
result = (rc == bytesToWrite);
|
||||
|
@ -556,9 +690,15 @@ boolean PubSubClient::write(uint8_t header, uint8_t* buf, uint16_t length) {
|
|||
return result;
|
||||
#else
|
||||
rc = _client->write(buf+(MQTT_MAX_HEADER_SIZE-hlen),length+hlen);
|
||||
|
||||
// Start Tasmota patch
|
||||
// lastOutActivity = millis();
|
||||
|
||||
if (rc != 0) {
|
||||
lastOutActivity = millis();
|
||||
}
|
||||
// End Tasmota patch
|
||||
|
||||
return (rc == hlen+length);
|
||||
#endif
|
||||
}
|
||||
|
@ -568,10 +708,14 @@ boolean PubSubClient::subscribe(const char* topic) {
|
|||
}
|
||||
|
||||
boolean PubSubClient::subscribe(const char* topic, uint8_t qos) {
|
||||
size_t topicLength = strnlen(topic, this->bufferSize);
|
||||
if (topic == 0) {
|
||||
return false;
|
||||
}
|
||||
if (qos > 1) {
|
||||
return false;
|
||||
}
|
||||
if (MQTT_MAX_PACKET_SIZE < 9 + strlen(topic)) {
|
||||
if (this->bufferSize < 9 + topicLength) {
|
||||
// Too long
|
||||
return false;
|
||||
}
|
||||
|
@ -582,17 +726,21 @@ boolean PubSubClient::subscribe(const char* topic, uint8_t qos) {
|
|||
if (nextMsgId == 0) {
|
||||
nextMsgId = 1;
|
||||
}
|
||||
buffer[length++] = (nextMsgId >> 8);
|
||||
buffer[length++] = (nextMsgId & 0xFF);
|
||||
length = writeString((char*)topic, buffer,length);
|
||||
buffer[length++] = qos;
|
||||
return write(MQTTSUBSCRIBE|MQTTQOS1,buffer,length-MQTT_MAX_HEADER_SIZE);
|
||||
this->buffer[length++] = (nextMsgId >> 8);
|
||||
this->buffer[length++] = (nextMsgId & 0xFF);
|
||||
length = writeString((char*)topic, this->buffer,length);
|
||||
this->buffer[length++] = qos;
|
||||
return write(MQTTSUBSCRIBE|MQTTQOS1,this->buffer,length-MQTT_MAX_HEADER_SIZE);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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
|
||||
return false;
|
||||
}
|
||||
|
@ -602,25 +750,34 @@ boolean PubSubClient::unsubscribe(const char* topic) {
|
|||
if (nextMsgId == 0) {
|
||||
nextMsgId = 1;
|
||||
}
|
||||
buffer[length++] = (nextMsgId >> 8);
|
||||
buffer[length++] = (nextMsgId & 0xFF);
|
||||
length = writeString(topic, buffer,length);
|
||||
return write(MQTTUNSUBSCRIBE|MQTTQOS1,buffer,length-MQTT_MAX_HEADER_SIZE);
|
||||
this->buffer[length++] = (nextMsgId >> 8);
|
||||
this->buffer[length++] = (nextMsgId & 0xFF);
|
||||
length = writeString(topic, this->buffer,length);
|
||||
return write(MQTTUNSUBSCRIBE|MQTTQOS1,this->buffer,length-MQTT_MAX_HEADER_SIZE);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PubSubClient::disconnect(bool disconnect_package) {
|
||||
buffer[0] = MQTTDISCONNECT;
|
||||
buffer[1] = 0;
|
||||
this->buffer[0] = MQTTDISCONNECT;
|
||||
this->buffer[1] = 0;
|
||||
|
||||
// Start Tasmota patch
|
||||
// _client->write(this->buffer,2);
|
||||
// _state = MQTT_DISCONNECTED;
|
||||
// _client->flush();
|
||||
// _client->stop();
|
||||
|
||||
if (_client != nullptr) {
|
||||
if (disconnect_package) {
|
||||
_client->write(buffer,2);
|
||||
_client->write(this->buffer,2);
|
||||
}
|
||||
_client->flush();
|
||||
_client->stop();
|
||||
}
|
||||
_state = MQTT_DISCONNECTED;
|
||||
// End Tasmota patch
|
||||
|
||||
lastInActivity = lastOutActivity = millis();
|
||||
}
|
||||
|
||||
|
@ -628,7 +785,7 @@ uint16_t PubSubClient::writeString(const char* string, uint8_t* buf, uint16_t po
|
|||
const char* idp = string;
|
||||
uint16_t i = 0;
|
||||
pos += 2;
|
||||
while (*idp && pos < (MQTT_MAX_PACKET_SIZE - 2)) {
|
||||
while (*idp) {
|
||||
buf[pos++] = *idp++;
|
||||
i++;
|
||||
}
|
||||
|
@ -639,19 +796,27 @@ uint16_t PubSubClient::writeString(const char* string, uint8_t* buf, uint16_t po
|
|||
|
||||
|
||||
boolean PubSubClient::connected() {
|
||||
boolean rc;
|
||||
if (_client == NULL ) {
|
||||
|
||||
// Start Tasmota patch
|
||||
this->_state = MQTT_DISCONNECTED;
|
||||
return false;
|
||||
}
|
||||
if (_client->connected() == 0) {
|
||||
bool lastStateConnected = this->_state == MQTT_CONNECTED;
|
||||
this->disconnect();
|
||||
if (lastStateConnected) {
|
||||
// End Tasmota patch
|
||||
|
||||
rc = false;
|
||||
} else {
|
||||
rc = (int)_client->connected();
|
||||
if (!rc) {
|
||||
if (this->_state == MQTT_CONNECTED) {
|
||||
this->_state = MQTT_CONNECTION_LOST;
|
||||
_client->flush();
|
||||
_client->stop();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return this->_state == MQTT_CONNECTED;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
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) {
|
||||
this->ip = ip;
|
||||
this->port = port;
|
||||
|
||||
// Start Tasmota patch
|
||||
// this->domain = NULL;
|
||||
|
||||
this->domain = "";
|
||||
// End Tasmota patch
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -690,3 +861,34 @@ PubSubClient& PubSubClient::setStream(Stream& stream){
|
|||
int PubSubClient::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
|
||||
#endif
|
||||
|
||||
// MQTT_MAX_PACKET_SIZE : Maximum packet size
|
||||
// MQTT_MAX_PACKET_SIZE : Maximum packet size. Override with setBufferSize().
|
||||
#ifndef MQTT_MAX_PACKET_SIZE
|
||||
//#define MQTT_MAX_PACKET_SIZE 128
|
||||
//#define MQTT_MAX_PACKET_SIZE 1000 // Tasmota v5.11.1c
|
||||
//#define MQTT_MAX_PACKET_SIZE 256
|
||||
#define MQTT_MAX_PACKET_SIZE 1200 // Tasmota v8.1.0.8
|
||||
#endif
|
||||
|
||||
// MQTT_KEEPALIVE : keepAlive interval in Seconds
|
||||
// Keepalive timeout for default MQTT Broker is 10s
|
||||
// MQTT_KEEPALIVE : keepAlive interval in Seconds. Override with setKeepAlive()
|
||||
#ifndef MQTT_KEEPALIVE
|
||||
//#define MQTT_KEEPALIVE 10
|
||||
#define MQTT_KEEPALIVE 30 // Tasmota v6.5.0.14 enabling AWS-iot
|
||||
#define MQTT_KEEPALIVE 15
|
||||
#endif
|
||||
|
||||
// MQTT_SOCKET_TIMEOUT: socket timeout interval in Seconds
|
||||
// MQTT_SOCKET_TIMEOUT: socket timeout interval in Seconds. Override with setSocketTimeout()
|
||||
#ifndef MQTT_SOCKET_TIMEOUT
|
||||
//#define MQTT_SOCKET_TIMEOUT 15
|
||||
#define MQTT_SOCKET_TIMEOUT 4 // Tasmota 20210120
|
||||
#define MQTT_SOCKET_TIMEOUT 15
|
||||
#endif
|
||||
|
||||
// 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)
|
||||
#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 {
|
||||
private:
|
||||
Client* _client;
|
||||
uint8_t buffer[MQTT_MAX_PACKET_SIZE];
|
||||
uint8_t* buffer;
|
||||
uint16_t bufferSize;
|
||||
uint16_t keepAlive;
|
||||
uint16_t socketTimeout;
|
||||
uint16_t nextMsgId;
|
||||
unsigned long lastOutActivity;
|
||||
unsigned long lastInActivity;
|
||||
bool pingOutstanding;
|
||||
MQTT_CALLBACK_SIGNATURE;
|
||||
uint16_t readPacket(uint8_t*);
|
||||
uint32_t readPacket(uint8_t*);
|
||||
boolean readByte(uint8_t * result);
|
||||
boolean readByte(uint8_t * result, uint16_t * index);
|
||||
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
|
||||
size_t buildHeader(uint8_t header, uint8_t* buf, uint16_t length);
|
||||
IPAddress ip;
|
||||
|
||||
// Start Tasmota patch
|
||||
// const char* domain;
|
||||
|
||||
String domain;
|
||||
// End Tasmota patch
|
||||
|
||||
uint16_t port;
|
||||
Stream* stream;
|
||||
int _state;
|
||||
|
@ -129,7 +134,8 @@ public:
|
|||
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, Stream&);
|
||||
virtual ~PubSubClient() {}
|
||||
|
||||
~PubSubClient();
|
||||
|
||||
PubSubClient& setServer(IPAddress ip, uint16_t port);
|
||||
PubSubClient& setServer(uint8_t * ip, uint16_t port);
|
||||
|
@ -137,13 +143,24 @@ public:
|
|||
PubSubClient& setCallback(MQTT_CALLBACK_SIGNATURE);
|
||||
PubSubClient& setClient(Client& client);
|
||||
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, 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* 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);
|
||||
|
||||
// Start Tasmota patch
|
||||
// void disconnect();
|
||||
|
||||
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 retained);
|
||||
boolean publish(const char* topic, const uint8_t * payload, unsigned int plength);
|
||||
|
@ -173,6 +190,7 @@ public:
|
|||
boolean loop();
|
||||
boolean connected();
|
||||
int state();
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -280,6 +280,38 @@ int test_connect_disconnect_connect() {
|
|||
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()
|
||||
{
|
||||
SUITE("Connect");
|
||||
|
@ -298,5 +330,7 @@ int main()
|
|||
test_connect_with_will();
|
||||
test_connect_with_will_username_password();
|
||||
test_connect_disconnect_connect();
|
||||
|
||||
test_connect_custom_keepalive();
|
||||
FINISH
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
class Buffer {
|
||||
private:
|
||||
uint8_t buffer[1024];
|
||||
uint8_t buffer[2048];
|
||||
uint16_t pos;
|
||||
uint16_t length;
|
||||
|
|
@ -134,6 +134,7 @@ int test_publish_too_long() {
|
|||
shimClient.respond(connack,4);
|
||||
|
||||
PubSubClient client(server, 1883, callback, shimClient);
|
||||
client.setBufferSize(128);
|
||||
int rc = client.connect((char*)"client_test1");
|
||||
IS_TRUE(rc);
|
||||
|
|
@ -20,6 +20,7 @@ void reset_callback() {
|
|||
}
|
||||
|
||||
void callback(char* topic, byte* payload, unsigned int length) {
|
||||
TRACE("Callback received topic=[" << topic << "] length=" << length << "\n")
|
||||
callback_called = true;
|
||||
strcpy(lastTopic,topic);
|
||||
memcpy(lastPayload,payload,length);
|
||||
|
@ -102,10 +103,15 @@ int test_receive_max_sized_message() {
|
|||
shimClient.respond(connack,4);
|
||||
|
||||
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");
|
||||
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 bigPublish[length];
|
||||
memset(bigPublish,'A',length);
|
||||
|
@ -137,11 +143,13 @@ int test_receive_oversized_message() {
|
|||
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);
|
||||
|
||||
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 bigPublish[length];
|
||||
memset(bigPublish,'A',length);
|
||||
|
@ -188,9 +196,58 @@ int test_drop_invalid_remaining_length_message() {
|
|||
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() {
|
||||
IT("drops an oversized message");
|
||||
IT("receive an oversized streamed message");
|
||||
reset_callback();
|
||||
|
||||
Stream stream;
|
||||
|
@ -201,11 +258,13 @@ int test_receive_oversized_stream_message() {
|
|||
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, stream);
|
||||
client.setBufferSize(length-1);
|
||||
int rc = client.connect((char*)"client_test1");
|
||||
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 bigPublish[length];
|
||||
|
@ -222,7 +281,8 @@ int test_receive_oversized_stream_message() {
|
|||
|
||||
IS_TRUE(callback_called);
|
||||
IS_TRUE(strcmp(lastTopic,"topic")==0);
|
||||
IS_TRUE(lastLength == length-9);
|
||||
|
||||
IS_TRUE(lastLength == length-10);
|
||||
|
||||
IS_FALSE(stream.error());
|
||||
IS_FALSE(shimClient.error());
|
||||
|
@ -272,6 +332,7 @@ int main()
|
|||
test_receive_max_sized_message();
|
||||
test_drop_invalid_remaining_length_message();
|
||||
test_receive_oversized_message();
|
||||
test_resize_buffer();
|
||||
test_receive_oversized_stream_message();
|
||||
test_receive_qos1();
|
||||
|
|
@ -106,6 +106,7 @@ int test_subscribe_too_long() {
|
|||
shimClient.respond(connack,4);
|
||||
|
||||
PubSubClient client(server, 1883, callback, shimClient);
|
||||
client.setBufferSize(128);
|
||||
int rc = client.connect((char*)"client_test1");
|
||||
IS_TRUE(rc);
|
||||
|
|
@ -366,6 +366,8 @@
|
|||
#define D_CMND_MQTTCLIENT "MqttClient"
|
||||
#define D_CMND_MQTTUSER "MqttUser"
|
||||
#define D_CMND_MQTTPASSWORD "MqttPassword"
|
||||
#define D_CMND_MQTTKEEPALIVE "MqttKeepAlive"
|
||||
#define D_CMND_MQTTTIMEOUT "MqttTimeout"
|
||||
#define D_CMND_TLSKEY "TLSKey"
|
||||
#define D_CMND_FULLTOPIC "FullTopic"
|
||||
#define D_CMND_PREFIX "Prefix"
|
||||
|
|
|
@ -101,6 +101,9 @@
|
|||
// -- MQTT ----------------------------------------
|
||||
#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_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)
|
||||
|
|
|
@ -488,7 +488,12 @@ struct {
|
|||
|
||||
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
|
||||
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));
|
||||
Settings.tele_period = TELE_PERIOD;
|
||||
Settings.mqttlog_level = MQTT_LOG_LEVEL;
|
||||
Settings.mqtt_keepalive = MQTT_KEEPALIVE;
|
||||
Settings.mqtt_socket_timeout = MQTT_SOCKET_TIMEOUT;
|
||||
|
||||
// Energy
|
||||
flag.no_power_on_check |= ENERGY_VOLTAGE_ALWAYS;
|
||||
|
@ -1244,6 +1246,10 @@ void SettingsDelta(void) {
|
|||
if (Settings.version < 0x09020007) {
|
||||
*(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;
|
||||
SettingsSave(1);
|
||||
|
|
|
@ -2125,7 +2125,7 @@ void SyslogAsync(bool refresh) {
|
|||
static uint32_t syslog_host_hash = 0; // Syslog host name hash
|
||||
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; }
|
||||
|
||||
char* line;
|
||||
|
@ -2137,8 +2137,16 @@ void SyslogAsync(bool refresh) {
|
|||
if (mxtime > 0) {
|
||||
uint32_t current_hash = GetHash(SettingsText(SET_SYSLOG_HOST), strlen(SettingsText(SET_SYSLOG_HOST)));
|
||||
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;
|
||||
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)) {
|
||||
TasmotaGlobal.syslog_level = 0;
|
||||
|
|
|
@ -529,9 +529,9 @@ void CmndStatus(void)
|
|||
|
||||
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\",\""
|
||||
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(),
|
||||
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"));
|
||||
}
|
||||
|
||||
|
|
|
@ -270,8 +270,8 @@ const uint16_t LOG_BUFFER_SIZE = 4000; // Max number of characters in lo
|
|||
#ifndef MQTT_KEEPALIVE
|
||||
#define MQTT_KEEPALIVE 30 // Seconds
|
||||
#endif
|
||||
#ifndef MQTT_TIMEOUT
|
||||
#define MQTT_TIMEOUT 10000 // milli seconds
|
||||
#ifndef MQTT_SOCKET_TIMEOUT
|
||||
#define MQTT_SOCKET_TIMEOUT 4 // Seconds
|
||||
#endif
|
||||
#ifndef MQTT_CLEAN_SESSION
|
||||
#define MQTT_CLEAN_SESSION 1 // 0 = No clean session, 1 = Clean session (default)
|
||||
|
|
|
@ -20,6 +20,6 @@
|
|||
#ifndef _TASMOTA_VERSION_H_
|
||||
#define _TASMOTA_VERSION_H_
|
||||
|
||||
const uint32_t VERSION = 0x09030101;
|
||||
const uint32_t VERSION = 0x09030102;
|
||||
|
||||
#endif // _TASMOTA_VERSION_H_
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#define MQTT_WIFI_CLIENT_TIMEOUT 200 // Wifi TCP connection timeout (default is 5000 mSec)
|
||||
#endif
|
||||
|
||||
#define USE_MQTT_NEW_PUBSUBCLIENT
|
||||
|
||||
// #define DEBUG_DUMP_TLS // allow dumping of TLS Flash keys
|
||||
|
||||
#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)
|
||||
D_CMND_MQTTFINGERPRINT "|"
|
||||
#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)
|
||||
D_CMND_TLSKEY "|"
|
||||
#endif
|
||||
|
@ -68,7 +70,7 @@ void (* const MqttCommand[])(void) PROGMEM = {
|
|||
#if defined(USE_MQTT_TLS) && !defined(USE_MQTT_TLS_CA_CERT)
|
||||
&CmndMqttFingerprint,
|
||||
#endif
|
||||
&CmndMqttUser, &CmndMqttPassword,
|
||||
&CmndMqttUser, &CmndMqttPassword, &CmndMqttKeepAlive, &CmndMqttTimeout,
|
||||
#if defined(USE_MQTT_TLS) && defined(USE_MQTT_AWS_IOT)
|
||||
&CmndTlsKey,
|
||||
#endif
|
||||
|
@ -209,6 +211,9 @@ void MqttInit(void) {
|
|||
#else // USE_MQTT_TLS
|
||||
MqttClient.setClient(EspClient);
|
||||
#endif // USE_MQTT_TLS
|
||||
|
||||
MqttClient.setKeepAlive(Settings.mqtt_keepalive);
|
||||
MqttClient.setSocketTimeout(Settings.mqtt_socket_timeout);
|
||||
}
|
||||
|
||||
bool MqttIsConnected(void) {
|
||||
|
@ -311,7 +316,7 @@ void MqttUnsubscribe(const char *topic) {
|
|||
void MqttPublishLoggingAsync(bool refresh) {
|
||||
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; }
|
||||
|
||||
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) {
|
||||
if ((XdrvMailbox.payload >= LOG_LEVEL_NONE) && (XdrvMailbox.payload <= LOG_LEVEL_DEBUG_MORE)) {
|
||||
Settings.mqttlog_level = XdrvMailbox.payload;
|
||||
|
|
|
@ -57,6 +57,7 @@ String FormatMetricName(const char *metric) { // cleanup spaces and uppercases
|
|||
String formatted = metric;
|
||||
formatted.toLowerCase();
|
||||
formatted.replace(" ", "_");
|
||||
formatted.replace(".", "_");
|
||||
return formatted;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue