mqtt_client_packet.c
Go to the documentation of this file.
1 /**
2  * @file mqtt_client_packet.c
3  * @brief MQTT packet parsing and formatting
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2020 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 1.9.8
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL MQTT_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/net.h"
36 #include "mqtt/mqtt_client.h"
39 #include "mqtt/mqtt_client_misc.h"
40 #include "debug.h"
41 
42 //Check TCP/IP stack configuration
43 #if (MQTT_CLIENT_SUPPORT == ENABLED)
44 
45 //MQTT control packets
46 static const char_t *packetLabel[16] =
47 {
48  "Reserved", //0
49  "CONNECT", //1
50  "CONNACK", //2
51  "PUBLISH", //3
52  "PUBACK", //4
53  "PUBREC", //5
54  "PUBREL", //6
55  "PUBCOMP", //7
56  "SUBSCRIBE", //8
57  "SUBACK", //9
58  "UNSUBSCRIBE", //10
59  "UNSUBACK", //11
60  "PINGREQ", //12
61  "PINGRESP", //13
62  "DISCONNECT", //14
63  "Reserved" //15
64 };
65 
66 
67 /**
68  * @brief Receive MQTT packet
69  * @param[in] context Pointer to the MQTT client context
70  * @return Error code
71  **/
72 
74 {
75  error_t error;
76  size_t n;
77  uint8_t value;
78 
79  //Initialize status code
80  error = NO_ERROR;
81 
82  //Receive incoming packet
83  while(1)
84  {
85  //Packet header is being received?
86  if(context->packetLen == 0)
87  {
88  //Read a single byte
89  error = mqttClientReceiveData(context, &value, sizeof(uint8_t), &n, 0);
90 
91  //Any data received?
92  if(!error)
93  {
94  //Save the current byte
95  context->packet[context->packetPos] = value;
96 
97  //The Remaining Length is encoded using a variable length encoding scheme
98  if(context->packetPos > 0)
99  {
100  //The most significant bit is used to indicate that there are
101  //following bytes in the representation
102  if(value & 0x80)
103  {
104  //Applications can send control packets of size up to 256 MB
105  if(context->packetPos < 4)
106  {
107  //The least significant seven bits of each byte encode the data
108  context->remainingLen |= (value & 0x7F) << (7 * (context->packetPos - 1));
109  }
110  else
111  {
112  //Report an error
113  error = ERROR_INVALID_SYNTAX;
114  }
115  }
116  else
117  {
118  //The least significant seven bits of each byte encode the data
119  context->remainingLen |= value << (7 * (context->packetPos - 1));
120  //Calculate the length of the control packet
121  context->packetLen = context->packetPos + 1 + context->remainingLen;
122 
123  //Sanity check
124  if(context->packetLen > MQTT_CLIENT_BUFFER_SIZE)
125  error = ERROR_INVALID_LENGTH;
126  }
127  }
128 
129  //Advance data pointer
130  context->packetPos++;
131  }
132  }
133  //Variable header or payload is being received?
134  else
135  {
136  //Any remaining data?
137  if(context->packetPos < context->packetLen)
138  {
139  //Read more data
140  error = mqttClientReceiveData(context, context->packet + context->packetPos,
141  context->packetLen - context->packetPos, &n, 0);
142 
143  //Advance data pointer
144  context->packetPos += n;
145  }
146  else
147  {
148  //The packet has been successfully received
149  break;
150  }
151  }
152 
153  //Any error to report?
154  if(error)
155  break;
156  }
157 
158  //Return status code
159  return error;
160 }
161 
162 
163 /**
164  * @brief Process incoming MQTT packet
165  * @param[in] context Pointer to the MQTT client context
166  * @return Error code
167  **/
168 
170 {
171  error_t error;
172  bool_t dup;
173  bool_t retain;
174  size_t remainingLen;
177 
178  //Point to the first byte of the packet
179  context->packetPos = 0;
180 
181  //Read the fixed header from the input buffer
182  error = mqttDeserializeHeader(context->packet, context->packetLen,
183  &context->packetPos, &type, &dup, &qos, &retain, &remainingLen);
184 
185  //Failed to deserialize fixed header?
186  if(error)
187  return error;
188 
189  //Debug message
190  TRACE_INFO("MQTT: %s packet received (%" PRIuSIZE " bytes)...\r\n",
191  packetLabel[type], context->packetLen);
192 
193  //Dump the contents of the packet
194  TRACE_DEBUG_ARRAY(" ", context->packet, context->packetLen);
195 
196  //Check MQTT control packet type
197  switch(type)
198  {
199  //CONNACK packet received?
201  //Process incoming CONNACK packet
202  error = mqttClientProcessConnAck(context, dup, qos, retain, remainingLen);
203  break;
204  //PUBLISH packet received?
206  //Process incoming PUBLISH packet
207  error = mqttClientProcessPublish(context, dup, qos, retain, remainingLen);
208  break;
209  //PUBACK packet received?
211  //Process incoming PUBACK packet
212  error = mqttClientProcessPubAck(context, dup, qos, retain, remainingLen);
213  break;
214  //PUBREC packet received?
216  //Process incoming PUBREC packet
217  error = mqttClientProcessPubRec(context, dup, qos, retain, remainingLen);
218  break;
219  //PUBREL packet received?
221  //Process incoming PUBREL packet
222  error = mqttClientProcessPubRel(context, dup, qos, retain, remainingLen);
223  break;
224  //PUBCOMP packet received?
226  //Process incoming PUBCOMP packet
227  error = mqttClientProcessPubComp(context, dup, qos, retain, remainingLen);
228  break;
229  //SUBACK packet received?
231  //Process incoming SUBACK packet
232  error = mqttClientProcessSubAck(context, dup, qos, retain, remainingLen);
233  break;
234  //UNSUBACK packet received?
236  //Process incoming UNSUBACK packet
237  error = mqttClientProcessUnsubAck(context, dup, qos, retain, remainingLen);
238  break;
239  //PINGRESP packet received?
241  //Process incoming PINGRESP packet
242  error = mqttClientProcessPingResp(context, dup, qos, retain, remainingLen);
243  break;
244  //Unknown packet received?
245  default:
246  //Report an error
247  error = ERROR_INVALID_PACKET;
248  }
249 
250  //Return status code
251  return error;
252 }
253 
254 
255 /**
256  * @brief Process incoming CONNACK packet
257  * @param[in] context Pointer to the MQTT client context
258  * @param[in] dup DUP flag from the fixed header
259  * @param[in] qos QoS field from the fixed header
260  * @param[in] retain RETAIN flag from the fixed header
261  * @param[in] remainingLen Length of the variable header and the payload
262  **/
263 
265  bool_t dup, MqttQosLevel qos, bool_t retain, size_t remainingLen)
266 {
267  error_t error;
268  uint8_t connectAckFlags;
269  uint8_t connectReturnCode;
270 
271  //If invalid flags are received, the receiver must close the network connection
272  if(dup != FALSE && qos != MQTT_QOS_LEVEL_0 && retain != FALSE)
273  return ERROR_INVALID_PACKET;
274 
275  //The first byte of the variable header is the Connect Acknowledge Flags
276  error = mqttDeserializeByte(context->packet, context->packetLen,
277  &context->packetPos, &connectAckFlags);
278 
279  //Failed to deserialize the Connect Acknowledge Flags?
280  if(error)
281  return error;
282 
283  //The second byte of the variable header is the Connect Return Code
284  error = mqttDeserializeByte(context->packet, context->packetLen,
285  &context->packetPos, &connectReturnCode);
286 
287  //Failed to deserialize the Connect Return Code?
288  if(error)
289  return error;
290 
291  //Any registered callback?
292  if(context->callbacks.connAckCallback != NULL)
293  {
294  //Invoke user callback function
295  context->callbacks.connAckCallback(context,
296  connectAckFlags, connectReturnCode);
297  }
298 
299  //Make sure the connection is accepted
300  if(connectReturnCode != MQTT_CONNECT_RET_CODE_ACCEPTED)
302 
303  //Notify the application that a CONNACK packet has been received
304  if(context->packetType == MQTT_PACKET_TYPE_CONNECT)
306 
307  //Successful processing
308  return NO_ERROR;
309 }
310 
311 
312 /**
313  * @brief Process incoming PUBLISH packet
314  * @param[in] context Pointer to the MQTT client context
315  * @param[in] dup DUP flag from the fixed header
316  * @param[in] qos QoS field from the fixed header
317  * @param[in] retain RETAIN flag from the fixed header
318  * @param[in] remainingLen Length of the variable header and the payload
319  **/
320 
322  bool_t dup, MqttQosLevel qos, bool_t retain, size_t remainingLen)
323 {
324  error_t error;
325  uint16_t packetId;
326  char_t *topic;
327  size_t topicLen;
328  uint8_t *message;
329  size_t messageLen;
330 
331  //The Topic Name must be present as the first field in the PUBLISH
332  //packet variable header
333  error = mqttDeserializeString(context->packet, context->packetLen,
334  &context->packetPos, &topic, &topicLen);
335 
336  //Failed to deserialize Topic Name?
337  if(error)
338  return error;
339 
340  //Check QoS level
341  if(qos != MQTT_QOS_LEVEL_0)
342  {
343  //The Packet Identifier field is only present in PUBLISH packets
344  //where the QoS level is 1 or 2
345  error = mqttDeserializeShort(context->packet, context->packetLen,
346  &context->packetPos, &packetId);
347 
348  //Failed to deserialize Packet Identifier field?
349  if(error)
350  return error;
351  }
352  else
353  {
354  //No packet identifier
355  packetId = 0;
356  }
357 
358  //The payload contains the Application Message that is being published
359  message = context->packet + context->packetPos;
360 
361  //The length of the payload can be calculated by subtracting the length of the
362  //variable header from the Remaining Length field that is in the fixed header
363  messageLen = context->packetLen - context->packetPos;
364 
365  //Make room for the NULL character at the end of the Topic Name
366  osMemmove(topic - 1, topic, topicLen);
367  //Properly terminate the string with a NULL character
368  topic[topicLen - 1] = '\0';
369  //Point to the first character of the Topic Name
370  topic--;
371 
372  //Any registered callback?
373  if(context->callbacks.publishCallback != NULL)
374  {
375  //Invoke user callback function
376  context->callbacks.publishCallback(context, topic,
377  message, messageLen, dup, qos, retain, packetId);
378  }
379 
380  //Check QoS level
381  if(qos == MQTT_QOS_LEVEL_1)
382  {
383  //A PUBACK packet is the response to a PUBLISH packet with QoS level 1
384  error = mqttClientFormatPubAck(context, packetId);
385 
386  //Check status code
387  if(!error)
388  {
389  //Debug message
390  TRACE_INFO("MQTT: Sending PUBACK packet (%" PRIuSIZE " bytes)...\r\n", context->packetLen);
391  TRACE_DEBUG_ARRAY(" ", context->packet, context->packetLen);
392 
393  //Point to the beginning of the packet
394  context->packetPos = 0;
395 
396  //Send PUBACK packet
398  }
399  }
400  else if(qos == MQTT_QOS_LEVEL_2)
401  {
402  //A PUBREC packet is the response to a PUBLISH packet with QoS 2. It is
403  //the second packet of the QoS 2 protocol exchange
404  error = mqttClientFormatPubRec(context, packetId);
405 
406  //Check status code
407  if(!error)
408  {
409  //Debug message
410  TRACE_INFO("MQTT: Sending PUBREC packet (%" PRIuSIZE " bytes)...\r\n", context->packetLen);
411  TRACE_DEBUG_ARRAY(" ", context->packet, context->packetLen);
412 
413  //Point to the beginning of the packet
414  context->packetPos = 0;
415 
416  //Send PUBREC packet
418  }
419  }
420 
421  //Return status code
422  return error;
423 }
424 
425 
426 /**
427  * @brief Process incoming PUBACK packet
428  * @param[in] context Pointer to the MQTT client context
429  * @param[in] dup DUP flag from the fixed header
430  * @param[in] qos QoS field from the fixed header
431  * @param[in] retain RETAIN flag from the fixed header
432  * @param[in] remainingLen Length of the variable header and the payload
433  **/
434 
436  bool_t dup, MqttQosLevel qos, bool_t retain, size_t remainingLen)
437 {
438  error_t error;
439  uint16_t packetId;
440 
441  //If invalid flags are received, the receiver must close the network connection
442  if(dup != FALSE && qos != MQTT_QOS_LEVEL_0 && retain != FALSE)
443  return ERROR_INVALID_PACKET;
444 
445  //The variable header contains the Packet Identifier from the PUBLISH
446  //packet that is being acknowledged
447  error = mqttDeserializeShort(context->packet, context->packetLen,
448  &context->packetPos, &packetId);
449 
450  //Failed to deserialize Packet Identifier field?
451  if(error)
452  return error;
453 
454  //Any registered callback?
455  if(context->callbacks.pubAckCallback != NULL)
456  {
457  //Invoke user callback function
458  context->callbacks.pubAckCallback(context, packetId);
459  }
460 
461  //Notify the application that a PUBACK packet has been received
462  if(context->packetType == MQTT_PACKET_TYPE_PUBLISH && context->packetId == packetId)
464 
465  //Return status code
466  return error;
467 }
468 
469 
470 /**
471  * @brief Process incoming PUBREC packet
472  * @param[in] context Pointer to the MQTT client context
473  * @param[in] dup DUP flag from the fixed header
474  * @param[in] qos QoS field from the fixed header
475  * @param[in] retain RETAIN flag from the fixed header
476  * @param[in] remainingLen Length of the variable header and the payload
477  **/
478 
480  bool_t dup, MqttQosLevel qos, bool_t retain, size_t remainingLen)
481 {
482  error_t error;
483  uint16_t packetId;
484 
485  //If invalid flags are received, the receiver must close the network connection
486  if(dup != FALSE && qos != MQTT_QOS_LEVEL_0 && retain != FALSE)
487  return ERROR_INVALID_PACKET;
488 
489  //The variable header contains the Packet Identifier from the PUBLISH
490  //packet that is being acknowledged
491  error = mqttDeserializeShort(context->packet, context->packetLen,
492  &context->packetPos, &packetId);
493 
494  //Failed to deserialize Packet Identifier field?
495  if(error)
496  return error;
497 
498  //Any registered callback?
499  if(context->callbacks.pubRecCallback != NULL)
500  {
501  //Invoke user callback function
502  context->callbacks.pubRecCallback(context, packetId);
503  }
504 
505  //A PUBREL packet is the response to a PUBREC packet. It is the third
506  //packet of the QoS 2 protocol exchange
507  error = mqttClientFormatPubRel(context, packetId);
508 
509  //Check status code
510  if(!error)
511  {
512  //Debug message
513  TRACE_INFO("MQTT: Sending PUBREL packet (%" PRIuSIZE " bytes)...\r\n", context->packetLen);
514  TRACE_DEBUG_ARRAY(" ", context->packet, context->packetLen);
515 
516  //Point to the beginning of the packet
517  context->packetPos = 0;
518 
519  //Send PUBREL packet
521  }
522 
523  //Return status code
524  return error;
525 }
526 
527 
528 /**
529  * @brief Process incoming PUBREL packet
530  * @param[in] context Pointer to the MQTT client context
531  * @param[in] dup DUP flag from the fixed header
532  * @param[in] qos QoS field from the fixed header
533  * @param[in] retain RETAIN flag from the fixed header
534  * @param[in] remainingLen Length of the variable header and the payload
535  **/
536 
538  bool_t dup, MqttQosLevel qos, bool_t retain, size_t remainingLen)
539 {
540  error_t error;
541  uint16_t packetId;
542 
543  //If invalid flags are received, the receiver must close the network connection
544  if(dup != FALSE && qos != MQTT_QOS_LEVEL_1 && retain != FALSE)
545  return ERROR_INVALID_PACKET;
546 
547  //The variable header contains the same Packet Identifier as the PUBREC
548  //packet that is being acknowledged
549  error = mqttDeserializeShort(context->packet, context->packetLen,
550  &context->packetPos, &packetId);
551 
552  //Failed to deserialize Packet Identifier field?
553  if(error)
554  return error;
555 
556  //Any registered callback?
557  if(context->callbacks.pubRelCallback != NULL)
558  {
559  //Invoke user callback function
560  context->callbacks.pubRelCallback(context, packetId);
561  }
562 
563  //A PUBCOMP packet is the response to a PUBREL packet. It is the fourth and
564  //final packet of the QoS 2 protocol exchange
565  error = mqttClientFormatPubComp(context, packetId);
566 
567  //Check status code
568  if(!error)
569  {
570  //Debug message
571  TRACE_INFO("MQTT: Sending PUBCOMP packet (%" PRIuSIZE " bytes)...\r\n", context->packetLen);
572  TRACE_DEBUG_ARRAY(" ", context->packet, context->packetLen);
573 
574  //Point to the beginning of the packet
575  context->packetPos = 0;
576 
577  //Send PUBCOMP packet
579  }
580 
581  //Return status code
582  return error;
583 }
584 
585 
586 /**
587  * @brief Process incoming PUBCOMP packet
588  * @param[in] context Pointer to the MQTT client context
589  * @param[in] dup DUP flag from the fixed header
590  * @param[in] qos QoS field from the fixed header
591  * @param[in] retain RETAIN flag from the fixed header
592  * @param[in] remainingLen Length of the variable header and the payload
593  **/
594 
596  bool_t dup, MqttQosLevel qos, bool_t retain, size_t remainingLen)
597 {
598  error_t error;
599  uint16_t packetId;
600 
601  //If invalid flags are received, the receiver must close the network connection
602  if(dup != FALSE && qos != MQTT_QOS_LEVEL_0 && retain != FALSE)
603  return ERROR_INVALID_PACKET;
604 
605  //The variable header contains the same Packet Identifier as the PUBREL
606  //packet that is being acknowledged
607  error = mqttDeserializeShort(context->packet, context->packetLen,
608  &context->packetPos, &packetId);
609 
610  //Failed to deserialize Packet Identifier field?
611  if(error)
612  return error;
613 
614  //Any registered callback?
615  if(context->callbacks.pubCompCallback != NULL)
616  {
617  //Invoke user callback function
618  context->callbacks.pubCompCallback(context, packetId);
619  }
620 
621  //Notify the application that a PUBCOMP packet has been received
622  if(context->packetType == MQTT_PACKET_TYPE_PUBLISH && context->packetId == packetId)
624 
625  //Successful processing
626  return NO_ERROR;
627 }
628 
629 
630 /**
631  * @brief Process incoming SUBACK packet
632  * @param[in] context Pointer to the MQTT client context
633  * @param[in] dup DUP flag from the fixed header
634  * @param[in] qos QoS field from the fixed header
635  * @param[in] retain RETAIN flag from the fixed header
636  * @param[in] remainingLen Length of the variable header and the payload
637  **/
638 
640  bool_t dup, MqttQosLevel qos, bool_t retain, size_t remainingLen)
641 {
642  error_t error;
643  uint16_t packetId;
644 
645  //If invalid flags are received, the receiver must close the network connection
646  if(dup != FALSE && qos != MQTT_QOS_LEVEL_0 && retain != FALSE)
647  return ERROR_INVALID_PACKET;
648 
649  //The variable header contains the Packet Identifier from the SUBSCRIBE
650  //packet that is being acknowledged
651  error = mqttDeserializeShort(context->packet, context->packetLen,
652  &context->packetPos, &packetId);
653 
654  //Failed to deserialize Packet Identifier field?
655  if(error)
656  return error;
657 
658  //Any registered callback?
659  if(context->callbacks.subAckCallback != NULL)
660  {
661  //Invoke user callback function
662  context->callbacks.subAckCallback(context, packetId);
663  }
664 
665  //Notify the application that a SUBACK packet has been received
666  if(context->packetType == MQTT_PACKET_TYPE_SUBSCRIBE && context->packetId == packetId)
668 
669  //Successful processing
670  return NO_ERROR;
671 }
672 
673 
674 /**
675  * @brief Process incoming UNSUBACK packet
676  * @param[in] context Pointer to the MQTT client context
677  * @param[in] dup DUP flag from the fixed header
678  * @param[in] qos QoS field from the fixed header
679  * @param[in] retain RETAIN flag from the fixed header
680  * @param[in] remainingLen Length of the variable header and the payload
681  **/
682 
684  bool_t dup, MqttQosLevel qos, bool_t retain, size_t remainingLen)
685 {
686  error_t error;
687  uint16_t packetId;
688 
689  //If invalid flags are received, the receiver must close the network connection
690  if(dup != FALSE && qos != MQTT_QOS_LEVEL_0 && retain != FALSE)
691  return ERROR_INVALID_PACKET;
692 
693  //The variable header contains the Packet Identifier from the UNSUBSCRIBE
694  //packet that is being acknowledged
695  error = mqttDeserializeShort(context->packet, context->packetLen,
696  &context->packetPos, &packetId);
697 
698  //Failed to deserialize Packet Identifier field?
699  if(error)
700  return error;
701 
702  //Any registered callback?
703  if(context->callbacks.unsubAckCallback != NULL)
704  {
705  //Invoke user callback function
706  context->callbacks.unsubAckCallback(context, packetId);
707  }
708 
709  //Notify the application that an UNSUBACK packet has been received
710  if(context->packetType == MQTT_PACKET_TYPE_UNSUBSCRIBE && context->packetId == packetId)
712 
713  //Successful processing
714  return NO_ERROR;
715 }
716 
717 
718 /**
719  * @brief Process incoming PINGRESP packet
720  * @param[in] context Pointer to the MQTT client context
721  * @param[in] dup DUP flag from the fixed header
722  * @param[in] qos QoS field from the fixed header
723  * @param[in] retain RETAIN flag from the fixed header
724  * @param[in] remainingLen Length of the variable header and the payload
725  **/
726 
728  bool_t dup, MqttQosLevel qos, bool_t retain, size_t remainingLen)
729 {
730  //If invalid flags are received, the receiver must close the network connection
731  if(dup != FALSE && qos != MQTT_QOS_LEVEL_0 && retain != FALSE)
732  return ERROR_INVALID_PACKET;
733 
734  //Any registered callback?
735  if(context->callbacks.pingRespCallback != NULL)
736  {
737  //Invoke user callback function
738  context->callbacks.pingRespCallback(context);
739  }
740 
741  //Notify the application that an PINGRESP packet has been received
742  if(context->packetType == MQTT_PACKET_TYPE_PINGREQ)
744 
745  //Successful processing
746  return NO_ERROR;
747 }
748 
749 
750 /**
751  * @brief Format CONNECT packet
752  * @param[in] context Pointer to the MQTT client context
753  * @param[in] cleanSession If this flag is set, then the client and server
754  * must discard any previous session and start a new one
755  * @return Error code
756  **/
757 
760 {
761  error_t error;
762  size_t n;
763  uint8_t connectFlags;
764  MqttClientWillMessage *willMessage;
765 
766  //Make room for the fixed header
768 
769  //Check protocol version
770  if(context->settings.version == MQTT_VERSION_3_1)
771  {
772  //The Protocol Name is a UTF-8 encoded string that represents the
773  //protocol name "MQIsdp"
774  error = mqttSerializeString(context->buffer, MQTT_CLIENT_BUFFER_SIZE,
776  }
777  else if(context->settings.version == MQTT_VERSION_3_1_1)
778  {
779  //The Protocol Name is a UTF-8 encoded string that represents the
780  //protocol name "MQTT"
781  error = mqttSerializeString(context->buffer, MQTT_CLIENT_BUFFER_SIZE,
783  }
784  else
785  {
786  //Invalid protocol level
787  error = ERROR_INVALID_VERSION;
788  }
789 
790  //Any error to report?
791  if(error)
792  return error;
793 
794  //The Protocol Level represents the revision level of the protocol
795  //used by the client
796  error = mqttSerializeByte(context->buffer, MQTT_CLIENT_BUFFER_SIZE,
797  &n, context->settings.version);
798 
799  //Failed to serialize data?
800  if(error)
801  return error;
802 
803  //The Connect Flags byte contains a number of parameters specifying
804  //the behavior of the MQTT connection
805  connectFlags = 0;
806 
807  //If CleanSession is set to 1, the client and server must discard any
808  //previous session and start a new one
809  if(cleanSession)
810  connectFlags |= MQTT_CONNECT_FLAG_CLEAN_SESSION;
811 
812  //If the client supplies a zero-byte Client Identifier, the client must
813  //also set CleanSession to 1
814  if(context->settings.clientId[0] == '\0')
815  connectFlags |= MQTT_CONNECT_FLAG_CLEAN_SESSION;
816 
817  //Point to the Will message
818  willMessage = &context->settings.willMessage;
819 
820  //Check whether a valid Will message has been specified
821  if(willMessage->topic[0] != '\0')
822  {
823  //Set the Will flag
824  connectFlags |= MQTT_CONNECT_FLAG_WILL;
825 
826  //Check the Will QoS level
827  if(willMessage->qos == MQTT_QOS_LEVEL_1)
828  connectFlags |= MQTT_CONNECT_FLAG_WILL_QOS_1;
829  else if(willMessage->qos == MQTT_QOS_LEVEL_2)
830  connectFlags |= MQTT_CONNECT_FLAG_WILL_QOS_2;
831 
832  //The Will Retain flag specifies if the Will Message is to be
833  //retained when it is published
834  if(willMessage->retain)
835  connectFlags |= MQTT_CONNECT_FLAG_WILL_RETAIN;
836  }
837 
838  //Check whether a valid user name has been specified
839  if(context->settings.username[0] != '\0')
840  connectFlags |= MQTT_CONNECT_FLAG_USERNAME;
841 
842  //Check whether a valid password has been specified
843  if(context->settings.password[0] != '\0')
844  connectFlags |= MQTT_CONNECT_FLAG_PASSWORD;
845 
846  //Write the Connect Flags to the output buffer
847  error = mqttSerializeByte(context->buffer, MQTT_CLIENT_BUFFER_SIZE,
848  &n, connectFlags);
849 
850  //Failed to serialize data?
851  if(error)
852  return error;
853 
854  //The Keep Alive is a time interval measured in seconds. It is the maximum
855  //time interval that is permitted to elapse between the point at which the
856  //client finishes transmitting one control packet and the point it starts
857  //sending the next
858  error = mqttSerializeShort(context->buffer, MQTT_CLIENT_BUFFER_SIZE,
859  &n, context->settings.keepAlive);
860 
861  //Failed to serialize data?
862  if(error)
863  return error;
864 
865  //The Client Identifier identifies the client to the server. The Client
866  //Identifier must be present and must be the first field in the CONNECT
867  //packet payload
868  error = mqttSerializeString(context->buffer, MQTT_CLIENT_BUFFER_SIZE,
869  &n, context->settings.clientId, osStrlen(context->settings.clientId));
870 
871  //Failed to serialize data?
872  if(error)
873  return error;
874 
875  //If the Will Flag is set to 1, the Will Topic is the next field in
876  //the payload
877  if(willMessage->topic[0] != '\0')
878  {
879  //Write the Will Topic to the output buffer
880  error = mqttSerializeString(context->buffer, MQTT_CLIENT_BUFFER_SIZE,
881  &n, willMessage->topic, osStrlen(willMessage->topic));
882 
883  //Failed to serialize data?
884  if(error)
885  return error;
886 
887  //Write the Will message to the output buffer
888  error = mqttSerializeString(context->buffer, MQTT_CLIENT_BUFFER_SIZE,
889  &n, willMessage->payload, willMessage->length);
890 
891  //Failed to serialize data?
892  if(error)
893  return error;
894  }
895 
896  //If the User Name Flag is set to 1, this is the next field in the payload
897  if(context->settings.username[0] != '\0')
898  {
899  //Write the User Name to the output buffer
900  error = mqttSerializeString(context->buffer, MQTT_CLIENT_BUFFER_SIZE,
901  &n, context->settings.username, osStrlen(context->settings.username));
902 
903  //Failed to serialize data?
904  if(error)
905  return error;
906  }
907 
908  //If the Password Flag is set to 1, this is the next field in the payload
909  if(context->settings.password[0] != '\0')
910  {
911  //Write the Password to the output buffer
912  error = mqttSerializeString(context->buffer, MQTT_CLIENT_BUFFER_SIZE,
913  &n, context->settings.password, osStrlen(context->settings.password));
914 
915  //Failed to serialize data?
916  if(error)
917  return error;
918  }
919 
920  //Calculate the length of the variable header and the payload
921  context->packetLen = n - MQTT_MAX_HEADER_SIZE;
922 
923  //The fixed header will be encoded in reverse order
925 
926  //Prepend the variable header and the payload with the fixed header
927  error = mqttSerializeHeader(context->buffer, &n, MQTT_PACKET_TYPE_CONNECT,
928  FALSE, MQTT_QOS_LEVEL_0, FALSE, context->packetLen);
929 
930  //Failed to serialize fixed header?
931  if(error)
932  return error;
933 
934  //Point to the first byte of the MQTT packet
935  context->packet = context->buffer + n;
936  //Calculate the length of the MQTT packet
937  context->packetLen += MQTT_MAX_HEADER_SIZE - n;
938 
939  //Successful processing
940  return NO_ERROR;
941 }
942 
943 
944 /**
945  * @brief Format PUBLISH packet
946  * @param[in] context Pointer to the MQTT client context
947  * @param[in] topic Topic name
948  * @param[in] message Message payload
949  * @param[in] length Length of the message payload
950  * @param[in] qos QoS level to be used when publishing the message
951  * @param[in] retain This flag specifies if the message is to be retained
952  * @return Error code
953  **/
954 
956  const void *message, size_t length, MqttQosLevel qos, bool_t retain)
957 {
958  error_t error;
959  size_t n;
960 
961  //Make room for the fixed header
963 
964  //The Topic Name must be present as the first field in the PUBLISH
965  //packet variable header
966  error = mqttSerializeString(context->buffer, MQTT_CLIENT_BUFFER_SIZE,
967  &n, topic, osStrlen(topic));
968 
969  //Failed to serialize Topic Name?
970  if(error)
971  return error;
972 
973  //Check QoS level
974  if(qos != MQTT_QOS_LEVEL_0)
975  {
976  //Each time a client sends a new PUBLISH packet it must assign it
977  //a currently unused packet identifier
978  context->packetId++;
979 
980  //The Packet Identifier field is only present in PUBLISH packets
981  //where the QoS level is 1 or 2
982  error = mqttSerializeShort(context->buffer, MQTT_CLIENT_BUFFER_SIZE,
983  &n, context->packetId);
984 
985  //Failed to serialize Packet Identifier field?
986  if(error)
987  return error;
988  }
989 
990  //The payload contains the Application Message that is being published
991  error = mqttSerializeData(context->buffer, MQTT_CLIENT_BUFFER_SIZE,
992  &n, message, length);
993 
994  //Failed to serialize Application Message?
995  if(error)
996  return error;
997 
998  //Calculate the length of the variable header and the payload
999  context->packetLen = n - MQTT_MAX_HEADER_SIZE;
1000 
1001  //The fixed header will be encoded in reverse order
1003 
1004  //Prepend the variable header and the payload with the fixed header
1005  error = mqttSerializeHeader(context->buffer, &n, MQTT_PACKET_TYPE_PUBLISH,
1006  FALSE, qos, retain, context->packetLen);
1007 
1008  //Failed to serialize fixed header?
1009  if(error)
1010  return error;
1011 
1012  //Point to the first byte of the MQTT packet
1013  context->packet = context->buffer + n;
1014  //Calculate the length of the MQTT packet
1015  context->packetLen += MQTT_MAX_HEADER_SIZE - n;
1016 
1017  //Successful processing
1018  return NO_ERROR;
1019 }
1020 
1021 
1022 /**
1023  * @brief Format PUBACK packet
1024  * @param[in] context Pointer to the MQTT client context
1025  * @param[in] packetId Packet identifier
1026  * @return Error code
1027  **/
1028 
1030 {
1031  error_t error;
1032  size_t n;
1033 
1034  //Make room for the fixed header
1036 
1037  //The variable header contains the Packet Identifier from the PUBLISH
1038  //packet that is being acknowledged
1039  error = mqttSerializeShort(context->buffer, MQTT_CLIENT_BUFFER_SIZE,
1040  &n, packetId);
1041 
1042  //Failed to serialize Packet Identifier field?
1043  if(error)
1044  return error;
1045 
1046  //Calculate the length of the variable header and the payload
1047  context->packetLen = n - MQTT_MAX_HEADER_SIZE;
1048 
1049  //The fixed header will be encoded in reverse order
1051 
1052  //Prepend the variable header and the payload with the fixed header
1053  error = mqttSerializeHeader(context->buffer, &n, MQTT_PACKET_TYPE_PUBACK,
1054  FALSE, MQTT_QOS_LEVEL_0, FALSE, context->packetLen);
1055 
1056  //Failed to serialize fixed header?
1057  if(error)
1058  return error;
1059 
1060  //Point to the first byte of the MQTT packet
1061  context->packet = context->buffer + n;
1062  //Calculate the length of the MQTT packet
1063  context->packetLen += MQTT_MAX_HEADER_SIZE - n;
1064 
1065  //Successful processing
1066  return NO_ERROR;
1067 }
1068 
1069 
1070 /**
1071  * @brief Format PUBREC packet
1072  * @param[in] context Pointer to the MQTT client context
1073  * @param[in] packetId Packet identifier
1074  * @return Error code
1075  **/
1076 
1078 {
1079  error_t error;
1080  size_t n;
1081 
1082  //Make room for the fixed header
1084 
1085  //The variable header contains the Packet Identifier from the PUBLISH
1086  //packet that is being acknowledged
1087  error = mqttSerializeShort(context->buffer, MQTT_CLIENT_BUFFER_SIZE,
1088  &n, packetId);
1089 
1090  //Failed to serialize Packet Identifier field?
1091  if(error)
1092  return error;
1093 
1094  //Calculate the length of the variable header and the payload
1095  context->packetLen = n - MQTT_MAX_HEADER_SIZE;
1096 
1097  //The fixed header will be encoded in reverse order
1099 
1100  //Prepend the variable header and the payload with the fixed header
1101  error = mqttSerializeHeader(context->buffer, &n, MQTT_PACKET_TYPE_PUBREC,
1102  FALSE, MQTT_QOS_LEVEL_0, FALSE, context->packetLen);
1103 
1104  //Failed to serialize fixed header?
1105  if(error)
1106  return error;
1107 
1108  //Point to the first byte of the MQTT packet
1109  context->packet = context->buffer + n;
1110  //Calculate the length of the MQTT packet
1111  context->packetLen += MQTT_MAX_HEADER_SIZE - n;
1112 
1113  //Successful processing
1114  return NO_ERROR;
1115 }
1116 
1117 
1118 /**
1119  * @brief Format PUBREL packet
1120  * @param[in] context Pointer to the MQTT client context
1121  * @param[in] packetId Packet identifier
1122  * @return Error code
1123  **/
1124 
1126 {
1127  error_t error;
1128  size_t n;
1129 
1130  //Make room for the fixed header
1132 
1133  //The variable header contains the same Packet Identifier as the PUBREC
1134  //packet that is being acknowledged
1135  error = mqttSerializeShort(context->buffer, MQTT_CLIENT_BUFFER_SIZE,
1136  &n, packetId);
1137 
1138  //Failed to serialize Packet Identifier field?
1139  if(error)
1140  return error;
1141 
1142  //Calculate the length of the variable header and the payload
1143  context->packetLen = n - MQTT_MAX_HEADER_SIZE;
1144 
1145  //The fixed header will be encoded in reverse order
1147 
1148  //Prepend the variable header and the payload with the fixed header
1149  error = mqttSerializeHeader(context->buffer, &n, MQTT_PACKET_TYPE_PUBREL,
1150  FALSE, MQTT_QOS_LEVEL_1, FALSE, context->packetLen);
1151 
1152  //Failed to serialize fixed header?
1153  if(error)
1154  return error;
1155 
1156  //Point to the first byte of the MQTT packet
1157  context->packet = context->buffer + n;
1158  //Calculate the length of the MQTT packet
1159  context->packetLen += MQTT_MAX_HEADER_SIZE - n;
1160 
1161  //Successful processing
1162  return NO_ERROR;
1163 }
1164 
1165 
1166 /**
1167  * @brief Format PUBCOMP packet
1168  * @param[in] context Pointer to the MQTT client context
1169  * @param[in] packetId Packet identifier
1170  * @return Error code
1171  **/
1172 
1174 {
1175  error_t error;
1176  size_t n;
1177 
1178  //Make room for the fixed header
1180 
1181  //The variable header contains the same Packet Identifier as the PUBREL
1182  //packet that is being acknowledged
1183  error = mqttSerializeShort(context->buffer, MQTT_CLIENT_BUFFER_SIZE,
1184  &n, packetId);
1185 
1186  //Failed to serialize Packet Identifier field?
1187  if(error)
1188  return error;
1189 
1190  //Calculate the length of the variable header and the payload
1191  context->packetLen = n - MQTT_MAX_HEADER_SIZE;
1192 
1193  //The fixed header will be encoded in reverse order
1195 
1196  //Prepend the variable header and the payload with the fixed header
1197  error = mqttSerializeHeader(context->buffer, &n, MQTT_PACKET_TYPE_PUBCOMP,
1198  FALSE, MQTT_QOS_LEVEL_0, FALSE, context->packetLen);
1199 
1200  //Failed to serialize fixed header?
1201  if(error)
1202  return error;
1203 
1204  //Point to the first byte of the MQTT packet
1205  context->packet = context->buffer + n;
1206  //Calculate the length of the MQTT packet
1207  context->packetLen += MQTT_MAX_HEADER_SIZE - n;
1208 
1209  //Successful processing
1210  return NO_ERROR;
1211 }
1212 
1213 
1214 /**
1215  * @brief Format SUBSCRIBE packet
1216  * @param[in] context Pointer to the MQTT client context
1217  * @param[in] topic Topic filter
1218  * @param[in] qos Maximum QoS level at which the server can send application
1219  * messages to the client
1220  * @return Error code
1221  **/
1222 
1224  const char_t *topic, MqttQosLevel qos)
1225 {
1226  error_t error;
1227  size_t n;
1228 
1229  //Make room for the fixed header
1231 
1232  //Each time a client sends a new SUBSCRIBE packet it must assign it
1233  //a currently unused packet identifier
1234  context->packetId++;
1235 
1236  //Write Packet Identifier to the output buffer
1237  error = mqttSerializeShort(context->buffer, MQTT_CLIENT_BUFFER_SIZE,
1238  &n, context->packetId);
1239 
1240  //Failed to serialize data?
1241  if(error)
1242  return error;
1243 
1244  //Write the Topic Filter to the output buffer
1245  error = mqttSerializeString(context->buffer, MQTT_CLIENT_BUFFER_SIZE,
1246  &n, topic, osStrlen(topic));
1247 
1248  //Failed to serialize data?
1249  if(error)
1250  return error;
1251 
1252  //Write the Requested QoS to the output buffer
1253  error = mqttSerializeByte(context->buffer, MQTT_CLIENT_BUFFER_SIZE,
1254  &n, qos);
1255 
1256  //Failed to serialize data?
1257  if(error)
1258  return error;
1259 
1260  //Calculate the length of the variable header and the payload
1261  context->packetLen = n - MQTT_MAX_HEADER_SIZE;
1262 
1263  //The fixed header will be encoded in reverse order
1265 
1266  //Prepend the variable header and the payload with the fixed header
1267  error = mqttSerializeHeader(context->buffer, &n, MQTT_PACKET_TYPE_SUBSCRIBE,
1268  FALSE, MQTT_QOS_LEVEL_1, FALSE, context->packetLen);
1269 
1270  //Failed to serialize fixed header?
1271  if(error)
1272  return error;
1273 
1274  //Point to the first byte of the MQTT packet
1275  context->packet = context->buffer + n;
1276  //Calculate the length of the MQTT packet
1277  context->packetLen += MQTT_MAX_HEADER_SIZE - n;
1278 
1279  //Successful processing
1280  return NO_ERROR;
1281 }
1282 
1283 
1284 /**
1285  * @brief Format UNSUBSCRIBE packet
1286  * @param[in] context Pointer to the MQTT client context
1287  * @param[in] topic Topic filter
1288  * @return Error code
1289  **/
1290 
1292  const char_t *topic)
1293 {
1294  error_t error;
1295  size_t n;
1296 
1297  //Make room for the fixed header
1299 
1300  //Each time a client sends a new UNSUBSCRIBE packet it must assign it
1301  //a currently unused packet identifier
1302  context->packetId++;
1303 
1304  //Write Packet Identifier to the output buffer
1305  error = mqttSerializeShort(context->buffer, MQTT_CLIENT_BUFFER_SIZE,
1306  &n, context->packetId);
1307 
1308  //Failed to serialize data?
1309  if(error)
1310  return error;
1311 
1312  //Write the Topic Filter to the output buffer
1313  error = mqttSerializeString(context->buffer, MQTT_CLIENT_BUFFER_SIZE,
1314  &n, topic, osStrlen(topic));
1315 
1316  //Failed to serialize data?
1317  if(error)
1318  return error;
1319 
1320  //Calculate the length of the variable header and the payload
1321  context->packetLen = n - MQTT_MAX_HEADER_SIZE;
1322 
1323  //The fixed header will be encoded in reverse order
1325 
1326  //Prepend the variable header and the payload with the fixed header
1327  error = mqttSerializeHeader(context->buffer, &n, MQTT_PACKET_TYPE_UNSUBSCRIBE,
1328  FALSE, MQTT_QOS_LEVEL_1, FALSE, context->packetLen);
1329 
1330  //Failed to serialize fixed header?
1331  if(error)
1332  return error;
1333 
1334  //Point to the first byte of the MQTT packet
1335  context->packet = context->buffer + n;
1336  //Calculate the length of the MQTT packet
1337  context->packetLen += MQTT_MAX_HEADER_SIZE - n;
1338 
1339  //Successful processing
1340  return NO_ERROR;
1341 }
1342 
1343 
1344 /**
1345  * @brief Format PINGREQ packet
1346  * @param[in] context Pointer to the MQTT client context
1347  * @return Error code
1348  **/
1349 
1351 {
1352  error_t error;
1353  size_t n;
1354 
1355  //The fixed header will be encoded in reverse order
1357 
1358  //The PINGREQ packet does not contain any variable header nor payload
1359  error = mqttSerializeHeader(context->buffer, &n, MQTT_PACKET_TYPE_PINGREQ,
1361 
1362  //Failed to serialize fixed header?
1363  if(error)
1364  return error;
1365 
1366  //Point to the first byte of the MQTT packet
1367  context->packet = context->buffer + n;
1368  //Calculate the length of the MQTT packet
1369  context->packetLen = MQTT_MAX_HEADER_SIZE - n;
1370 
1371  //Successful processing
1372  return NO_ERROR;
1373 }
1374 
1375 
1376 /**
1377  * @brief Format DISCONNECT packet
1378  * @param[in] context Pointer to the MQTT client context
1379  * @return Error code
1380  **/
1381 
1383 {
1384  error_t error;
1385  size_t n;
1386 
1387  //The fixed header will be encoded in reverse order
1389 
1390  //The DISCONNECT packet does not contain any variable header nor payload
1391  error = mqttSerializeHeader(context->buffer, &n, MQTT_PACKET_TYPE_DISCONNECT,
1393 
1394  //Failed to serialize fixed header?
1395  if(error)
1396  return error;
1397 
1398  //Point to the first byte of the MQTT packet
1399  context->packet = context->buffer + n;
1400  //Calculate the length of the MQTT packet
1401  context->packetLen = MQTT_MAX_HEADER_SIZE - n;
1402 
1403  //Successful processing
1404  return NO_ERROR;
1405 }
1406 
1407 #endif
error_t mqttSerializeData(uint8_t *buffer, size_t bufferLen, size_t *pos, const void *data, size_t dataLen)
Serialize raw data.
uint8_t length
Definition: coap_common.h:190
error_t mqttClientProcessPubAck(MqttClientContext *context, bool_t dup, MqttQosLevel qos, bool_t retain, size_t remainingLen)
Process incoming PUBACK packet.
error_t mqttClientProcessPingResp(MqttClientContext *context, bool_t dup, MqttQosLevel qos, bool_t retain, size_t remainingLen)
Process incoming PINGRESP packet.
int bool_t
Definition: compiler_port.h:49
Client is disconnecting.
Definition: mqtt_common.h:114
error_t mqttClientFormatPubAck(MqttClientContext *context, uint16_t packetId)
Format PUBACK packet.
error_t mqttClientFormatPingReq(MqttClientContext *context)
Format PINGREQ packet.
Exactly once delivery.
Definition: mqtt_common.h:90
error_t mqttClientProcessPubComp(MqttClientContext *context, bool_t dup, MqttQosLevel qos, bool_t retain, size_t remainingLen)
Process incoming PUBCOMP packet.
error_t mqttDeserializeHeader(uint8_t *buffer, size_t bufferLen, size_t *pos, MqttPacketType *type, bool_t *dup, MqttQosLevel *qos, bool_t *retain, size_t *remainingLen)
Deserialize fixed header.
Publish message.
Definition: mqtt_common.h:103
Publish received (assured delivery part 1)
Definition: mqtt_common.h:105
error_t mqttClientReceivePacket(MqttClientContext *context)
Receive MQTT packet.
error_t mqttDeserializeString(uint8_t *buffer, size_t bufferLen, size_t *pos, char_t **string, size_t *stringLen)
Deserialize string.
uint8_t qos
Definition: mqtt_common.h:179
#define osStrlen(s)
Definition: os_port.h:152
error_t mqttClientProcessPubRec(MqttClientContext *context, bool_t dup, MqttQosLevel qos, bool_t retain, size_t remainingLen)
Process incoming PUBREC packet.
uint8_t payload[MQTT_CLIENT_MAX_WILL_PAYLOAD_LEN]
Will message payload.
Definition: mqtt_client.h:261
error_t mqttDeserializeByte(uint8_t *buffer, size_t bufferLen, size_t *pos, uint8_t *value)
Read a 8-bit integer from the input buffer.
Connect acknowledgment.
Definition: mqtt_common.h:102
error_t mqttClientFormatConnect(MqttClientContext *context, bool_t cleanSession)
Format CONNECT packet.
error_t mqttClientProcessSubAck(MqttClientContext *context, bool_t dup, MqttQosLevel qos, bool_t retain, size_t remainingLen)
Process incoming SUBACK packet.
error_t mqttClientFormatPubRel(MqttClientContext *context, uint16_t packetId)
Format PUBREL packet.
error_t mqttClientProcessUnsubAck(MqttClientContext *context, bool_t dup, MqttQosLevel qos, bool_t retain, size_t remainingLen)
Process incoming UNSUBACK packet.
#define FALSE
Definition: os_port.h:46
error_t mqttSerializeHeader(uint8_t *buffer, size_t *pos, MqttPacketType type, bool_t dup, MqttQosLevel qos, bool_t retain, size_t remainingLen)
Serialize fixed header.
Helper functions for MQTT client.
void mqttClientChangeState(MqttClientContext *context, MqttClientState newState)
Update MQTT client state.
char_t type
error_t
Error codes.
Definition: error.h:42
Transport protocol abstraction layer.
At most once delivery.
Definition: mqtt_common.h:88
error_t mqttSerializeByte(uint8_t *buffer, size_t bufferLen, size_t *pos, uint8_t value)
Write a 8-bit integer to the output buffer.
error_t mqttClientFormatPublish(MqttClientContext *context, const char_t *topic, const void *message, size_t length, MqttQosLevel qos, bool_t retain)
Format PUBLISH packet.
Publish acknowledgment.
Definition: mqtt_common.h:104
MqttQosLevel
Quality of service level.
Definition: mqtt_common.h:86
uint8_t retain
Definition: mqtt_common.h:178
uint8_t value[]
Definition: tcp.h:332
Subscribe acknowledgment.
Definition: mqtt_common.h:109
error_t mqttClientProcessConnAck(MqttClientContext *context, bool_t dup, MqttQosLevel qos, bool_t retain, size_t remainingLen)
Process incoming CONNACK packet.
error_t mqttClientFormatUnsubscribe(MqttClientContext *context, const char_t *topic)
Format UNSUBSCRIBE packet.
Client request to connect to server.
Definition: mqtt_common.h:101
Client subscribe request.
Definition: mqtt_common.h:108
MQTT packet parsing and formatting.
Unsubscribe acknowledgment.
Definition: mqtt_common.h:111
#define TRACE_INFO(...)
Definition: debug.h:95
error_t mqttClientProcessPubRel(MqttClientContext *context, bool_t dup, MqttQosLevel qos, bool_t retain, size_t remainingLen)
Process incoming PUBREL packet.
error_t mqttClientProcessPacket(MqttClientContext *context)
Process incoming MQTT packet.
bool_t retain
Specifies if the Will message is to be retained.
Definition: mqtt_client.h:264
error_t mqttClientFormatPubRec(MqttClientContext *context, uint16_t packetId)
Format PUBREC packet.
Unsubscribe request.
Definition: mqtt_common.h:110
error_t mqttClientFormatDisconnect(MqttClientContext *context)
Format DISCONNECT packet.
#define MQTT_PROTOCOL_NAME_3_1
Definition: mqtt_common.h:43
size_t length
Length of the Will message payload.
Definition: mqtt_client.h:262
error_t mqttClientReceiveData(MqttClientContext *context, void *data, size_t size, size_t *received, uint_t flags)
Receive data using the relevant transport protocol.
char char_t
Definition: compiler_port.h:43
#define MQTT_MAX_HEADER_SIZE
Definition: mqtt_common.h:50
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:108
uint8_t n
Publish complete (assured delivery part 3)
Definition: mqtt_common.h:107
uint8_t cleanSession
error_t mqttClientFormatPubComp(MqttClientContext *context, uint16_t packetId)
Format PUBCOMP packet.
error_t mqttClientProcessPublish(MqttClientContext *context, bool_t dup, MqttQosLevel qos, bool_t retain, size_t remainingLen)
Process incoming PUBLISH packet.
uint8_t message[]
Definition: chap.h:152
error_t mqttClientFormatSubscribe(MqttClientContext *context, const char_t *topic, MqttQosLevel qos)
Format SUBSCRIBE packet.
uint8_t dup
Definition: mqtt_common.h:180
Publish release (assured delivery part 2)
Definition: mqtt_common.h:106
MQTT version 3.1.1.
Definition: mqtt_common.h:65
#define MqttClientContext
Definition: mqtt_client.h:142
MqttQosLevel qos
QoS level to be used when publishing the Will message.
Definition: mqtt_client.h:263
error_t mqttDeserializeShort(uint8_t *buffer, size_t bufferLen, size_t *pos, uint16_t *value)
Read a 16-bit integer from the input buffer.
error_t mqttSerializeShort(uint8_t *buffer, size_t bufferLen, size_t *pos, uint16_t value)
Write a 16-bit integer to the output buffer.
At least once delivery.
Definition: mqtt_common.h:89
#define PRIuSIZE
Definition: compiler_port.h:78
TCP/IP stack core.
#define MQTT_CLIENT_BUFFER_SIZE
Definition: mqtt_client.h:124
MQTT version 3.1.
Definition: mqtt_common.h:64
error_t mqttSerializeString(uint8_t *buffer, size_t bufferLen, size_t *pos, const void *string, size_t stringLen)
Serialize string.
char_t topic[MQTT_CLIENT_MAX_WILL_TOPIC_LEN+1]
Will topic name.
Definition: mqtt_client.h:260
Success.
Definition: error.h:44
MqttPacketType
MQTT control packet type.
Definition: mqtt_common.h:98
Debugging facilities.
#define osMemmove(dest, src, length)
Definition: os_port.h:140
#define MQTT_PROTOCOL_NAME_3_1_1
Definition: mqtt_common.h:45
MQTT client.