| 2 |
raymond |
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 15
|
|
|
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
|