PubSubClient
MQTT client library for Arduino
MQTT.h
1 /*
2 MQTT.h - MQTT packet classes
3 Copyright (C) 2015 Ian Tester
4 
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9 
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14 
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19 
20 #pragma once
21 
22 #include <stdint.h>
23 #ifdef ESP8266
24 #include <pgmspace.h>
25 #include <functional>
26 #endif
27 #include <Client.h>
28 
29 // MQTT_KEEPALIVE : keepAlive interval in Seconds
30 #define MQTT_KEEPALIVE 15
31 
32 class PubSubClient;
33 
35 namespace MQTT {
36 
37  enum message_type {
38  None,
39  CONNECT, // Client request to connect to Server
40  CONNACK, // Connect Acknowledgment
41  PUBLISH, // Publish message
42  PUBACK, // Publish Acknowledgment
43  PUBREC, // Publish Received (assured delivery part 1)
44  PUBREL, // Publish Release (assured delivery part 2)
45  PUBCOMP, // Publish Complete (assured delivery part 3)
46  SUBSCRIBE, // Client Subscribe request
47  SUBACK, // Subscribe Acknowledgment
48  UNSUBSCRIBE, // Client Unsubscribe request
49  UNSUBACK, // Unsubscribe Acknowledgment
50  PINGREQ, // PING Request
51  PINGRESP, // PING Response
52  DISCONNECT, // Client is Disconnecting
53  Reserved, // Reserved
54  };
55 
56 #ifdef _GLIBCXX_FUNCTIONAL
57  typedef std::function<bool(Client&)> payload_callback_t;
58 #else
59  typedef bool(*payload_callback_t)(Client&);
60 #endif
61 
63  class Message {
64  protected:
65  message_type _type;
66  uint8_t _flags;
67  uint16_t _packet_id;
69  Client* _stream_client;
70  payload_callback_t _payload_callback;
71 
73  Message(message_type t, uint8_t f = 0) :
74  _type(t), _flags(f),
75  _packet_id(0), _need_packet_id(false),
76  _stream_client(NULL)
77  {}
78 
80  virtual ~Message() {}
81 
83 
86  uint8_t fixed_header_length(uint32_t rlength) const;
87 
89 
94  void write_fixed_header(uint8_t *buf, uint32_t& bufpos, uint32_t rlength) const;
95 
97  bool need_packet_id(void) const { return _need_packet_id; }
98 
100  void set_packet_id(uint16_t pid) { _packet_id = pid; }
101 
103  uint16_t packet_id(void) const { return _packet_id; }
104 
106 
110  void write_packet_id(uint8_t *buf, uint32_t& bufpos) const;
111 
113  virtual uint32_t variable_header_length(void) const { return 0; }
114 
116 
120  virtual void write_variable_header(uint8_t *buf, uint32_t& bufpos) const { }
121 
123  virtual uint32_t payload_length(void) const { return 0; }
124 
126 
130  virtual void write_payload(uint8_t *buf, uint32_t& bufpos) const { }
131 
133  virtual message_type response_type(void) const { return None; }
134 
135  friend PubSubClient; // Just to allow it to call response_type()
136 
137  public:
139  bool send(Client& client);
140 
142  message_type type(void) const { return _type; }
143 
145  bool has_stream(void) const { return _stream_client != NULL; }
146 
147  };
148 
150 
153  Message* readPacket(Client& client);
154 
155 
157  class Connect : public Message {
158  private:
159  bool _clean_session;
160  uint8_t _will_qos;
161  bool _will_retain;
162 
163  String _clientid;
164  String _will_topic;
165  String _will_message;
166  String _username, _password;
167 
168  uint16_t _keepalive;
169 
170  uint32_t variable_header_length(void) const;
171  void write_variable_header(uint8_t *buf, uint32_t& bufpos) const;
172  uint32_t payload_length(void) const;
173  void write_payload(uint8_t *buf, uint32_t& bufpos) const;
174 
175  message_type response_type(void) const { return CONNACK; }
176 
177  public:
179  Connect(String cid);
180 
182  Connect& set_clean_session(bool cs = true) { _clean_session = cs; return *this; }
184  Connect& unset_clean_session(void) { _clean_session = false; return *this; }
185 
187  Connect& set_will(String willTopic, String willMessage, uint8_t willQos = 0, bool willRetain = false) {
188  _will_topic = willTopic; _will_message = willMessage; _will_qos = willQos; _will_retain = willRetain;
189  return *this;
190  }
192  Connect& unset_will(void) { _will_topic = ""; return *this; }
193 
195  Connect& set_auth(String u, String p) { _username = u; _password = p; return *this; }
197  Connect& unset_auth(void) { _username = ""; _password = ""; return *this; }
198 
200  uint16_t keepalive(void) const { return _keepalive; }
202  Connect& set_keepalive(uint16_t k) { _keepalive = k; return *this; }
203 
204  };
205 
206 
208  class ConnectAck : public Message {
209  private:
210  bool _session_present;
211  uint8_t _rc;
212 
214  ConnectAck(uint8_t* data, uint32_t length);
215 
216  friend Message* readPacket(Client& client);
217  };
218 
219 
221  class Publish : public Message {
222  private:
223  String _topic;
224  uint8_t *_payload;
225  uint32_t _payload_len;
226  bool _payload_mine;
227 
228  uint32_t variable_header_length(void) const;
229  void write_variable_header(uint8_t *buf, uint32_t& bufpos) const;
230  uint32_t payload_length(void) const;
231  void write_payload(uint8_t *buf, uint32_t& bufpos) const;
232 
233  message_type response_type(void) const;
234 
236  Publish(String topic, uint8_t* payload, uint32_t length, bool mine) :
237  Message(PUBLISH),
238  _topic(topic),
239  _payload(payload), _payload_len(length),
240  _payload_mine(mine)
241  {}
242 
244  Publish(uint8_t flags, uint8_t* data, uint32_t length);
245 
247  Publish(uint8_t flags, Client& client, uint32_t remaining_length);
248 
249  friend Message* readPacket(Client& client);
250 
251  public:
253 
257  Publish(String topic, String payload);
258 
260 
265  Publish(String topic, uint8_t* payload, uint32_t length) :
266  Publish(topic, payload, length, false)
267  {}
268 
270 
275  Publish(String topic, payload_callback_t pcb, uint32_t length);
276 
278  Publish(String topic, const __FlashStringHelper* payload);
279 
280  friend Publish Publish_P(String topic, PGM_P payload, uint32_t length);
281 
282  ~Publish();
283 
285  bool retain(void) const { return _flags & 0x01; }
287  Publish& set_retain(bool r = true) { _flags = (_flags & ~0x01) | r; return *this; }
289  Publish& unset_retain(void) { _flags = _flags & ~0x01; return *this; }
290 
292  uint8_t qos(void) const { return (_flags >> 1) & 0x03; }
294  Publish& set_qos(uint8_t q);
296  Publish& unset_qos(void) { _flags &= ~0x06; _need_packet_id = false; return *this; }
297 
299  bool dup(void) const { return (_flags >> 3) & 0x01; }
301  Publish& set_dup(bool d = true) { _flags = (_flags & ~0x08) | (d ? 0x08 : 0); return *this; }
303  Publish& unset_dup(void) { _flags = _flags & ~0x08; return *this; }
304 
306  String topic(void) const { return _topic; }
307 
309  String payload_string(void) const;
310 
312  uint8_t* payload(void) const { return _payload; }
314  uint32_t payload_len(void) const { return _payload_len; }
315 
317  Client* payload_stream(void) const { return _stream_client; }
318  };
319 
321  Publish Publish_P(String topic, PGM_P payload, uint32_t length);
322 
323 
325  class PublishAck : public Message {
326  private:
328  PublishAck(uint8_t* data, uint32_t length);
329 
330  friend Message* readPacket(Client& client);
331 
332  public:
334  PublishAck(uint16_t pid);
335 
336  };
337 
338 
340  class PublishRec : public Message {
341  private:
342  uint32_t variable_header_length(void) const;
343  void write_variable_header(uint8_t *buf, uint32_t& bufpos) const;
344 
345  message_type response_type(void) const { return PUBREL; }
346 
348  PublishRec(uint8_t* data, uint32_t length);
349 
350  friend Message* readPacket(Client& client);
351 
352  public:
354  PublishRec(uint16_t pid);
355 
356  };
357 
358 
360  class PublishRel : public Message {
361  private:
362  uint32_t variable_header_length(void) const;
363  void write_variable_header(uint8_t *buf, uint32_t& bufpos) const;
364 
365  message_type response_type(void) const { return PUBCOMP; }
366 
368  PublishRel(uint8_t* data, uint32_t length);
369 
370  friend Message* readPacket(Client& client);
371 
372  public:
374  PublishRel(uint16_t pid);
375 
376  };
377 
378 
380  class PublishComp : public Message {
381  private:
382  uint32_t variable_header_length(void) const;
383  void write_variable_header(uint8_t *buf, uint32_t& bufpos) const;
384 
386  PublishComp(uint8_t* data, uint32_t length);
387 
388  friend Message* readPacket(Client& client);
389 
390  public:
392  PublishComp(uint16_t pid);
393 
394  };
395 
396 
398  class Subscribe : public Message {
399  private:
400  uint8_t *_buffer;
401  uint32_t _buflen;
402 
403  uint32_t variable_header_length(void) const;
404  void write_variable_header(uint8_t *buf, uint32_t& bufpos) const;
405  uint32_t payload_length(void) const;
406  void write_payload(uint8_t *buf, uint32_t& bufpos) const;
407 
408  message_type response_type(void) const { return SUBACK; }
409 
410  public:
412  Subscribe();
413 
415  Subscribe(String topic, uint8_t qos = 0);
416 
417  ~Subscribe();
418 
420  Subscribe& add_topic(String topic, uint8_t qos = 0);
421 
422  };
423 
424 
426  class SubscribeAck : public Message {
427  private:
428  uint8_t *_rcs;
429  uint32_t _num_rcs;
430 
432  SubscribeAck(uint8_t* data, uint32_t length);
433 
435  SubscribeAck(Client& client, uint32_t remaining_length);
436 
437  friend Message* readPacket(Client& client);
438 
439  public:
440  ~SubscribeAck();
441 
443  uint32_t num_rcs(void) const { return _num_rcs; }
444 
446  uint8_t rc(uint8_t i) const { return _rcs[i]; }
447 
449  uint8_t next_rc(void) const;
450 
451  };
452 
453 
455  class Unsubscribe : public Message {
456  private:
457  uint8_t *_buffer;
458  uint32_t _buflen;
459 
460  uint32_t variable_header_length(void) const;
461  void write_variable_header(uint8_t *buf, uint32_t& bufpos) const;
462  uint32_t payload_length(void) const;
463  void write_payload(uint8_t *buf, uint32_t& bufpos) const;
464 
465  message_type response_type(void) const { return UNSUBACK; }
466 
467  public:
469  Unsubscribe();
470 
472  Unsubscribe(String topic);
473 
474  ~Unsubscribe();
475 
477  Unsubscribe& add_topic(String topic);
478 
479  };
480 
481 
483  class UnsubscribeAck : public Message {
484  private:
486  UnsubscribeAck(uint8_t* data, uint32_t length);
487 
488  friend Message* readPacket(Client& client);
489 
490  };
491 
492 
494  class Ping : public Message {
495  private:
496  message_type response_type(void) const { return PINGRESP; }
497 
498  public:
500  Ping() :
501  Message(PINGREQ)
502  {}
503 
504  };
505 
506 
508  class PingResp : public Message {
509  public:
512  Message(PINGRESP)
513  {}
514 
515  };
516 
517 
519  class Disconnect : public Message {
520  public:
523  Message(DISCONNECT)
524  {}
525 
526  };
527 
528 }
529 
Main do-everything class that sketches will use.
Definition: PubSubClient.h:20
String topic(void) const
Get the topic string.
Definition: MQTT.h:306
Unsubscribe()
Constructor that starts with an empty list of unsubscriptions.
Definition: MQTT.cpp:653
friend Message * readPacket(Client &client)
Parser.
Definition: MQTT.cpp:180
friend Publish Publish_P(String topic, PGM_P payload, uint32_t length)
A function made to look like a constructor, reading the payload from flash.
Definition: MQTT.cpp:373
Subscribe & add_topic(String topic, uint8_t qos=0)
Add another topic and optional QoS level.
Definition: MQTT.cpp:589
uint8_t rc(uint8_t i) const
Get a return code.
Definition: MQTT.h:446
Subscribe to one or more topics.
Definition: MQTT.h:398
virtual uint32_t variable_header_length(void) const
Length of variable header.
Definition: MQTT.h:113
bool dup(void) const
Get dup flag.
Definition: MQTT.h:299
Disconnect from the broker.
Definition: MQTT.h:519
Disconnect()
Constructor.
Definition: MQTT.h:522
bool send(Client &client)
Send the message out.
Definition: MQTT.cpp:143
uint32_t num_rcs(void) const
Get the number of return codes available.
Definition: MQTT.h:443
message_type type(void) const
Get the message type.
Definition: MQTT.h:142
virtual void write_variable_header(uint8_t *buf, uint32_t &bufpos) const
Write variable header.
Definition: MQTT.h:120
Response to Unsubscribe.
Definition: MQTT.h:483
bool _need_packet_id
Not all message types use a packet id, but most do.
Definition: MQTT.h:68
Response to Ping.
Definition: MQTT.h:508
Publish & set_dup(bool d=true)
Set dup flag.
Definition: MQTT.h:301
void write_fixed_header(uint8_t *buf, uint32_t &bufpos, uint32_t rlength) const
Write the fixed header to a buffer.
Definition: MQTT.cpp:115
uint16_t keepalive(void) const
Get the keepalive period.
Definition: MQTT.h:200
Subscribe()
Constructor that starts an empty list of subscriptions.
Definition: MQTT.cpp:568
Connect(String cid)
Connect with a client ID.
Definition: MQTT.cpp:269
virtual uint32_t payload_length(void) const
Length of payload.
Definition: MQTT.h:123
Message sent when connecting to a broker.
Definition: MQTT.h:157
friend Message * readPacket(Client &client)
Parser.
Definition: MQTT.cpp:180
virtual ~Message()
Virtual destructor.
Definition: MQTT.h:80
Message(message_type t, uint8_t f=0)
Private constructor from type and flags.
Definition: MQTT.h:73
uint8_t fixed_header_length(uint32_t rlength) const
Length of the fixed header.
Definition: MQTT.cpp:104
Response to PublishRel.
Definition: MQTT.h:380
Unsubscribe from one or more topics.
Definition: MQTT.h:455
Publish & unset_dup(void)
Unset dup flag.
Definition: MQTT.h:303
Connect & set_auth(String u, String p)
Set the username and password for authentication.
Definition: MQTT.h:195
Publish(String topic, uint8_t *payload, uint32_t length)
Constructor from arbitrary payload.
Definition: MQTT.h:265
friend Message * readPacket(Client &client)
Parser.
Definition: MQTT.cpp:180
Response to PublishRec.
Definition: MQTT.h:360
virtual void write_payload(uint8_t *buf, uint32_t &bufpos) const
Write payload.
Definition: MQTT.h:130
Response to Subscribe.
Definition: MQTT.h:426
Publish Publish_P(String topic, PGM_P payload, uint32_t length)
A function made to look like a constructor, reading the payload from flash.
Definition: MQTT.cpp:373
Response to Connect.
Definition: MQTT.h:208
Client * payload_stream(void) const
Get the network stream for reading the payload.
Definition: MQTT.h:317
friend Message * readPacket(Client &client)
Parser.
Definition: MQTT.cpp:180
Response to Publish when qos == 1.
Definition: MQTT.h:325
Connect & unset_will(void)
Unset the "will" flag and associated attributes.
Definition: MQTT.h:192
friend Message * readPacket(Client &client)
Parser.
Definition: MQTT.cpp:180
Publish & unset_retain(void)
Unset retain flag.
Definition: MQTT.h:289
Ping the broker.
Definition: MQTT.h:494
void set_packet_id(uint16_t pid)
Set the packet id.
Definition: MQTT.h:100
bool need_packet_id(void) const
Does this message need a packet id before being sent?
Definition: MQTT.h:97
Connect & set_clean_session(bool cs=true)
Set the "clear session" flag.
Definition: MQTT.h:182
Publish a payload to a topic.
Definition: MQTT.h:221
uint16_t packet_id(void) const
Get the packet id.
Definition: MQTT.h:103
Unsubscribe & add_topic(String topic)
Add another topic to unsubscribe from.
Definition: MQTT.cpp:673
bool retain(void) const
Get retain flag.
Definition: MQTT.h:285
Publish & set_qos(uint8_t q)
Set QoS value.
Definition: MQTT.cpp:431
String payload_string(void) const
Get the payload as a string.
Definition: MQTT.cpp:443
bool has_stream(void) const
Does this message have a network stream for reading the (large) payload?
Definition: MQTT.h:145
uint32_t payload_len(void) const
Get the payload length.
Definition: MQTT.h:314
PingResp()
Constructor.
Definition: MQTT.h:511
Publish & set_retain(bool r=true)
Set retain flag.
Definition: MQTT.h:287
friend Message * readPacket(Client &client)
Parser.
Definition: MQTT.cpp:180
uint8_t * payload(void) const
Get the payload pointer.
Definition: MQTT.h:312
Connect & set_will(String willTopic, String willMessage, uint8_t willQos=0, bool willRetain=false)
Set the "will" flag and associated attributes.
Definition: MQTT.h:187
First response to Publish when qos == 2.
Definition: MQTT.h:340
Publish & unset_qos(void)
Unset QoS value.
Definition: MQTT.h:296
Abstract base class.
Definition: MQTT.h:63
Ping()
Constructor.
Definition: MQTT.h:500
Connect & set_keepalive(uint16_t k)
Set the keepalive period.
Definition: MQTT.h:202
friend Message * readPacket(Client &client)
Parser.
Definition: MQTT.cpp:180
uint8_t next_rc(void) const
Get the next return code from a stream.
Definition: MQTT.cpp:647
void write_packet_id(uint8_t *buf, uint32_t &bufpos) const
Write the packet id to a buffer.
Definition: MQTT.cpp:139
uint8_t qos(void) const
Get QoS value.
Definition: MQTT.h:292
Message * readPacket(Client &client)
Parser.
Definition: MQTT.cpp:180
friend Message * readPacket(Client &client)
Parser.
Definition: MQTT.cpp:180
virtual message_type response_type(void) const
Message type to expect in response to this message.
Definition: MQTT.h:133
Connect & unset_clean_session(void)
Unset the "clear session" flag.
Definition: MQTT.h:184
Connect & unset_auth(void)
Unset the username and password for authentication.
Definition: MQTT.h:197
namespace for classes representing MQTT messages
Definition: MQTT.cpp:23