RaspberrPi project source code
guowenxue
2024-03-12 c5e9e88eb8c6039cd2a4d2b3fdae0b1e3d8aea40
commit | author | age
d6b4a7 1 /*
G 2  * coreMQTT v2.1.1
3  * Copyright (C) 2022 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4  *
5  * SPDX-License-Identifier: MIT
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy of
8  * this software and associated documentation files (the "Software"), to deal in
9  * the Software without restriction, including without limitation the rights to
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11  * the Software, and to permit persons to whom the Software is furnished to do so,
12  * subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in all
15  * copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24
25 /**
26  * @file core_mqtt_serializer.h
27  * @brief User-facing functions for serializing and deserializing MQTT 3.1.1
28  * packets. This header should be included for building a lighter weight MQTT
29  * client than the managed CSDK MQTT library API in core_mqtt.h, by using the
30  * serializer and de-serializer functions exposed in this file's API.
31  */
32 #ifndef CORE_MQTT_SERIALIZER_H
33 #define CORE_MQTT_SERIALIZER_H
34
35 #include <stddef.h>
36 #include <stdint.h>
37 #include <stdbool.h>
38
39 /* *INDENT-OFF* */
40 #ifdef __cplusplus
41     extern "C" {
42 #endif
43 /* *INDENT-ON */
44
45 /* MQTT_DO_NOT_USE_CUSTOM_CONFIG allows building the MQTT library
46  * without a custom config. If a custom config is provided, the
47  * MQTT_DO_NOT_USE_CUSTOM_CONFIG macro should not be defined. */
48 #ifndef MQTT_DO_NOT_USE_CUSTOM_CONFIG
49     /* Include custom config file before other headers. */
50     #include "core_mqtt_config.h"
51 #endif
52
53 /* Include config defaults header to get default values of configs not
54  * defined in core_mqtt_config.h file. */
55 #include "core_mqtt_config_defaults.h"
56
57 #include "transport_interface.h"
58
59 /* MQTT packet types. */
60
61 /**
62  * @addtogroup mqtt_constants
63  * @{
64  */
65 #define MQTT_PACKET_TYPE_CONNECT        ( ( uint8_t ) 0x10U )  /**< @brief CONNECT (client-to-server). */
66 #define MQTT_PACKET_TYPE_CONNACK        ( ( uint8_t ) 0x20U )  /**< @brief CONNACK (server-to-client). */
67 #define MQTT_PACKET_TYPE_PUBLISH        ( ( uint8_t ) 0x30U )  /**< @brief PUBLISH (bidirectional). */
68 #define MQTT_PACKET_TYPE_PUBACK         ( ( uint8_t ) 0x40U )  /**< @brief PUBACK (bidirectional). */
69 #define MQTT_PACKET_TYPE_PUBREC         ( ( uint8_t ) 0x50U )  /**< @brief PUBREC (bidirectional). */
70 #define MQTT_PACKET_TYPE_PUBREL         ( ( uint8_t ) 0x62U )  /**< @brief PUBREL (bidirectional). */
71 #define MQTT_PACKET_TYPE_PUBCOMP        ( ( uint8_t ) 0x70U )  /**< @brief PUBCOMP (bidirectional). */
72 #define MQTT_PACKET_TYPE_SUBSCRIBE      ( ( uint8_t ) 0x82U )  /**< @brief SUBSCRIBE (client-to-server). */
73 #define MQTT_PACKET_TYPE_SUBACK         ( ( uint8_t ) 0x90U )  /**< @brief SUBACK (server-to-client). */
74 #define MQTT_PACKET_TYPE_UNSUBSCRIBE    ( ( uint8_t ) 0xA2U )  /**< @brief UNSUBSCRIBE (client-to-server). */
75 #define MQTT_PACKET_TYPE_UNSUBACK       ( ( uint8_t ) 0xB0U )  /**< @brief UNSUBACK (server-to-client). */
76 #define MQTT_PACKET_TYPE_PINGREQ        ( ( uint8_t ) 0xC0U )  /**< @brief PINGREQ (client-to-server). */
77 #define MQTT_PACKET_TYPE_PINGRESP       ( ( uint8_t ) 0xD0U )  /**< @brief PINGRESP (server-to-client). */
78 #define MQTT_PACKET_TYPE_DISCONNECT     ( ( uint8_t ) 0xE0U )  /**< @brief DISCONNECT (client-to-server). */
79 /** @} */
80
81 /**
82  * @ingroup mqtt_constants
83  * @brief The size of MQTT PUBACK, PUBREC, PUBREL, and PUBCOMP packets, per MQTT spec.
84  */
85 #define MQTT_PUBLISH_ACK_PACKET_SIZE    ( 4UL )
86
87 /* Structures defined in this file. */
88 struct MQTTFixedBuffer;
89 struct MQTTConnectInfo;
90 struct MQTTSubscribeInfo;
91 struct MQTTPublishInfo;
92 struct MQTTPacketInfo;
93
94 /**
95  * @ingroup mqtt_enum_types
96  * @brief Return codes from MQTT functions.
97  */
98 typedef enum MQTTStatus
99 {
100     MQTTSuccess = 0,      /**< Function completed successfully. */
101     MQTTBadParameter,     /**< At least one parameter was invalid. */
102     MQTTNoMemory,         /**< A provided buffer was too small. */
103     MQTTSendFailed,       /**< The transport send function failed. */
104     MQTTRecvFailed,       /**< The transport receive function failed. */
105     MQTTBadResponse,      /**< An invalid packet was received from the server. */
106     MQTTServerRefused,    /**< The server refused a CONNECT or SUBSCRIBE. */
107     MQTTNoDataAvailable,  /**< No data available from the transport interface. */
108     MQTTIllegalState,     /**< An illegal state in the state record. */
109     MQTTStateCollision,   /**< A collision with an existing state record entry. */
110     MQTTKeepAliveTimeout, /**< Timeout while waiting for PINGRESP. */
111     MQTTNeedMoreBytes     /**< MQTT_ProcessLoop/MQTT_ReceiveLoop has received
112                           incomplete data; it should be called again (probably after
113                           a delay). */
114 } MQTTStatus_t;
115
116 /**
117  * @ingroup mqtt_enum_types
118  * @brief MQTT Quality of Service values.
119  */
120 typedef enum MQTTQoS
121 {
122     MQTTQoS0 = 0, /**< Delivery at most once. */
123     MQTTQoS1 = 1, /**< Delivery at least once. */
124     MQTTQoS2 = 2  /**< Delivery exactly once. */
125 } MQTTQoS_t;
126
127 /**
128  * @ingroup mqtt_struct_types
129  * @brief Buffer passed to MQTT library.
130  *
131  * These buffers are not copied and must remain in scope for the duration of the
132  * MQTT operation.
133  */
134 typedef struct MQTTFixedBuffer
135 {
136     uint8_t * pBuffer; /**< @brief Pointer to buffer. */
137     size_t size;       /**< @brief Size of buffer. */
138 } MQTTFixedBuffer_t;
139
140 /**
141  * @ingroup mqtt_struct_types
142  * @brief MQTT CONNECT packet parameters.
143  */
144 typedef struct MQTTConnectInfo
145 {
146     /**
147      * @brief Whether to establish a new, clean session or resume a previous session.
148      */
149     bool cleanSession;
150
151     /**
152      * @brief MQTT keep alive period.
153      */
154     uint16_t keepAliveSeconds;
155
156     /**
157      * @brief MQTT client identifier. Must be unique per client.
158      */
159     const char * pClientIdentifier;
160
161     /**
162      * @brief Length of the client identifier.
163      */
164     uint16_t clientIdentifierLength;
165
166     /**
167      * @brief MQTT user name. Set to NULL if not used.
168      */
169     const char * pUserName;
170
171     /**
172      * @brief Length of MQTT user name. Set to 0 if not used.
173      */
174     uint16_t userNameLength;
175
176     /**
177      * @brief MQTT password. Set to NULL if not used.
178      */
179     const char * pPassword;
180
181     /**
182      * @brief Length of MQTT password. Set to 0 if not used.
183      */
184     uint16_t passwordLength;
185 } MQTTConnectInfo_t;
186
187 /**
188  * @ingroup mqtt_struct_types
189  * @brief MQTT SUBSCRIBE packet parameters.
190  */
191 typedef struct MQTTSubscribeInfo
192 {
193     /**
194      * @brief Quality of Service for subscription.
195      */
196     MQTTQoS_t qos;
197
198     /**
199      * @brief Topic filter to subscribe to.
200      */
201     const char * pTopicFilter;
202
203     /**
204      * @brief Length of subscription topic filter.
205      */
206     uint16_t topicFilterLength;
207 } MQTTSubscribeInfo_t;
208
209 /**
210  * @ingroup mqtt_struct_types
211  * @brief MQTT PUBLISH packet parameters.
212  */
213 typedef struct MQTTPublishInfo
214 {
215     /**
216      * @brief Quality of Service for message.
217      */
218     MQTTQoS_t qos;
219
220     /**
221      * @brief Whether this is a retained message.
222      */
223     bool retain;
224
225     /**
226      * @brief Whether this is a duplicate publish message.
227      */
228     bool dup;
229
230     /**
231      * @brief Topic name on which the message is published.
232      */
233     const char * pTopicName;
234
235     /**
236      * @brief Length of topic name.
237      */
238     uint16_t topicNameLength;
239
240     /**
241      * @brief Message payload.
242      */
243     const void * pPayload;
244
245     /**
246      * @brief Message payload length.
247      */
248     size_t payloadLength;
249 } MQTTPublishInfo_t;
250
251 /**
252  * @ingroup mqtt_struct_types
253  * @brief MQTT incoming packet parameters.
254  */
255 typedef struct MQTTPacketInfo
256 {
257     /**
258      * @brief Type of incoming MQTT packet.
259      */
260     uint8_t type;
261
262     /**
263      * @brief Remaining serialized data in the MQTT packet.
264      */
265     uint8_t * pRemainingData;
266
267     /**
268      * @brief Length of remaining serialized data.
269      */
270     size_t remainingLength;
271
272     /**
273      * @brief The length of the MQTT header including the type and length.
274      */
275     size_t headerLength;
276 } MQTTPacketInfo_t;
277
278 /**
279  * @brief Get the size and Remaining Length of an MQTT CONNECT packet.
280  *
281  * This function must be called before #MQTT_SerializeConnect in order to get
282  * the size of the MQTT CONNECT packet that is generated from #MQTTConnectInfo_t
283  * and optional #MQTTPublishInfo_t. The size of the #MQTTFixedBuffer_t supplied
284  * to #MQTT_SerializeConnect must be at least @p pPacketSize. The provided
285  * @p pConnectInfo and @p pWillInfo are valid for serialization with
286  * #MQTT_SerializeConnect only if this function returns #MQTTSuccess. The
287  * remaining length returned in @p pRemainingLength and the packet size returned
288  * in @p pPacketSize are valid only if this function returns #MQTTSuccess.
289  *
290  * @param[in] pConnectInfo MQTT CONNECT packet parameters.
291  * @param[in] pWillInfo Last Will and Testament. Pass NULL if not used.
292  * @param[out] pRemainingLength The Remaining Length of the MQTT CONNECT packet.
293  * @param[out] pPacketSize The total size of the MQTT CONNECT packet.
294  *
295  * @return #MQTTBadParameter if the packet would exceed the size allowed by the
296  * MQTT spec; #MQTTSuccess otherwise.
297  *
298  * <b>Example</b>
299  * @code{c}
300  *
301  * // Variables used in this example.
302  * MQTTStatus_t status;
303  * MQTTConnectInfo_t connectInfo = { 0 };
304  * MQTTPublishInfo_t willInfo = { 0 };
305  * size_t remainingLength = 0, packetSize = 0;
306  *
307  * // Initialize the connection info, the details are out of scope for this example.
308  * initializeConnectInfo( &connectInfo );
309  *
310  * // Initialize the optional will info, the details are out of scope for this example.
311  * initializeWillInfo( &willInfo );
312  *
313  * // Get the size requirement for the connect packet.
314  * status = MQTT_GetConnectPacketSize(
315  *      &connectInfo, &willInfo, &remainingLength, &packetSize
316  * );
317  *
318  * if( status == MQTTSuccess )
319  * {
320  *      // The application should allocate or use a static #MQTTFixedBuffer_t
321  *      // of size >= packetSize to serialize the connect request.
322  * }
323  * @endcode
324  */
325 /* @[declare_mqtt_getconnectpacketsize] */
326 MQTTStatus_t MQTT_GetConnectPacketSize( const MQTTConnectInfo_t * pConnectInfo,
327                                         const MQTTPublishInfo_t * pWillInfo,
328                                         size_t * pRemainingLength,
329                                         size_t * pPacketSize );
330 /* @[declare_mqtt_getconnectpacketsize] */
331
332 /**
333  * @brief Serialize an MQTT CONNECT packet in the given fixed buffer @p pFixedBuffer.
334  *
335  * #MQTT_GetConnectPacketSize should be called with @p pConnectInfo and
336  * @p pWillInfo before invoking this function to get the size of the required
337  * #MQTTFixedBuffer_t and @p remainingLength. The @p remainingLength must be
338  * the same as returned by #MQTT_GetConnectPacketSize. The #MQTTFixedBuffer_t
339  * must be at least as large as the size returned by #MQTT_GetConnectPacketSize.
340  *
341  * @param[in] pConnectInfo MQTT CONNECT packet parameters.
342  * @param[in] pWillInfo Last Will and Testament. Pass NULL if not used.
343  * @param[in] remainingLength Remaining Length provided by #MQTT_GetConnectPacketSize.
344  * @param[out] pFixedBuffer Buffer for packet serialization.
345  *
346  * @return #MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet;
347  * #MQTTBadParameter if invalid parameters are passed;
348  * #MQTTSuccess otherwise.
349  *
350  * <b>Example</b>
351  * @code{c}
352  *
353  * // Variables used in this example.
354  * MQTTStatus_t status;
355  * MQTTConnectInfo_t connectInfo = { 0 };
356  * MQTTPublishInfo_t willInfo = { 0 };
357  * MQTTFixedBuffer_t fixedBuffer;
358  * uint8_t buffer[ BUFFER_SIZE ];
359  * size_t remainingLength = 0, packetSize = 0;
360  *
361  * fixedBuffer.pBuffer = buffer;
362  * fixedBuffer.size = BUFFER_SIZE;
363  *
364  * // Assume connectInfo and willInfo are initialized. Get the size requirement for
365  * // the connect packet.
366  * status = MQTT_GetConnectPacketSize(
367  *      &connectInfo, &willInfo, &remainingLength, &packetSize
368  * );
369  * assert( status == MQTTSuccess );
370  * assert( packetSize <= BUFFER_SIZE );
371  *
372  * // Serialize the connect packet into the fixed buffer.
373  * status = MQTT_SerializeConnect( &connectInfo, &willInfo, remainingLength, &fixedBuffer );
374  *
375  * if( status == MQTTSuccess )
376  * {
377  *      // The connect packet can now be sent to the broker.
378  * }
379  * @endcode
380  */
381 /* @[declare_mqtt_serializeconnect] */
382 MQTTStatus_t MQTT_SerializeConnect( const MQTTConnectInfo_t * pConnectInfo,
383                                     const MQTTPublishInfo_t * pWillInfo,
384                                     size_t remainingLength,
385                                     const MQTTFixedBuffer_t * pFixedBuffer );
386 /* @[declare_mqtt_serializeconnect] */
387
388 /**
389  * @brief Get packet size and Remaining Length of an MQTT SUBSCRIBE packet.
390  *
391  * This function must be called before #MQTT_SerializeSubscribe in order to get
392  * the size of the MQTT SUBSCRIBE packet that is generated from the list of
393  * #MQTTSubscribeInfo_t. The size of the #MQTTFixedBuffer_t supplied
394  * to #MQTT_SerializeSubscribe must be at least @p pPacketSize. The provided
395  * @p pSubscriptionList is valid for serialization with #MQTT_SerializeSubscribe
396  * only if this function returns #MQTTSuccess. The remaining length returned in
397  * @p pRemainingLength and the packet size returned in @p pPacketSize are valid
398  * only if this function returns #MQTTSuccess.
399  *
400  * @param[in] pSubscriptionList List of MQTT subscription info.
401  * @param[in] subscriptionCount The number of elements in pSubscriptionList.
402  * @param[out] pRemainingLength The Remaining Length of the MQTT SUBSCRIBE packet.
403  * @param[out] pPacketSize The total size of the MQTT SUBSCRIBE packet.
404  *
405  * @return #MQTTBadParameter if the packet would exceed the size allowed by the
406  * MQTT spec; #MQTTSuccess otherwise.
407  *
408  * <b>Example</b>
409  * @code{c}
410  *
411  * // Variables used in this example.
412  * MQTTStatus_t status;
413  * MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
414  * size_t remainingLength = 0, packetSize = 0;
415  * // This is assumed to be a list of filters we want to subscribe to.
416  * const char * filters[ NUMBER_OF_SUBSCRIPTIONS ];
417  *
418  * // Set each subscription.
419  * for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )
420  * {
421  *      subscriptionList[ i ].qos = MQTTQoS0;
422  *      // Each subscription needs a topic filter.
423  *      subscriptionList[ i ].pTopicFilter = filters[ i ];
424  *      subscriptionList[ i ].topicFilterLength = strlen( filters[ i ] );
425  * }
426  *
427  * // Get the size requirement for the subscribe packet.
428  * status = MQTT_GetSubscribePacketSize(
429  *      &subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
430  * );
431  *
432  * if( status == MQTTSuccess )
433  * {
434  *      // The application should allocate or use a static #MQTTFixedBuffer_t
435  *      // of size >= packetSize to serialize the subscribe request.
436  * }
437  * @endcode
438  */
439 /* @[declare_mqtt_getsubscribepacketsize] */
440 MQTTStatus_t MQTT_GetSubscribePacketSize( const MQTTSubscribeInfo_t * pSubscriptionList,
441                                           size_t subscriptionCount,
442                                           size_t * pRemainingLength,
443                                           size_t * pPacketSize );
444 /* @[declare_mqtt_getsubscribepacketsize] */
445
446 /**
447  * @brief Serialize an MQTT SUBSCRIBE packet in the given buffer.
448  *
449  * #MQTT_GetSubscribePacketSize should be called with @p pSubscriptionList
450  * before invoking this function to get the size of the required
451  * #MQTTFixedBuffer_t and @p remainingLength. The @p remainingLength must be
452  * the same as returned by #MQTT_GetSubscribePacketSize. The #MQTTFixedBuffer_t
453  * must be at least as large as the size returned by #MQTT_GetSubscribePacketSize.
454  *
455  * @param[in] pSubscriptionList List of MQTT subscription info.
456  * @param[in] subscriptionCount The number of elements in pSubscriptionList.
457  * @param[in] packetId packet ID generated by #MQTT_GetPacketId.
458  * @param[in] remainingLength Remaining Length provided by #MQTT_GetSubscribePacketSize.
459  * @param[out] pFixedBuffer Buffer for packet serialization.
460  *
461  * @return #MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet;
462  * #MQTTBadParameter if invalid parameters are passed;
463  * #MQTTSuccess otherwise.
464  *
465  * <b>Example</b>
466  * @code{c}
467  *
468  * // Variables used in this example.
469  * MQTTStatus_t status;
470  * MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
471  * MQTTFixedBuffer_t fixedBuffer;
472  * uint8_t buffer[ BUFFER_SIZE ];
473  * size_t remainingLength = 0, packetSize = 0;
474  * uint16_t packetId;
475  *
476  * fixedBuffer.pBuffer = buffer;
477  * fixedBuffer.size = BUFFER_SIZE;
478  *
479  * // Function to return a valid, unused packet identifier. The details are out of
480  * // scope for this example.
481  * packetId = getNewPacketId();
482  *
483  * // Assume subscriptionList has been initialized. Get the subscribe packet size.
484  * status = MQTT_GetSubscribePacketSize(
485  *      &subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
486  * );
487  * assert( status == MQTTSuccess );
488  * assert( packetSize <= BUFFER_SIZE );
489  *
490  * // Serialize the subscribe packet into the fixed buffer.
491  * status = MQTT_SerializeSubscribe(
492  *      &subscriptionList[ 0 ],
493  *      NUMBER_OF_SUBSCRIPTIONS,
494  *      packetId,
495  *      remainingLength,
496  *      &fixedBuffer
497  * );
498  *
499  * if( status == MQTTSuccess )
500  * {
501  *      // The subscribe packet can now be sent to the broker.
502  * }
503  * @endcode
504  */
505 /* @[declare_mqtt_serializesubscribe] */
506 MQTTStatus_t MQTT_SerializeSubscribe( const MQTTSubscribeInfo_t * pSubscriptionList,
507                                       size_t subscriptionCount,
508                                       uint16_t packetId,
509                                       size_t remainingLength,
510                                       const MQTTFixedBuffer_t * pFixedBuffer );
511 /* @[declare_mqtt_serializesubscribe] */
512
513 /**
514  * @brief Get packet size and Remaining Length of an MQTT UNSUBSCRIBE packet.
515  *
516  * This function must be called before #MQTT_SerializeUnsubscribe in order to
517  * get the size of the MQTT UNSUBSCRIBE packet that is generated from the list
518  * of #MQTTSubscribeInfo_t. The size of the #MQTTFixedBuffer_t supplied
519  * to #MQTT_SerializeUnsubscribe must be at least @p pPacketSize. The provided
520  * @p pSubscriptionList is valid for serialization with #MQTT_SerializeUnsubscribe
521  * only if this function returns #MQTTSuccess. The remaining length returned in
522  * @p pRemainingLength and the packet size returned in @p pPacketSize are valid
523  * only if this function returns #MQTTSuccess.
524  *
525  * @param[in] pSubscriptionList List of MQTT subscription info.
526  * @param[in] subscriptionCount The number of elements in pSubscriptionList.
527  * @param[out] pRemainingLength The Remaining Length of the MQTT UNSUBSCRIBE packet.
528  * @param[out] pPacketSize The total size of the MQTT UNSUBSCRIBE packet.
529  *
530  * @return #MQTTBadParameter if the packet would exceed the size allowed by the
531  * MQTT spec; #MQTTSuccess otherwise.
532  *
533  * <b>Example</b>
534  * @code{c}
535  *
536  * // Variables used in this example.
537  * MQTTStatus_t status;
538  * MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
539  * size_t remainingLength = 0, packetSize = 0;
540  *
541  * // Initialize the subscribe info. The details are out of scope for this example.
542  * initializeSubscribeInfo( &subscriptionList[ 0 ] );
543  *
544  * // Get the size requirement for the unsubscribe packet.
545  * status = MQTT_GetUnsubscribePacketSize(
546  *      &subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
547  * );
548  *
549  * if( status == MQTTSuccess )
550  * {
551  *      // The application should allocate or use a static #MQTTFixedBuffer_t
552  *      // of size >= packetSize to serialize the unsubscribe request.
553  * }
554  * @endcode
555  */
556 /* @[declare_mqtt_getunsubscribepacketsize] */
557 MQTTStatus_t MQTT_GetUnsubscribePacketSize( const MQTTSubscribeInfo_t * pSubscriptionList,
558                                             size_t subscriptionCount,
559                                             size_t * pRemainingLength,
560                                             size_t * pPacketSize );
561 /* @[declare_mqtt_getunsubscribepacketsize] */
562
563 /**
564  * @brief Serialize an MQTT UNSUBSCRIBE packet in the given buffer.
565  *
566  * #MQTT_GetUnsubscribePacketSize should be called with @p pSubscriptionList
567  * before invoking this function to get the size of the required
568  * #MQTTFixedBuffer_t and @p remainingLength. The @p remainingLength must be
569  * the same as returned by #MQTT_GetUnsubscribePacketSize. The #MQTTFixedBuffer_t
570  * must be at least as large as the size returned by #MQTT_GetUnsubscribePacketSize.
571  *
572  * @param[in] pSubscriptionList List of MQTT subscription info.
573  * @param[in] subscriptionCount The number of elements in pSubscriptionList.
574  * @param[in] packetId packet ID generated by #MQTT_GetPacketId.
575  * @param[in] remainingLength Remaining Length provided by #MQTT_GetUnsubscribePacketSize.
576  * @param[out] pFixedBuffer Buffer for packet serialization.
577  *
578  * @return #MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet;
579  * #MQTTBadParameter if invalid parameters are passed;
580  * #MQTTSuccess otherwise.
581  *
582  * <b>Example</b>
583  * @code{c}
584  *
585  * // Variables used in this example.
586  * MQTTStatus_t status;
587  * MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
588  * MQTTFixedBuffer_t fixedBuffer;
589  * uint8_t buffer[ BUFFER_SIZE ];
590  * size_t remainingLength = 0, packetSize = 0;
591  * uint16_t packetId;
592  *
593  * fixedBuffer.pBuffer = buffer;
594  * fixedBuffer.size = BUFFER_SIZE;
595  *
596  * // Function to return a valid, unused packet identifier. The details are out of
597  * // scope for this example.
598  * packetId = getNewPacketId();
599  *
600  * // Assume subscriptionList has been initialized. Get the unsubscribe packet size.
601  * status = MQTT_GetUnsubscribePacketSize(
602  *      &subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
603  * );
604  * assert( status == MQTTSuccess );
605  * assert( packetSize <= BUFFER_SIZE );
606  *
607  * // Serialize the unsubscribe packet into the fixed buffer.
608  * status = MQTT_SerializeUnsubscribe(
609  *      &subscriptionList[ 0 ],
610  *      NUMBER_OF_SUBSCRIPTIONS,
611  *      packetId,
612  *      remainingLength,
613  *      &fixedBuffer
614  * );
615  *
616  * if( status == MQTTSuccess )
617  * {
618  *      // The unsubscribe packet can now be sent to the broker.
619  * }
620  * @endcode
621  */
622 /* @[declare_mqtt_serializeunsubscribe] */
623 MQTTStatus_t MQTT_SerializeUnsubscribe( const MQTTSubscribeInfo_t * pSubscriptionList,
624                                         size_t subscriptionCount,
625                                         uint16_t packetId,
626                                         size_t remainingLength,
627                                         const MQTTFixedBuffer_t * pFixedBuffer );
628 /* @[declare_mqtt_serializeunsubscribe] */
629
630 /**
631  * @brief Get the packet size and remaining length of an MQTT PUBLISH packet.
632  *
633  * This function must be called before #MQTT_SerializePublish in order to get
634  * the size of the MQTT PUBLISH packet that is generated from #MQTTPublishInfo_t.
635  * The size of the #MQTTFixedBuffer_t supplied to #MQTT_SerializePublish must be
636  * at least @p pPacketSize. The provided @p pPublishInfo is valid for
637  * serialization with #MQTT_SerializePublish only if this function returns
638  * #MQTTSuccess. The remaining length returned in @p pRemainingLength and the
639  * packet size returned in @p pPacketSize are valid only if this function
640  * returns #MQTTSuccess.
641  *
642  * @param[in] pPublishInfo MQTT PUBLISH packet parameters.
643  * @param[out] pRemainingLength The Remaining Length of the MQTT PUBLISH packet.
644  * @param[out] pPacketSize The total size of the MQTT PUBLISH packet.
645  *
646  * @return #MQTTBadParameter if the packet would exceed the size allowed by the
647  * MQTT spec or if invalid parameters are passed; #MQTTSuccess otherwise.
648  *
649  * <b>Example</b>
650  * @code{c}
651  *
652  * // Variables used in this example.
653  * MQTTStatus_t status;
654  * MQTTPublishInfo_t publishInfo = { 0 };
655  * size_t remainingLength = 0, packetSize = 0;
656  *
657  * // Initialize the publish info.
658  * publishInfo.qos = MQTTQoS0;
659  * publishInfo.pTopicName = "/some/topic/name";
660  * publishInfo.topicNameLength = strlen( publishInfo.pTopicName );
661  * publishInfo.pPayload = "Hello World!";
662  * publishInfo.payloadLength = strlen( "Hello World!" );
663  *
664  * // Get the size requirement for the publish packet.
665  * status = MQTT_GetPublishPacketSize(
666  *      &publishInfo, &remainingLength, &packetSize
667  * );
668  *
669  * if( status == MQTTSuccess )
670  * {
671  *      // The application should allocate or use a static #MQTTFixedBuffer_t
672  *      // of size >= packetSize to serialize the publish.
673  * }
674  * @endcode
675  */
676 /* @[declare_mqtt_getpublishpacketsize] */
677 MQTTStatus_t MQTT_GetPublishPacketSize( const MQTTPublishInfo_t * pPublishInfo,
678                                         size_t * pRemainingLength,
679                                         size_t * pPacketSize );
680 /* @[declare_mqtt_getpublishpacketsize] */
681
682 /**
683  * @brief Serialize an MQTT PUBLISH packet in the given buffer.
684  *
685  * This function will serialize complete MQTT PUBLISH packet into
686  * the given buffer. If the PUBLISH payload can be sent separately,
687  * consider using #MQTT_SerializePublishHeader, which will serialize
688  * only the PUBLISH header into the buffer.
689  *
690  * #MQTT_GetPublishPacketSize should be called with @p pPublishInfo before
691  * invoking this function to get the size of the required #MQTTFixedBuffer_t and
692  * @p remainingLength. The @p remainingLength must be the same as returned by
693  * #MQTT_GetPublishPacketSize. The #MQTTFixedBuffer_t must be at least as large
694  * as the size returned by #MQTT_GetPublishPacketSize.
695  *
696  * @param[in] pPublishInfo MQTT PUBLISH packet parameters.
697  * @param[in] packetId packet ID generated by #MQTT_GetPacketId.
698  * @param[in] remainingLength Remaining Length provided by #MQTT_GetPublishPacketSize.
699  * @param[out] pFixedBuffer Buffer for packet serialization.
700  *
701  * @return #MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet;
702  * #MQTTBadParameter if invalid parameters are passed;
703  * #MQTTSuccess otherwise.
704  *
705  * <b>Example</b>
706  * @code{c}
707  *
708  * // Variables used in this example.
709  * MQTTStatus_t status;
710  * MQTTPublishInfo_t publishInfo = { 0 };
711  * MQTTFixedBuffer_t fixedBuffer;
712  * uint8_t buffer[ BUFFER_SIZE ];
713  * size_t remainingLength = 0, packetSize = 0;
714  * uint16_t packetId;
715  *
716  * fixedBuffer.pBuffer = buffer;
717  * fixedBuffer.size = BUFFER_SIZE;
718  *
719  * // A packet identifier is unused for QoS 0 publishes. Otherwise, a valid, unused packet
720  * // identifier must be used.
721  * packetId = 0;
722  *
723  * // Assume publishInfo has been initialized. Get publish packet size.
724  * status = MQTT_GetPublishPacketSize(
725  *      &publishInfo, &remainingLength, &packetSize
726  * );
727  * assert( status == MQTTSuccess );
728  * assert( packetSize <= BUFFER_SIZE );
729  *
730  * // Serialize the publish packet into the fixed buffer.
731  * status = MQTT_SerializePublish(
732  *      &publishInfo,
733  *      packetId,
734  *      remainingLength,
735  *      &fixedBuffer
736  * );
737  *
738  * if( status == MQTTSuccess )
739  * {
740  *      // The publish packet can now be sent to the broker.
741  * }
742  * @endcode
743  */
744 /* @[declare_mqtt_serializepublish] */
745 MQTTStatus_t MQTT_SerializePublish( const MQTTPublishInfo_t * pPublishInfo,
746                                     uint16_t packetId,
747                                     size_t remainingLength,
748                                     const MQTTFixedBuffer_t * pFixedBuffer );
749 /* @[declare_mqtt_serializepublish] */
750
751 /**
752  * @brief Serialize an MQTT PUBLISH packet header without the topic string in the
753  * given buffer. This function will add the topic string length to the provided
754  * buffer. This helps reduce an unnecessary copy of the topic string into the
755  * buffer.
756  *
757  * @param[in] pPublishInfo MQTT PUBLISH packet parameters.
758  * @param[in] remainingLength Remaining Length provided by #MQTT_GetPublishPacketSize.
759  * @param[out] pBuffer Buffer for packet serialization.
760  * @param[out] headerSize Size of the serialized MQTT PUBLISH header.
761  *
762  * @return #MQTTSuccess if the serialization is successful. Otherwise, #MQTTBadParameter.
763  */
764 MQTTStatus_t MQTT_SerializePublishHeaderWithoutTopic( const MQTTPublishInfo_t * pPublishInfo,
765                                                       size_t remainingLength,
766                                                       uint8_t * pBuffer,
767                                                       size_t * headerSize );
768
769 /**
770  * @brief Serialize an MQTT PUBLISH packet header in the given buffer.
771  *
772  * This function serializes PUBLISH header in to the given buffer. The payload
773  * for PUBLISH will not be copied over to the buffer. This will help reduce
774  * the memory needed for the buffer and avoid an unwanted copy operation of the
775  * PUBLISH payload into the buffer. If the payload also would need to be part of
776  * the serialized buffer, consider using #MQTT_SerializePublish.
777  *
778  * #MQTT_GetPublishPacketSize should be called with @p pPublishInfo before
779  * invoking this function to get the size of the required #MQTTFixedBuffer_t and
780  * @p remainingLength. The @p remainingLength must be the same as returned by
781  * #MQTT_GetPublishPacketSize. The #MQTTFixedBuffer_t must be at least as large
782  * as the size returned by #MQTT_GetPublishPacketSize.
783  *
784  * @param[in] pPublishInfo MQTT PUBLISH packet parameters.
785  * @param[in] packetId packet ID generated by #MQTT_GetPacketId.
786  * @param[in] remainingLength Remaining Length provided by #MQTT_GetPublishPacketSize.
787  * @param[out] pFixedBuffer Buffer for packet serialization.
788  * @param[out] pHeaderSize Size of the serialized MQTT PUBLISH header.
789  *
790  * @return #MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet;
791  * #MQTTBadParameter if invalid parameters are passed;
792  * #MQTTSuccess otherwise.
793  *
794  * <b>Example</b>
795  * @code{c}
796  *
797  * // Variables used in this example.
798  * MQTTStatus_t status;
799  * MQTTPublishInfo_t publishInfo = { 0 };
800  * MQTTFixedBuffer_t fixedBuffer;
801  * uint8_t buffer[ BUFFER_SIZE ];
802  * size_t remainingLength = 0, packetSize = 0, headerSize = 0;
803  * uint16_t packetId;
804  * int32_t bytesSent;
805  *
806  * fixedBuffer.pBuffer = buffer;
807  * fixedBuffer.size = BUFFER_SIZE;
808  *
809  * // A packet identifier is unused for QoS 0 publishes. Otherwise, a valid, unused packet
810  * // identifier must be used.
811  * packetId = 0;
812  *
813  * // Assume publishInfo has been initialized. Get the publish packet size.
814  * status = MQTT_GetPublishPacketSize(
815  *      &publishInfo, &remainingLength, &packetSize
816  * );
817  * assert( status == MQTTSuccess );
818  * // The payload will not be serialized, so the the fixed buffer does not need to hold it.
819  * assert( ( packetSize - publishInfo.payloadLength ) <= BUFFER_SIZE );
820  *
821  * // Serialize the publish packet header into the fixed buffer.
822  * status = MQTT_SerializePublishHeader(
823  *      &publishInfo,
824  *      packetId,
825  *      remainingLength,
826  *      &fixedBuffer,
827  *      &headerSize
828  * );
829  *
830  * if( status == MQTTSuccess )
831  * {
832  *      // The publish header and payload can now be sent to the broker.
833  *      // mqttSocket here is a socket descriptor created and connected to the MQTT
834  *      // broker outside of this function.
835  *      bytesSent = send( mqttSocket, ( void * ) fixedBuffer.pBuffer, headerSize, 0 );
836  *      assert( bytesSent == headerSize );
837  *      bytesSent = send( mqttSocket, publishInfo.pPayload, publishInfo.payloadLength, 0 );
838  *      assert( bytesSent == publishInfo.payloadLength );
839  * }
840  * @endcode
841  */
842 /* @[declare_mqtt_serializepublishheader] */
843 MQTTStatus_t MQTT_SerializePublishHeader( const MQTTPublishInfo_t * pPublishInfo,
844                                           uint16_t packetId,
845                                           size_t remainingLength,
846                                           const MQTTFixedBuffer_t * pFixedBuffer,
847                                           size_t * pHeaderSize );
848 /* @[declare_mqtt_serializepublishheader] */
849
850 /**
851  * @brief Serialize an MQTT PUBACK, PUBREC, PUBREL, or PUBCOMP into the given
852  * buffer.
853  *
854  * @param[out] pFixedBuffer Buffer for packet serialization.
855  * @param[in] packetType Byte of the corresponding packet fixed header per the
856  * MQTT spec.
857  * @param[in] packetId Packet ID of the publish.
858  *
859  * @return #MQTTBadParameter, #MQTTNoMemory, or #MQTTSuccess.
860  *
861  * <b>Example</b>
862  * @code{c}
863  *
864  * // Variables used in this example.
865  * MQTTStatus_t status;
866  * MQTTFixedBuffer_t fixedBuffer;
867  * uint8_t buffer[ BUFFER_SIZE ];
868  * uint16_t packetId;
869  * uint8_t packetType;
870  *
871  * fixedBuffer.pBuffer = buffer;
872  * fixedBuffer.size = BUFFER_SIZE;
873  * // The fixed buffer must be large enough to hold 4 bytes.
874  * assert( BUFFER_SIZE >= MQTT_PUBLISH_ACK_PACKET_SIZE );
875  *
876  * // The packet ID must be the same as the original publish packet.
877  * packetId = publishPacketId;
878  *
879  * // The byte representing a packet of type ACK. This function accepts PUBACK, PUBREC, PUBREL, or PUBCOMP.
880  * packetType = MQTT_PACKET_TYPE_PUBACK;
881  *
882  * // Serialize the publish acknowledgment into the fixed buffer.
883  * status = MQTT_SerializeAck( &fixedBuffer, packetType, packetId );
884  *
885  * if( status == MQTTSuccess )
886  * {
887  *      // The publish acknowledgment can now be sent to the broker.
888  * }
889  * @endcode
890  */
891 /* @[declare_mqtt_serializeack] */
892 MQTTStatus_t MQTT_SerializeAck( const MQTTFixedBuffer_t * pFixedBuffer,
893                                 uint8_t packetType,
894                                 uint16_t packetId );
895 /* @[declare_mqtt_serializeack] */
896
897 /**
898  * @brief Get the size of an MQTT DISCONNECT packet.
899  *
900  * @param[out] pPacketSize The size of the MQTT DISCONNECT packet.
901  *
902  * @return #MQTTSuccess, or #MQTTBadParameter if @p pPacketSize is NULL.
903  *
904  * <b>Example</b>
905  * @code{c}
906  *
907  * // Variables used in this example.
908  * MQTTStatus_t status;
909  * size_t packetSize = 0;
910  *
911  * // Get the size requirement for the disconnect packet.
912  * status = MQTT_GetDisconnectPacketSize( &packetSize );
913  * assert( status == MQTTSuccess );
914  * assert( packetSize == 2 );
915  *
916  * // The application should allocate or use a static #MQTTFixedBuffer_t of
917  * // size >= 2 to serialize the disconnect packet.
918  *
919  * @endcode
920  */
921 /* @[declare_mqtt_getdisconnectpacketsize] */
922 MQTTStatus_t MQTT_GetDisconnectPacketSize( size_t * pPacketSize );
923 /* @[declare_mqtt_getdisconnectpacketsize] */
924
925 /**
926  * @brief Serialize an MQTT DISCONNECT packet into the given buffer.
927  *
928  * The input #MQTTFixedBuffer_t.size must be at least as large as the size
929  * returned by #MQTT_GetDisconnectPacketSize.
930  *
931  * @param[out] pFixedBuffer Buffer for packet serialization.
932  *
933  * @return #MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet;
934  * #MQTTBadParameter if invalid parameters are passed;
935  * #MQTTSuccess otherwise.
936  *
937  * <b>Example</b>
938  * @code{c}
939  *
940  * // Variables used in this example.
941  * MQTTStatus_t status;
942  * MQTTFixedBuffer_t fixedBuffer;
943  * uint8_t buffer[ BUFFER_SIZE ];
944  *
945  * fixedBuffer.pBuffer = buffer;
946  * fixedBuffer.size = BUFFER_SIZE;
947  *
948  * // Get the disconnect packet size.
949  * status = MQTT_GetDisconnectPacketSize( &packetSize );
950  * assert( status == MQTTSuccess );
951  * assert( packetSize <= BUFFER_SIZE );
952  *
953  * // Serialize the disconnect into the fixed buffer.
954  * status = MQTT_SerializeDisconnect( &fixedBuffer );
955  *
956  * if( status == MQTTSuccess )
957  * {
958  *      // The disconnect packet can now be sent to the broker.
959  * }
960  * @endcode
961  */
962 /* @[declare_mqtt_serializedisconnect] */
963 MQTTStatus_t MQTT_SerializeDisconnect( const MQTTFixedBuffer_t * pFixedBuffer );
964 /* @[declare_mqtt_serializedisconnect] */
965
966 /**
967  * @brief Get the size of an MQTT PINGREQ packet.
968  *
969  * @param[out] pPacketSize The size of the MQTT PINGREQ packet.
970  *
971  * @return  #MQTTSuccess or #MQTTBadParameter if pPacketSize is NULL.
972  *
973  * <b>Example</b>
974  * @code{c}
975  *
976  * // Variables used in this example.
977  * MQTTStatus_t status;
978  * size_t packetSize = 0;
979  *
980  * // Get the size requirement for the ping request packet.
981  * status = MQTT_GetPingreqPacketSize( &packetSize );
982  * assert( status == MQTTSuccess );
983  * assert( packetSize == 2 );
984  *
985  * // The application should allocate or use a static #MQTTFixedBuffer_t of
986  * // size >= 2 to serialize the ping request.
987  *
988  * @endcode
989  */
990 /* @[declare_mqtt_getpingreqpacketsize] */
991 MQTTStatus_t MQTT_GetPingreqPacketSize( size_t * pPacketSize );
992 /* @[declare_mqtt_getpingreqpacketsize] */
993
994 /**
995  * @brief Serialize an MQTT PINGREQ packet into the given buffer.
996  *
997  * The input #MQTTFixedBuffer_t.size must be at least as large as the size
998  * returned by #MQTT_GetPingreqPacketSize.
999  *
1000  * @param[out] pFixedBuffer Buffer for packet serialization.
1001  *
1002  * @return #MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet;
1003  * #MQTTBadParameter if invalid parameters are passed;
1004  * #MQTTSuccess otherwise.
1005  *
1006  * <b>Example</b>
1007  * @code{c}
1008  *
1009  * // Variables used in this example.
1010  * MQTTStatus_t status;
1011  * MQTTFixedBuffer_t fixedBuffer;
1012  * uint8_t buffer[ BUFFER_SIZE ];
1013  *
1014  * fixedBuffer.pBuffer = buffer;
1015  * fixedBuffer.size = BUFFER_SIZE;
1016  *
1017  * // Get the ping request packet size.
1018  * status = MQTT_GetPingreqPacketSize( &packetSize );
1019  * assert( status == MQTTSuccess );
1020  * assert( packetSize <= BUFFER_SIZE );
1021  *
1022  * // Serialize the ping request into the fixed buffer.
1023  * status = MQTT_SerializePingreq( &fixedBuffer );
1024  *
1025  * if( status == MQTTSuccess )
1026  * {
1027  *      // The ping request can now be sent to the broker.
1028  * }
1029  * @endcode
1030  */
1031 /* @[declare_mqtt_serializepingreq] */
1032 MQTTStatus_t MQTT_SerializePingreq( const MQTTFixedBuffer_t * pFixedBuffer );
1033 /* @[declare_mqtt_serializepingreq] */
1034
1035 /**
1036  * @brief Deserialize an MQTT PUBLISH packet.
1037  *
1038  * @param[in] pIncomingPacket #MQTTPacketInfo_t containing the buffer.
1039  * @param[out] pPacketId The packet ID obtained from the buffer.
1040  * @param[out] pPublishInfo Struct containing information about the publish.
1041  *
1042  * @return #MQTTBadParameter, #MQTTBadResponse, or #MQTTSuccess.
1043  *
1044  * <b>Example</b>
1045  * @code{c}
1046  *
1047  * // TransportRecv_t function for reading from the network.
1048  * int32_t socket_recv(
1049  *      NetworkContext_t * pNetworkContext,
1050  *      void * pBuffer,
1051  *      size_t bytesToRecv
1052  * );
1053  * // Some context to be used with the above transport receive function.
1054  * NetworkContext_t networkContext;
1055  *
1056  * // Other variables used in this example.
1057  * MQTTStatus_t status;
1058  * MQTTPacketInfo_t incomingPacket;
1059  * MQTTPublishInfo_t publishInfo = { 0 };
1060  * uint16_t packetId;
1061  *
1062  * int32_t bytesRecvd;
1063  * // A buffer to hold remaining data of the incoming packet.
1064  * uint8_t buffer[ BUFFER_SIZE ];
1065  *
1066  * // Populate all fields of the incoming packet.
1067  * status = MQTT_GetIncomingPacketTypeAndLength(
1068  *      socket_recv,
1069  *      &networkContext,
1070  *      &incomingPacket
1071  * );
1072  * assert( status == MQTTSuccess );
1073  * assert( incomingPacket.remainingLength <= BUFFER_SIZE );
1074  * bytesRecvd = socket_recv(
1075  *      &networkContext,
1076  *      ( void * ) buffer,
1077  *      incomingPacket.remainingLength
1078  * );
1079  * incomingPacket.pRemainingData = buffer;
1080  *
1081  * // Deserialize the publish information if the incoming packet is a publish.
1082  * if( ( incomingPacket.type & 0xF0 ) == MQTT_PACKET_TYPE_PUBLISH )
1083  * {
1084  *      status = MQTT_DeserializePublish( &incomingPacket, &packetId, &publishInfo );
1085  *      if( status == MQTTSuccess )
1086  *      {
1087  *          // The deserialized publish information can now be used from `publishInfo`.
1088  *      }
1089  * }
1090  * @endcode
1091  */
1092 /* @[declare_mqtt_deserializepublish] */
1093 MQTTStatus_t MQTT_DeserializePublish( const MQTTPacketInfo_t * pIncomingPacket,
1094                                       uint16_t * pPacketId,
1095                                       MQTTPublishInfo_t * pPublishInfo );
1096 /* @[declare_mqtt_deserializepublish] */
1097
1098 /**
1099  * @brief Deserialize an MQTT CONNACK, SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL,
1100  * PUBCOMP, or PINGRESP.
1101  *
1102  * @param[in] pIncomingPacket #MQTTPacketInfo_t containing the buffer.
1103  * @param[out] pPacketId The packet ID of obtained from the buffer. Not used
1104  * in CONNACK or PINGRESP.
1105  * @param[out] pSessionPresent Boolean flag from a CONNACK indicating present session.
1106  *
1107  * @return #MQTTBadParameter, #MQTTBadResponse, #MQTTServerRefused, or #MQTTSuccess.
1108  *
1109  * <b>Example</b>
1110  * @code{c}
1111  *
1112  * // Variables used in this example.
1113  * MQTTStatus_t status;
1114  * MQTTPacketInfo_t incomingPacket;
1115  * // Used for SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, and PUBCOMP.
1116  * uint16_t packetId;
1117  * // Used for CONNACK.
1118  * bool sessionPresent;
1119  *
1120  * // Receive an incoming packet and populate all fields. The details are out of scope
1121  * // for this example.
1122  * receiveIncomingPacket( &incomingPacket );
1123  *
1124  * // Deserialize ack information if the incoming packet is not a publish.
1125  * if( ( incomingPacket.type & 0xF0 ) != MQTT_PACKET_TYPE_PUBLISH )
1126  * {
1127  *      status = MQTT_DeserializeAck( &incomingPacket, &packetId, &sessionPresent );
1128  *      if( status == MQTTSuccess )
1129  *      {
1130  *          // The packet ID or session present flag information is available. For
1131  *          // ping response packets, the only information is the status code.
1132  *      }
1133  * }
1134  * @endcode
1135  */
1136 /* @[declare_mqtt_deserializeack] */
1137 MQTTStatus_t MQTT_DeserializeAck( const MQTTPacketInfo_t * pIncomingPacket,
1138                                   uint16_t * pPacketId,
1139                                   bool * pSessionPresent );
1140 /* @[declare_mqtt_deserializeack] */
1141
1142 /**
1143  * @brief Extract the MQTT packet type and length from incoming packet.
1144  *
1145  * This function must be called for every incoming packet to retrieve the
1146  * #MQTTPacketInfo_t.type and #MQTTPacketInfo_t.remainingLength. A
1147  * #MQTTPacketInfo_t is not valid until this routine has been invoked.
1148  *
1149  * @param[in] readFunc Transport layer read function pointer.
1150  * @param[in] pNetworkContext The network context pointer provided by the application.
1151  * @param[out] pIncomingPacket Pointer to MQTTPacketInfo_t structure. This is
1152  * where type, remaining length and packet identifier are stored.
1153  *
1154  * @return #MQTTSuccess on successful extraction of type and length,
1155  * #MQTTBadParameter if @p pIncomingPacket is invalid,
1156  * #MQTTRecvFailed on transport receive failure,
1157  * #MQTTBadResponse if an invalid packet is read, and
1158  * #MQTTNoDataAvailable if there is nothing to read.
1159  *
1160  * <b>Example</b>
1161  * @code{c}
1162  *
1163  * // TransportRecv_t function for reading from the network.
1164  * int32_t socket_recv(
1165  *      NetworkContext_t * pNetworkContext,
1166  *      void * pBuffer,
1167  *      size_t bytesToRecv
1168  * );
1169  * // Some context to be used with above transport receive function.
1170  * NetworkContext_t networkContext;
1171  *
1172  * // Struct to hold the incoming packet information.
1173  * MQTTPacketInfo_t incomingPacket;
1174  * MQTTStatus_t status = MQTTSuccess;
1175  * int32_t bytesRecvd;
1176  * // Buffer to hold the remaining data of the incoming packet.
1177  * uint8_t buffer[ BUFFER_SIZE ];
1178  *
1179  * // Loop until data is available to be received.
1180  * do{
1181  *      status = MQTT_GetIncomingPacketTypeAndLength(
1182  *          socket_recv,
1183  *          &networkContext,
1184  *          &incomingPacket
1185  *      );
1186  * } while( status == MQTTNoDataAvailable );
1187  *
1188  * assert( status == MQTTSuccess );
1189  *
1190  * // Receive the rest of the incoming packet.
1191  * assert( incomingPacket.remainingLength <= BUFFER_SIZE );
1192  * bytesRecvd = socket_recv(
1193  *      &networkContext,
1194  *      ( void * ) buffer,
1195  *      incomingPacket.remainingLength
1196  * );
1197  *
1198  * // Set the remaining data field.
1199  * incomingPacket.pRemainingData = buffer;
1200  * @endcode
1201  */
1202 /* @[declare_mqtt_getincomingpackettypeandlength] */
1203 MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength( TransportRecv_t readFunc,
1204                                                   NetworkContext_t * pNetworkContext,
1205                                                   MQTTPacketInfo_t * pIncomingPacket );
1206 /* @[declare_mqtt_getincomingpackettypeandlength] */
1207
1208 /**
1209  * @brief Extract the MQTT packet type and length from incoming packet.
1210  *
1211  * This function must be called for every incoming packet to retrieve the
1212  * #MQTTPacketInfo_t.type and #MQTTPacketInfo_t.remainingLength. A
1213  * #MQTTPacketInfo_t is not valid until this routine has been invoked.
1214  *
1215  * @param[in] pBuffer The buffer holding the raw data to be processed
1216  * @param[in] pIndex Pointer to the index within the buffer to marking the end
1217  *            of raw data available.
1218  * @param[out] pIncomingPacket Structure used to hold the fields of the
1219  *            incoming packet.
1220  *
1221  * @return #MQTTSuccess on successful extraction of type and length,
1222  * #MQTTBadParameter if @p pIncomingPacket is invalid,
1223  * #MQTTBadResponse if an invalid packet is read, and
1224  * #MQTTNoDataAvailable if there is nothing to read.
1225  */
1226  /* @[declare_mqtt_processincomingpackettypeandlength] */
1227 MQTTStatus_t MQTT_ProcessIncomingPacketTypeAndLength( const uint8_t * pBuffer,
1228                                                       const size_t * pIndex,
1229                                                       MQTTPacketInfo_t * pIncomingPacket );
1230 /* @[declare_mqtt_processincomingpackettypeandlength] */
1231
1232 /**
1233  * @fn uint8_t * MQTT_SerializeConnectFixedHeader( uint8_t * pIndex, const MQTTConnectInfo_t * pConnectInfo, const MQTTPublishInfo_t * pWillInfo, size_t remainingLength );
1234  * @brief Serialize the fixed part of the connect packet header.
1235  *
1236  * @param[out] pIndex Pointer to the buffer where the header is to
1237  * be serialized.
1238  * @param[in] pConnectInfo The connect information.
1239  * @param[in] pWillInfo The last will and testament information.
1240  * @param[in] remainingLength The remaining length of the packet to be
1241  * serialized.
1242  *
1243  * @return A pointer to the end of the encoded string.
1244  */
1245
1246 /**
1247  * @cond DOXYGEN_IGNORE
1248  * Doxygen should ignore this definition, this function is private.
1249  */
1250 uint8_t * MQTT_SerializeConnectFixedHeader( uint8_t * pIndex,
1251                                             const MQTTConnectInfo_t * pConnectInfo,
1252                                             const MQTTPublishInfo_t * pWillInfo,
1253                                             size_t remainingLength );
1254 /** @endcond */
1255
1256 /**
1257  * @fn  uint8_t * MQTT_SerializeSubscribeHeader( size_t remainingLength, uint8_t * pIndex, uint16_t packetId );
1258  * @brief Serialize the fixed part of the subscribe packet header.
1259  *
1260  * @param[in] remainingLength The remaining length of the packet to be
1261  * serialized.
1262  * @param[in] pIndex Pointer to the buffer where the header is to
1263  * be serialized.
1264  * @param[in] packetId The packet ID to be serialized.
1265  *
1266  * @return A pointer to the end of the encoded string.
1267  */
1268
1269 /**
1270  * @cond DOXYGEN_IGNORE
1271  * Doxygen should ignore this definition, this function is private.
1272  */
1273 uint8_t * MQTT_SerializeSubscribeHeader( size_t remainingLength,
1274                                          uint8_t * pIndex,
1275                                          uint16_t packetId );
1276 /** @endcond */
1277
1278 /**
1279  * @fn uint8_t * MQTT_SerializeUnsubscribeHeader( size_t remainingLength, uint8_t * pIndex, uint16_t packetId );
1280  * @brief Serialize the fixed part of the unsubscribe packet header.
1281  *
1282  * @param[in] remainingLength The remaining length of the packet to be
1283  * serialized.
1284  * @param[in] pIndex Pointer to the buffer where the header is to
1285  * be serialized.
1286  * @param[in] packetId The packet ID to be serialized.
1287  *
1288  * @return A pointer to the end of the encoded string.
1289  */
1290
1291 /**
1292  * @cond DOXYGEN_IGNORE
1293  * Doxygen should ignore this definition, this function is private.
1294  */
1295 uint8_t * MQTT_SerializeUnsubscribeHeader( size_t remainingLength,
1296                                            uint8_t * pIndex,
1297                                            uint16_t packetId );
1298 /** @endcond */
1299
1300 /* *INDENT-OFF* */
1301 #ifdef __cplusplus
1302     }
1303 #endif
1304 /* *INDENT-ON* */
1305
1306 #endif /* ifndef CORE_MQTT_SERIALIZER_H */