|
| 1 | +/* |
| 2 | + PubSubClient.h - A simple client for MQTT. |
| 3 | + Nick O'Leary |
| 4 | + http://knolleary.net |
| 5 | +*/ |
| 6 | + |
| 7 | +#ifndef PubSubClient_h |
| 8 | +#define PubSubClient_h |
| 9 | + |
| 10 | +#include <Arduino.h> |
| 11 | +#include "IPAddress.h" |
| 12 | +#include "Client.h" |
| 13 | +#include "Stream.h" |
| 14 | + |
| 15 | +#define MQTT_VERSION_3_1 3 |
| 16 | +#define MQTT_VERSION_3_1_1 4 |
| 17 | + |
| 18 | +// MQTT_VERSION : Pick the version |
| 19 | +//#define MQTT_VERSION MQTT_VERSION_3_1 |
| 20 | +#ifndef MQTT_VERSION |
| 21 | +#define MQTT_VERSION MQTT_VERSION_3_1_1 |
| 22 | +#endif |
| 23 | + |
| 24 | +// MQTT_MAX_PACKET_SIZE : Maximum packet size. Override with setBufferSize(). |
| 25 | +#ifndef MQTT_MAX_PACKET_SIZE |
| 26 | +#define MQTT_MAX_PACKET_SIZE 256 |
| 27 | +#endif |
| 28 | + |
| 29 | +// MQTT_KEEPALIVE : keepAlive interval in Seconds. Override with setKeepAlive() |
| 30 | +#ifndef MQTT_KEEPALIVE |
| 31 | +#define MQTT_KEEPALIVE 15 |
| 32 | +#endif |
| 33 | + |
| 34 | +// MQTT_SOCKET_TIMEOUT: socket timeout interval in Seconds. Override with setSocketTimeout() |
| 35 | +#ifndef MQTT_SOCKET_TIMEOUT |
| 36 | +#define MQTT_SOCKET_TIMEOUT 60 |
| 37 | +#endif |
| 38 | + |
| 39 | +// MQTT_MAX_TRANSFER_SIZE : limit how much data is passed to the network client |
| 40 | +// in each write call. Needed for the Arduino Wifi Shield. Leave undefined to |
| 41 | +// pass the entire MQTT packet in each write call. |
| 42 | +//#define MQTT_MAX_TRANSFER_SIZE 80 |
| 43 | + |
| 44 | +// Possible values for client.state() |
| 45 | +#define MQTT_CONNECTION_TIMEOUT -4 |
| 46 | +#define MQTT_CONNECTION_LOST -3 |
| 47 | +#define MQTT_CONNECT_FAILED -2 |
| 48 | +#define MQTT_DISCONNECTED -1 |
| 49 | +#define MQTT_CONNECTED 0 |
| 50 | +#define MQTT_CONNECT_BAD_PROTOCOL 1 |
| 51 | +#define MQTT_CONNECT_BAD_CLIENT_ID 2 |
| 52 | +#define MQTT_CONNECT_UNAVAILABLE 3 |
| 53 | +#define MQTT_CONNECT_BAD_CREDENTIALS 4 |
| 54 | +#define MQTT_CONNECT_UNAUTHORIZED 5 |
| 55 | + |
| 56 | +#define MQTTCONNECT 1 << 4 // Client request to connect to Server |
| 57 | +#define MQTTCONNACK 2 << 4 // Connect Acknowledgment |
| 58 | +#define MQTTPUBLISH 3 << 4 // Publish message |
| 59 | +#define MQTTPUBACK 4 << 4 // Publish Acknowledgment |
| 60 | +#define MQTTPUBREC 5 << 4 // Publish Received (assured delivery part 1) |
| 61 | +#define MQTTPUBREL 6 << 4 // Publish Release (assured delivery part 2) |
| 62 | +#define MQTTPUBCOMP 7 << 4 // Publish Complete (assured delivery part 3) |
| 63 | +#define MQTTSUBSCRIBE 8 << 4 // Client Subscribe request |
| 64 | +#define MQTTSUBACK 9 << 4 // Subscribe Acknowledgment |
| 65 | +#define MQTTUNSUBSCRIBE 10 << 4 // Client Unsubscribe request |
| 66 | +#define MQTTUNSUBACK 11 << 4 // Unsubscribe Acknowledgment |
| 67 | +#define MQTTPINGREQ 12 << 4 // PING Request |
| 68 | +#define MQTTPINGRESP 13 << 4 // PING Response |
| 69 | +#define MQTTDISCONNECT 14 << 4 // Client is Disconnecting |
| 70 | +#define MQTTReserved 15 << 4 // Reserved |
| 71 | + |
| 72 | +#define MQTTQOS0 (0 << 1) |
| 73 | +#define MQTTQOS1 (1 << 1) |
| 74 | +#define MQTTQOS2 (2 << 1) |
| 75 | + |
| 76 | +// Maximum size of fixed header and variable length size header |
| 77 | +#define MQTT_MAX_HEADER_SIZE 5 |
| 78 | + |
| 79 | +#if defined(ESP8266) || defined(ESP32) |
| 80 | +#include <functional> |
| 81 | +#define MQTT_CALLBACK_SIGNATURE std::function<void(char*, uint8_t*, unsigned int)> callback |
| 82 | +#else |
| 83 | +#define MQTT_CALLBACK_SIGNATURE void (*callback)(char*, uint8_t*, unsigned int) |
| 84 | +#endif |
| 85 | + |
| 86 | +#define CHECK_STRING_LENGTH(l,s) if (l+2+strnlen(s, this->bufferSize) > this->bufferSize) {_client->stop();return false;} |
| 87 | + |
| 88 | +class PubSubClient : public Print { |
| 89 | +private: |
| 90 | + Client* _client; |
| 91 | + uint8_t* buffer; |
| 92 | + uint16_t bufferSize; |
| 93 | + uint16_t keepAlive; |
| 94 | + uint16_t socketTimeout; |
| 95 | + uint16_t nextMsgId; |
| 96 | + unsigned long lastOutActivity; |
| 97 | + unsigned long lastInActivity; |
| 98 | + bool pingOutstanding; |
| 99 | + MQTT_CALLBACK_SIGNATURE; |
| 100 | + uint32_t readPacket(uint8_t*); |
| 101 | + boolean readByte(uint8_t * result); |
| 102 | + boolean readByte(uint8_t * result, uint16_t * index); |
| 103 | + boolean write(uint8_t header, uint8_t* buf, uint16_t length); |
| 104 | + uint16_t writeString(const char* string, uint8_t* buf, uint16_t pos); |
| 105 | + // Build up the header ready to send |
| 106 | + // Returns the size of the header |
| 107 | + // Note: the header is built at the end of the first MQTT_MAX_HEADER_SIZE bytes, so will start |
| 108 | + // (MQTT_MAX_HEADER_SIZE - <returned size>) bytes into the buffer |
| 109 | + size_t buildHeader(uint8_t header, uint8_t* buf, uint16_t length); |
| 110 | + IPAddress ip; |
| 111 | + const char* domain; |
| 112 | + uint16_t port; |
| 113 | + Stream* stream; |
| 114 | + int _state; |
| 115 | +public: |
| 116 | + PubSubClient(); |
| 117 | + PubSubClient(Client& client); |
| 118 | + PubSubClient(IPAddress, uint16_t, Client& client); |
| 119 | + PubSubClient(IPAddress, uint16_t, Client& client, Stream&); |
| 120 | + PubSubClient(IPAddress, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client); |
| 121 | + PubSubClient(IPAddress, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&); |
| 122 | + PubSubClient(uint8_t *, uint16_t, Client& client); |
| 123 | + PubSubClient(uint8_t *, uint16_t, Client& client, Stream&); |
| 124 | + PubSubClient(uint8_t *, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client); |
| 125 | + PubSubClient(uint8_t *, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&); |
| 126 | + PubSubClient(const char*, uint16_t, Client& client); |
| 127 | + PubSubClient(const char*, uint16_t, Client& client, Stream&); |
| 128 | + PubSubClient(const char*, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client); |
| 129 | + PubSubClient(const char*, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&); |
| 130 | + |
| 131 | + ~PubSubClient(); |
| 132 | + |
| 133 | + PubSubClient& setServer(IPAddress ip, uint16_t port); |
| 134 | + PubSubClient& setServer(uint8_t * ip, uint16_t port); |
| 135 | + PubSubClient& setServer(const char * domain, uint16_t port); |
| 136 | + PubSubClient& setCallback(MQTT_CALLBACK_SIGNATURE); |
| 137 | + PubSubClient& setClient(Client& client); |
| 138 | + PubSubClient& setStream(Stream& stream); |
| 139 | + PubSubClient& setKeepAlive(uint16_t keepAlive); |
| 140 | + PubSubClient& setSocketTimeout(uint16_t timeout); |
| 141 | + |
| 142 | + boolean setBufferSize(uint16_t size); |
| 143 | + uint16_t getBufferSize(); |
| 144 | + |
| 145 | + boolean connect(const char* id); |
| 146 | + boolean connect(const char* id, const char* user, const char* pass); |
| 147 | + boolean connect(const char* id, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage); |
| 148 | + boolean connect(const char* id, const char* user, const char* pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage); |
| 149 | + boolean connect(const char* id, const char* user, const char* pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage, boolean cleanSession); |
| 150 | + void disconnect(); |
| 151 | + boolean publish(const char* topic, const char* payload); |
| 152 | + boolean publish(const char* topic, const char* payload, boolean retained); |
| 153 | + boolean publish(const char* topic, const uint8_t * payload, unsigned int plength); |
| 154 | + boolean publish(const char* topic, const uint8_t * payload, unsigned int plength, boolean retained); |
| 155 | + boolean publish_P(const char* topic, const char* payload, boolean retained); |
| 156 | + boolean publish_P(const char* topic, const uint8_t * payload, unsigned int plength, boolean retained); |
| 157 | + // Start to publish a message. |
| 158 | + // This API: |
| 159 | + // beginPublish(...) |
| 160 | + // one or more calls to write(...) |
| 161 | + // endPublish() |
| 162 | + // Allows for arbitrarily large payloads to be sent without them having to be copied into |
| 163 | + // a new buffer and held in memory at one time |
| 164 | + // Returns 1 if the message was started successfully, 0 if there was an error |
| 165 | + boolean beginPublish(const char* topic, unsigned int plength, boolean retained); |
| 166 | + // Finish off this publish message (started with beginPublish) |
| 167 | + // Returns 1 if the packet was sent successfully, 0 if there was an error |
| 168 | + int endPublish(); |
| 169 | + // Write a single byte of payload (only to be used with beginPublish/endPublish) |
| 170 | + virtual size_t write(uint8_t); |
| 171 | + // Write size bytes from buffer into the payload (only to be used with beginPublish/endPublish) |
| 172 | + // Returns the number of bytes written |
| 173 | + virtual size_t write(const uint8_t *buffer, size_t size); |
| 174 | + boolean subscribe(const char* topic); |
| 175 | + boolean subscribe(const char* topic, uint8_t qos); |
| 176 | + boolean unsubscribe(const char* topic); |
| 177 | + boolean loop(); |
| 178 | + boolean connected(); |
| 179 | + int state(); |
| 180 | + |
| 181 | +}; |
| 182 | + |
| 183 | + |
| 184 | +#endif |
0 commit comments