Allow clean disconnect as optional. This avoid the automatic deletion of LWT message in the broker for clean disconnections, in order to let LWT work also on all cases (Restart, Config Changes, etc) See https://github.com/arendst/Tasmota/issues/7189
178 lines
7.4 KiB
C++
178 lines
7.4 KiB
C++
/*
|
|
PubSubClient.h - A simple client for MQTT.
|
|
Nick O'Leary
|
|
http://knolleary.net
|
|
*/
|
|
|
|
#ifndef PubSubClient_h
|
|
#define PubSubClient_h
|
|
|
|
#include <Arduino.h>
|
|
#include "IPAddress.h"
|
|
#include "Client.h"
|
|
#include "Stream.h"
|
|
|
|
#define MQTT_VERSION_3_1 3
|
|
#define MQTT_VERSION_3_1_1 4
|
|
|
|
// MQTT_VERSION : Pick the version
|
|
//#define MQTT_VERSION MQTT_VERSION_3_1
|
|
#ifndef MQTT_VERSION
|
|
#define MQTT_VERSION MQTT_VERSION_3_1_1
|
|
#endif
|
|
|
|
// MQTT_MAX_PACKET_SIZE : Maximum packet size
|
|
#ifndef MQTT_MAX_PACKET_SIZE
|
|
//#define MQTT_MAX_PACKET_SIZE 128
|
|
#define MQTT_MAX_PACKET_SIZE 1000 // Tasmota v5.11.1c
|
|
#endif
|
|
|
|
// MQTT_KEEPALIVE : keepAlive interval in Seconds
|
|
// Keepalive timeout for default MQTT Broker is 10s
|
|
#ifndef MQTT_KEEPALIVE
|
|
//#define MQTT_KEEPALIVE 10
|
|
#define MQTT_KEEPALIVE 30 // Tasmota v6.5.0.14 enabling AWS-iot
|
|
#endif
|
|
|
|
// MQTT_SOCKET_TIMEOUT: socket timeout interval in Seconds
|
|
#ifndef MQTT_SOCKET_TIMEOUT
|
|
#define MQTT_SOCKET_TIMEOUT 15
|
|
#endif
|
|
|
|
// MQTT_MAX_TRANSFER_SIZE : limit how much data is passed to the network client
|
|
// in each write call. Needed for the Arduino Wifi Shield. Leave undefined to
|
|
// pass the entire MQTT packet in each write call.
|
|
//#define MQTT_MAX_TRANSFER_SIZE 80
|
|
|
|
// Possible values for client.state()
|
|
#define MQTT_CONNECTION_TIMEOUT -4
|
|
#define MQTT_CONNECTION_LOST -3
|
|
#define MQTT_CONNECT_FAILED -2
|
|
#define MQTT_DISCONNECTED -1
|
|
#define MQTT_CONNECTED 0
|
|
#define MQTT_CONNECT_BAD_PROTOCOL 1
|
|
#define MQTT_CONNECT_BAD_CLIENT_ID 2
|
|
#define MQTT_CONNECT_UNAVAILABLE 3
|
|
#define MQTT_CONNECT_BAD_CREDENTIALS 4
|
|
#define MQTT_CONNECT_UNAUTHORIZED 5
|
|
|
|
#define MQTTCONNECT 1 << 4 // Client request to connect to Server
|
|
#define MQTTCONNACK 2 << 4 // Connect Acknowledgment
|
|
#define MQTTPUBLISH 3 << 4 // Publish message
|
|
#define MQTTPUBACK 4 << 4 // Publish Acknowledgment
|
|
#define MQTTPUBREC 5 << 4 // Publish Received (assured delivery part 1)
|
|
#define MQTTPUBREL 6 << 4 // Publish Release (assured delivery part 2)
|
|
#define MQTTPUBCOMP 7 << 4 // Publish Complete (assured delivery part 3)
|
|
#define MQTTSUBSCRIBE 8 << 4 // Client Subscribe request
|
|
#define MQTTSUBACK 9 << 4 // Subscribe Acknowledgment
|
|
#define MQTTUNSUBSCRIBE 10 << 4 // Client Unsubscribe request
|
|
#define MQTTUNSUBACK 11 << 4 // Unsubscribe Acknowledgment
|
|
#define MQTTPINGREQ 12 << 4 // PING Request
|
|
#define MQTTPINGRESP 13 << 4 // PING Response
|
|
#define MQTTDISCONNECT 14 << 4 // Client is Disconnecting
|
|
#define MQTTReserved 15 << 4 // Reserved
|
|
|
|
#define MQTTQOS0 (0 << 1)
|
|
#define MQTTQOS1 (1 << 1)
|
|
#define MQTTQOS2 (2 << 1)
|
|
|
|
// Maximum size of fixed header and variable length size header
|
|
#define MQTT_MAX_HEADER_SIZE 5
|
|
|
|
#if defined(ESP8266) || defined(ESP32)
|
|
#include <functional>
|
|
#define MQTT_CALLBACK_SIGNATURE std::function<void(char*, uint8_t*, unsigned int)> callback
|
|
#else
|
|
#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;}
|
|
|
|
class PubSubClient : public Print {
|
|
private:
|
|
Client* _client;
|
|
uint8_t buffer[MQTT_MAX_PACKET_SIZE];
|
|
uint16_t nextMsgId;
|
|
unsigned long lastOutActivity;
|
|
unsigned long lastInActivity;
|
|
bool pingOutstanding;
|
|
MQTT_CALLBACK_SIGNATURE;
|
|
uint16_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);
|
|
uint16_t writeString(const char* string, uint8_t* buf, uint16_t pos);
|
|
// Build up the header ready to send
|
|
// Returns the size of the header
|
|
// Note: the header is built at the end of the first MQTT_MAX_HEADER_SIZE bytes, so will start
|
|
// (MQTT_MAX_HEADER_SIZE - <returned size>) bytes into the buffer
|
|
size_t buildHeader(uint8_t header, uint8_t* buf, uint16_t length);
|
|
IPAddress ip;
|
|
String domain;
|
|
uint16_t port;
|
|
Stream* stream;
|
|
int _state;
|
|
public:
|
|
PubSubClient();
|
|
PubSubClient(Client& client);
|
|
PubSubClient(IPAddress, uint16_t, Client& client);
|
|
PubSubClient(IPAddress, uint16_t, Client& client, Stream&);
|
|
PubSubClient(IPAddress, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client);
|
|
PubSubClient(IPAddress, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&);
|
|
PubSubClient(uint8_t *, uint16_t, Client& client);
|
|
PubSubClient(uint8_t *, uint16_t, Client& client, Stream&);
|
|
PubSubClient(uint8_t *, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client);
|
|
PubSubClient(uint8_t *, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&);
|
|
PubSubClient(const char*, uint16_t, Client& client);
|
|
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& setServer(IPAddress ip, uint16_t port);
|
|
PubSubClient& setServer(uint8_t * ip, uint16_t port);
|
|
PubSubClient& setServer(const char * domain, uint16_t port);
|
|
PubSubClient& setCallback(MQTT_CALLBACK_SIGNATURE);
|
|
PubSubClient& setClient(Client& client);
|
|
PubSubClient& setStream(Stream& stream);
|
|
|
|
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);
|
|
void disconnect(bool disconnect_package = false);
|
|
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);
|
|
boolean publish(const char* topic, const uint8_t * payload, unsigned int plength, boolean retained);
|
|
boolean publish_P(const char* topic, const char* payload, boolean retained);
|
|
boolean publish_P(const char* topic, const uint8_t * payload, unsigned int plength, boolean retained);
|
|
// Start to publish a message.
|
|
// This API:
|
|
// beginPublish(...)
|
|
// one or more calls to write(...)
|
|
// endPublish()
|
|
// Allows for arbitrarily large payloads to be sent without them having to be copied into
|
|
// a new buffer and held in memory at one time
|
|
// Returns 1 if the message was started successfully, 0 if there was an error
|
|
boolean beginPublish(const char* topic, unsigned int plength, boolean retained);
|
|
// Finish off this publish message (started with beginPublish)
|
|
// Returns 1 if the packet was sent successfully, 0 if there was an error
|
|
int endPublish();
|
|
// Write a single byte of payload (only to be used with beginPublish/endPublish)
|
|
virtual size_t write(uint8_t);
|
|
// Write size bytes from buffer into the payload (only to be used with beginPublish/endPublish)
|
|
// Returns the number of bytes written
|
|
virtual size_t write(const uint8_t *buffer, size_t size);
|
|
boolean subscribe(const char* topic);
|
|
boolean subscribe(const char* topic, uint8_t qos);
|
|
boolean unsubscribe(const char* topic);
|
|
boolean loop();
|
|
boolean connected();
|
|
int state();
|
|
};
|
|
|
|
|
|
#endif
|