• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2  * Copyright (c) 2009, 2018 IBM Corp.
3  *
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * and Eclipse Distribution License v1.0 which accompany this distribution.
7  *
8  * The Eclipse Public License is available at
9  *    http://www.eclipse.org/legal/epl-v10.html
10  * and the Eclipse Distribution License is available at
11  *   http://www.eclipse.org/org/documents/edl-v10.php.
12  *
13  * Contributors:
14  *    Ian Craggs - initial API and implementation and/or initial documentation
15  *    Ian Craggs, Allan Stockdill-Mander - SSL updates
16  *    Ian Craggs - multiple server connection support
17  *    Ian Craggs - MQTT 3.1.1 support
18  *    Ian Craggs - remove const from eyecatchers #168
19  *******************************************************************************/
20 
21 /**
22  * @cond MQTTClient_internal
23  * @mainpage MQTT Client Library Internals
24  * In the beginning there was one MQTT C client library, MQTTClient, as implemented in MQTTClient.c
25  * This library was designed to be easy to use for applications which didn't mind if some of the calls
26  * blocked for a while.  For instance, the MQTTClient_connect call will block until a successful
27  * connection has completed, or a connection has failed, which could be as long as the "connection
28  * timeout" interval, whose default is 30 seconds.
29  *
30  * However in mobile devices and other windowing environments, blocking on the GUI thread is a bad
31  * thing as it causes the user interface to freeze.  Hence a new API, MQTTAsync, implemented
32  * in MQTTAsync.c, was devised.  There are no blocking calls in this library, so it is well suited
33  * to GUI and mobile environments, at the expense of some extra complexity.
34  *
35  * Both libraries are designed to be sparing in the use of threads.  So multiple client objects are
36  * handled by one or two threads, with a select call in Socket_getReadySocket(), used to determine
37  * when a socket has incoming data.  This API is thread safe: functions may be called by multiple application
38  * threads, with the exception of ::MQTTClient_yield and ::MQTTClient_receive, which are intended
39  * for single threaded environments only.
40  *
41  * @endcond
42  * @cond MQTTClient_main
43  * @mainpage MQTT Client library for C
44  * © Copyright IBM Corp. 2009, 2018
45  *
46  * @brief An MQTT client library in C.
47  *
48  * These pages describe the original more synchronous API which might be
49  * considered easier to use.  Some of the calls will block.  For the new
50  * totally asynchronous API where no calls block, which is especially suitable
51  * for use in windowed environments, see the
52  * <a href="../../MQTTAsync/html/index.html">MQTT C Client Asynchronous API Documentation</a>.
53  * The MQTTClient API is not thread safe, whereas the MQTTAsync API is.
54  *
55  * An MQTT client application connects to MQTT-capable servers.
56  * A typical client is responsible for collecting information from a telemetry
57  * device and publishing the information to the server. It can also subscribe
58  * to topics, receive messages, and use this information to control the
59  * telemetry device.
60  *
61  * MQTT clients implement the published MQTT v3 protocol. You can write your own
62  * API to the MQTT protocol using the programming language and platform of your
63  * choice. This can be time-consuming and error-prone.
64  *
65  * To simplify writing MQTT client applications, this library encapsulates
66  * the MQTT v3 protocol for you. Using this library enables a fully functional
67  * MQTT client application to be written in a few lines of code.
68  * The information presented here documents the API provided
69  * by the MQTT Client library for C.
70  *
71  * <b>Using the client</b><br>
72  * Applications that use the client library typically use a similar structure:
73  * <ul>
74  * <li>Create a client object</li>
75  * <li>Set the options to connect to an MQTT server</li>
76  * <li>Set up callback functions if multi-threaded (asynchronous mode)
77  * operation is being used (see @ref async).</li>
78  * <li>Subscribe to any topics the client needs to receive</li>
79  * <li>Repeat until finished:</li>
80  *     <ul>
81  *     <li>Publish any messages the client needs to</li>
82  *     <li>Handle any incoming messages</li>
83  *     </ul>
84  * <li>Disconnect the client</li>
85  * <li>Free any memory being used by the client</li>
86  * </ul>
87  * Some simple examples are shown here:
88  * <ul>
89  * <li>@ref pubsync</li>
90  * <li>@ref pubasync</li>
91  * <li>@ref subasync</li>
92  * </ul>
93  * Additional information about important concepts is provided here:
94  * <ul>
95  * <li>@ref async</li>
96  * <li>@ref wildcard</li>
97  * <li>@ref qos</li>
98  * <li>@ref tracing</li>
99  * </ul>
100  * @endcond
101  */
102 
103 /*
104 /// @cond EXCLUDE
105 */
106 #if !defined(MQTTCLIENT_H)
107 #define MQTTCLIENT_H
108 
109 #if defined(__cplusplus)
110  extern "C" {
111 #endif
112 
113 #if defined(WIN32) || defined(WIN64)
114   #define DLLImport __declspec(dllimport)
115   #define DLLExport __declspec(dllexport)
116 #else
117   #define DLLImport extern
118   #define DLLExport __attribute__ ((visibility ("default")))
119 #endif
120 
121 #include <stdio.h>
122 /*
123 /// @endcond
124 */
125 
126 #include "MQTTProperties.h"
127 #include "MQTTReasonCodes.h"
128 #include "MQTTSubscribeOpts.h"
129 #if !defined(NO_PERSISTENCE)
130 #include "MQTTClientPersistence.h"
131 #endif
132 
133 /**
134  * Return code: No error. Indicates successful completion of an MQTT client
135  * operation.
136  */
137 #define MQTTCLIENT_SUCCESS 0
138 /**
139  * Return code: A generic error code indicating the failure of an MQTT client
140  * operation.
141  */
142 #define MQTTCLIENT_FAILURE -1
143 
144 /* error code -2 is MQTTCLIENT_PERSISTENCE_ERROR */
145 
146 /**
147  * Return code: The client is disconnected.
148  */
149 #define MQTTCLIENT_DISCONNECTED -3
150 /**
151  * Return code: The maximum number of messages allowed to be simultaneously
152  * in-flight has been reached.
153  */
154 #define MQTTCLIENT_MAX_MESSAGES_INFLIGHT -4
155 /**
156  * Return code: An invalid UTF-8 string has been detected.
157  */
158 #define MQTTCLIENT_BAD_UTF8_STRING -5
159 /**
160  * Return code: A NULL parameter has been supplied when this is invalid.
161  */
162 #define MQTTCLIENT_NULL_PARAMETER -6
163 /**
164  * Return code: The topic has been truncated (the topic string includes
165  * embedded NULL characters). String functions will not access the full topic.
166  * Use the topic length value to access the full topic.
167  */
168 #define MQTTCLIENT_TOPICNAME_TRUNCATED -7
169 /**
170  * Return code: A structure parameter does not have the correct eyecatcher
171  * and version number.
172  */
173 #define MQTTCLIENT_BAD_STRUCTURE -8
174 /**
175  * Return code: A QoS value that falls outside of the acceptable range (0,1,2)
176  */
177 #define MQTTCLIENT_BAD_QOS -9
178 /**
179  * Return code: Attempting SSL connection using non-SSL version of library
180  */
181 #define MQTTCLIENT_SSL_NOT_SUPPORTED -10
182  /**
183   * Return code: unrecognized MQTT version
184   */
185  #define MQTTCLIENT_BAD_MQTT_VERSION -11
186 /**
187  * Return code: protocol prefix in serverURI should be tcp://, ssl://, ws:// or wss://
188  * The TLS enabled prefixes (ssl, wss) are only valid if the TLS version of the library
189  * is linked with.
190  */
191 #define MQTTCLIENT_BAD_PROTOCOL -14
192  /**
193   * Return code: option not applicable to the requested version of MQTT
194   */
195  #define MQTTCLIENT_BAD_MQTT_OPTION -15
196  /**
197   * Return code: call not applicable to the requested version of MQTT
198   */
199  #define MQTTCLIENT_WRONG_MQTT_VERSION -16
200 
201 
202 /**
203  * Default MQTT version to connect with.  Use 3.1.1 then fall back to 3.1
204  */
205 #define MQTTVERSION_DEFAULT 0
206 /**
207  * MQTT version to connect with: 3.1
208  */
209 #define MQTTVERSION_3_1 3
210 /**
211  * MQTT version to connect with: 3.1.1
212  */
213 #define MQTTVERSION_3_1_1 4
214  /**
215   * MQTT version to connect with: 5
216   */
217  #define MQTTVERSION_5 5
218 /**
219  * Bad return code from subscribe, as defined in the 3.1.1 specification
220  */
221 #define MQTT_BAD_SUBSCRIBE 0x80
222 
223 /**
224  *  Initialization options
225  */
226 typedef struct
227 {
228 	/** The eyecatcher for this structure.  Must be MQTG. */
229 	char struct_id[4];
230 	/** The version number of this structure.  Must be 0 */
231 	int struct_version;
232 	/** 1 = we do openssl init, 0 = leave it to the application */
233 	int do_openssl_init;
234 } MQTTClient_init_options;
235 
236 #define MQTTClient_init_options_initializer { {'M', 'Q', 'T', 'G'}, 0, 0 }
237 
238 /**
239  * Global init of mqtt library. Call once on program start to set global behaviour.
240  * do_openssl_init - if mqtt library should initialize OpenSSL (1) or rely on the caller to do it before using the library (0)
241  */
242 DLLExport void MQTTClient_global_init(MQTTClient_init_options* inits);
243 
244 /**
245  * A handle representing an MQTT client. A valid client handle is available
246  * following a successful call to MQTTClient_create().
247  */
248 typedef void* MQTTClient;
249 /**
250  * A value representing an MQTT message. A delivery token is returned to the
251  * client application when a message is published. The token can then be used to
252  * check that the message was successfully delivered to its destination (see
253  * MQTTClient_publish(),
254  * MQTTClient_publishMessage(),
255  * MQTTClient_deliveryComplete(),
256  * MQTTClient_waitForCompletion() and
257  * MQTTClient_getPendingDeliveryTokens()).
258  */
259 typedef int MQTTClient_deliveryToken;
260 typedef int MQTTClient_token;
261 
262 /**
263  * A structure representing the payload and attributes of an MQTT message. The
264  * message topic is not part of this structure (see MQTTClient_publishMessage(),
265  * MQTTClient_publish(), MQTTClient_receive(), MQTTClient_freeMessage()
266  * and MQTTClient_messageArrived()).
267  */
268 typedef struct
269 {
270 	/** The eyecatcher for this structure.  must be MQTM. */
271 	char struct_id[4];
272 	/** The version number of this structure.  Must be 0 or 1
273 	 *  0 indicates no message properties */
274 	int struct_version;
275 	/** The length of the MQTT message payload in bytes. */
276 	int payloadlen;
277 	/** A pointer to the payload of the MQTT message. */
278 	void* payload;
279 	/**
280      * The quality of service (QoS) assigned to the message.
281      * There are three levels of QoS:
282      * <DL>
283      * <DT><B>QoS0</B></DT>
284      * <DD>Fire and forget - the message may not be delivered</DD>
285      * <DT><B>QoS1</B></DT>
286      * <DD>At least once - the message will be delivered, but may be
287      * delivered more than once in some circumstances.</DD>
288      * <DT><B>QoS2</B></DT>
289      * <DD>Once and one only - the message will be delivered exactly once.</DD>
290      * </DL>
291      */
292 	int qos;
293 	/**
294      * The retained flag serves two purposes depending on whether the message
295      * it is associated with is being published or received.
296      *
297      * <b>retained = true</b><br>
298      * For messages being published, a true setting indicates that the MQTT
299      * server should retain a copy of the message. The message will then be
300      * transmitted to new subscribers to a topic that matches the message topic.
301      * For subscribers registering a new subscription, the flag being true
302      * indicates that the received message is not a new one, but one that has
303      * been retained by the MQTT server.
304      *
305      * <b>retained = false</b> <br>
306      * For publishers, this indicates that this message should not be retained
307      * by the MQTT server. For subscribers, a false setting indicates this is
308      * a normal message, received as a result of it being published to the
309      * server.
310      */
311 	int retained;
312 	/**
313       * The dup flag indicates whether or not this message is a duplicate.
314       * It is only meaningful when receiving QoS1 messages. When true, the
315       * client application should take appropriate action to deal with the
316       * duplicate message.
317       */
318 	int dup;
319 	/** The message identifier is normally reserved for internal use by the
320       * MQTT client and server.
321       */
322 	int msgid;
323 	/**
324 	 * The MQTT V5 properties associated with the message.
325 	 */
326 	MQTTProperties properties;
327 } MQTTClient_message;
328 
329 #define MQTTClient_message_initializer { {'M', 'Q', 'T', 'M'}, 1, 0, NULL, 0, 0, 0, 0, MQTTProperties_initializer }
330 
331 /**
332  * This is a callback function. The client application
333  * must provide an implementation of this function to enable asynchronous
334  * receipt of messages. The function is registered with the client library by
335  * passing it as an argument to MQTTClient_setCallbacks(). It is
336  * called by the client library when a new message that matches a client
337  * subscription has been received from the server. This function is executed on
338  * a separate thread to the one on which the client application is running.
339  * @param context A pointer to the <i>context</i> value originally passed to
340  * MQTTClient_setCallbacks(), which contains any application-specific context.
341  * @param topicName The topic associated with the received message.
342  * @param topicLen The length of the topic if there are one
343  * more NULL characters embedded in <i>topicName</i>, otherwise <i>topicLen</i>
344  * is 0. If <i>topicLen</i> is 0, the value returned by <i>strlen(topicName)</i>
345  * can be trusted. If <i>topicLen</i> is greater than 0, the full topic name
346  * can be retrieved by accessing <i>topicName</i> as a byte array of length
347  * <i>topicLen</i>.
348  * @param message The MQTTClient_message structure for the received message.
349  * This structure contains the message payload and attributes.
350  * @return This function must return a boolean value indicating whether or not
351  * the message has been safely received by the client application. Returning
352  * true indicates that the message has been successfully handled.
353  * Returning false indicates that there was a problem. In this
354  * case, the client library will reinvoke MQTTClient_messageArrived() to
355  * attempt to deliver the message to the application again.
356  */
357 typedef int MQTTClient_messageArrived(void* context, char* topicName, int topicLen, MQTTClient_message* message);
358 
359 /**
360  * This is a callback function. The client application
361  * must provide an implementation of this function to enable asynchronous
362  * notification of delivery of messages. The function is registered with the
363  * client library by passing it as an argument to MQTTClient_setCallbacks().
364  * It is called by the client library after the client application has
365  * published a message to the server. It indicates that the necessary
366  * handshaking and acknowledgements for the requested quality of service (see
367  * MQTTClient_message.qos) have been completed. This function is executed on a
368  * separate thread to the one on which the client application is running.
369  * <b>Note:</b>MQTTClient_deliveryComplete() is not called when messages are
370  * published at QoS0.
371  * @param context A pointer to the <i>context</i> value originally passed to
372  * MQTTClient_setCallbacks(), which contains any application-specific context.
373  * @param dt The ::MQTTClient_deliveryToken associated with
374  * the published message. Applications can check that all messages have been
375  * correctly published by matching the delivery tokens returned from calls to
376  * MQTTClient_publish() and MQTTClient_publishMessage() with the tokens passed
377  * to this callback.
378  */
379 typedef void MQTTClient_deliveryComplete(void* context, MQTTClient_deliveryToken dt);
380 
381 /**
382  * This is a callback function. The client application
383  * must provide an implementation of this function to enable asynchronous
384  * notification of the loss of connection to the server. The function is
385  * registered with the client library by passing it as an argument to
386  * MQTTClient_setCallbacks(). It is called by the client library if the client
387  * loses its connection to the server. The client application must take
388  * appropriate action, such as trying to reconnect or reporting the problem.
389  * This function is executed on a separate thread to the one on which the
390  * client application is running.
391  * @param context A pointer to the <i>context</i> value originally passed to
392  * MQTTClient_setCallbacks(), which contains any application-specific context.
393  * @param cause The reason for the disconnection.
394  * Currently, <i>cause</i> is always set to NULL.
395  */
396 typedef void MQTTClient_connectionLost(void* context, char* cause);
397 
398 /**
399  * This function sets the callback functions for a specific client.
400  * If your client application doesn't use a particular callback, set the
401  * relevant parameter to NULL. Calling MQTTClient_setCallbacks() puts the
402  * client into multi-threaded mode. Any necessary message acknowledgements and
403  * status communications are handled in the background without any intervention
404  * from the client application. See @ref async for more information.
405  *
406  * <b>Note:</b> The MQTT client must be disconnected when this function is
407  * called.
408  * @param handle A valid client handle from a successful call to
409  * MQTTClient_create().
410  * @param context A pointer to any application-specific context. The
411  * the <i>context</i> pointer is passed to each of the callback functions to
412  * provide access to the context information in the callback.
413  * @param cl A pointer to an MQTTClient_connectionLost() callback
414  * function. You can set this to NULL if your application doesn't handle
415  * disconnections.
416  * @param ma A pointer to an MQTTClient_messageArrived() callback
417  * function. This callback function must be specified when you call
418  * MQTTClient_setCallbacks().
419  * @param dc A pointer to an MQTTClient_deliveryComplete() callback
420  * function. You can set this to NULL if your application publishes
421  * synchronously or if you do not want to check for successful delivery.
422  * @return ::MQTTCLIENT_SUCCESS if the callbacks were correctly set,
423  * ::MQTTCLIENT_FAILURE if an error occurred.
424  */
425 DLLExport int MQTTClient_setCallbacks(MQTTClient handle, void* context, MQTTClient_connectionLost* cl,
426 									MQTTClient_messageArrived* ma, MQTTClient_deliveryComplete* dc);
427 
428 
429 /**
430  * This is a callback function, which will be called when the a disconnect
431  * packet is received from the server.  This applies to MQTT V5 and above only.
432  * @param context A pointer to the <i>context</i> value originally passed to
433  * ::MQTTAsync_setDisconnected(), which contains any application-specific context.
434  * @param properties The MQTT V5 properties received with the disconnect, if any.
435  * @param reasonCode The MQTT V5 reason code received with the disconnect.
436  * Currently, <i>cause</i> is always set to NULL.
437  */
438 typedef void MQTTClient_disconnected(void* context, MQTTProperties* properties,
439 		enum MQTTReasonCodes reasonCode);
440 
441 /**
442  * Sets the MQTTClient_disconnected() callback function for a client.  This will be called
443  * if a disconnect packet is received from the server.  Only valid for MQTT V5 and above.
444  * @param handle A valid client handle from a successful call to
445  * MQTTClient_create().
446  * @param context A pointer to any application-specific context. The
447  * the <i>context</i> pointer is passed to each of the callback functions to
448  * provide access to the context information in the callback.
449  * @param co A pointer to an MQTTClient_disconnected() callback
450  * function.  NULL removes the callback setting.
451  * @return ::MQTTCLIENT_SUCCESS if the callbacks were correctly set,
452  * ::MQTTCLIENT_FAILURE if an error occurred.
453  */
454 DLLExport int MQTTClient_setDisconnected(MQTTClient handle, void* context, MQTTClient_disconnected* co);
455 
456 /**
457  * This is a callback function, the MQTT V5 version of MQTTClient_deliveryComplete().
458  * The client application
459  * must provide an implementation of this function to enable asynchronous
460  * notification of the completed delivery of messages.
461  * It is called by the client library after the client application has
462  * published a message to the server. It indicates that the necessary
463  * handshaking and acknowledgements for the requested quality of service (see
464  * MQTTClient_message.qos) have been completed. This function is executed on a
465  * separate thread to the one on which the client application is running.
466  * <b>Note:</b> It is not called when messages are published at QoS0.
467  * @param context A pointer to the <i>context</i> value originally passed to
468  * MQTTClient_setCallbacks(), which contains any application-specific context.
469  * @param dt The ::MQTTClient_deliveryToken associated with
470  * the published message. Applications can check that all messages have been
471  * correctly published by matching the delivery tokens returned from calls to
472  * MQTTClient_publish() and MQTTClient_publishMessage() with the tokens passed
473  * to this callback.
474  * @param packet_type the last received packet type for this completion. For QoS 1
475  * always PUBACK.  For QoS 2 could be PUBREC or PUBCOMP.
476  * @param properties the MQTT V5 properties returned with the last packet from the server
477  * @param reasonCode the reason code returned from the server
478  */
479 typedef void MQTTClient_published(void* context, int dt, int packet_type, MQTTProperties* properties,
480 		enum MQTTReasonCodes reasonCode);
481 
482 DLLExport int MQTTClient_setPublished(MQTTClient handle, void* context, MQTTClient_published* co);
483 
484 /**
485  * This function creates an MQTT client ready for connection to the
486  * specified server and using the specified persistent storage (see
487  * MQTTClient_persistence). See also MQTTClient_destroy().
488  * @param handle A pointer to an ::MQTTClient handle. The handle is
489  * populated with a valid client reference following a successful return from
490  * this function.
491  * @param serverURI A null-terminated string specifying the server to
492  * which the client will connect. It takes the form <i>protocol://host:port</i>.
493  * Currently, <i>protocol</i> must be <i>tcp</i> or <i>ssl</i>.
494  * For <i>host</i>, you can
495  * specify either an IP address or a host name. For instance, to connect to
496  * a server running on the local machines with the default MQTT port, specify
497  * <i>tcp://localhost:1883</i>.
498  * @param clientId The client identifier passed to the server when the
499  * client connects to it. It is a null-terminated UTF-8 encoded string.
500  * @param persistence_type The type of persistence to be used by the client:
501  * <br>
502  * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or
503  * system on which the client is running fails or is switched off, the current
504  * state of any in-flight messages is lost and some messages may not be
505  * delivered even at QoS1 and QoS2.
506  * <br>
507  * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based)
508  * persistence mechanism. Status about in-flight messages is held in persistent
509  * storage and provides some protection against message loss in the case of
510  * unexpected failure.
511  * <br>
512  * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence
513  * implementation. Using this type of persistence gives control of the
514  * persistence mechanism to the application. The application has to implement
515  * the MQTTClient_persistence interface.
516  * @param persistence_context If the application uses
517  * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should
518  * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it
519  * should be set to the location of the persistence directory (if set
520  * to NULL, the persistence directory used is the working directory).
521  * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this
522  * argument to point to a valid MQTTClient_persistence structure.
523  * @return ::MQTTCLIENT_SUCCESS if the client is successfully created, otherwise
524  * an error code is returned.
525  */
526 DLLExport int MQTTClient_create(MQTTClient* handle, const char* serverURI, const char* clientId,
527 		int persistence_type, void* persistence_context);
528 
529 typedef struct
530 {
531 	/** The eyecatcher for this structure.  must be MQCO. */
532 	char struct_id[4];
533 	/** The version number of this structure.  Must be 0 */
534 	int struct_version;
535 	/** Whether the MQTT version is 3.1, 3.1.1, or 5.  To use V5, this must be set.
536 	 *  MQTT V5 has to be chosen here, because during the create call the message persistence
537 	 *  is initialized, and we want to know whether the format of any persisted messages
538 	 *  is appropriate for the MQTT version we are going to connect with.  Selecting 3.1 or
539 	 *  3.1.1 and attempting to read 5.0 persisted messages will result in an error on create.  */
540 	int MQTTVersion;
541 } MQTTClient_createOptions;
542 
543 #define MQTTClient_createOptions_initializer { {'M', 'Q', 'C', 'O'}, 0, MQTTVERSION_DEFAULT }
544 
545 /**
546  * A version of :MQTTClient_create() with additional options.
547  * This function creates an MQTT client ready for connection to the
548  * specified server and using the specified persistent storage (see
549  * MQTTClient_persistence). See also MQTTClient_destroy().
550  * @param handle A pointer to an ::MQTTClient handle. The handle is
551  * populated with a valid client reference following a successful return from
552  * this function.
553  * @param serverURI A null-terminated string specifying the server to
554  * which the client will connect. It takes the form <i>protocol://host:port</i>.
555  * Currently, <i>protocol</i> must be <i>tcp</i> or <i>ssl</i>.
556  * For <i>host</i>, you can
557  * specify either an IP address or a host name. For instance, to connect to
558  * a server running on the local machines with the default MQTT port, specify
559  * <i>tcp://localhost:1883</i>.
560  * @param clientId The client identifier passed to the server when the
561  * client connects to it. It is a null-terminated UTF-8 encoded string.
562  * @param persistence_type The type of persistence to be used by the client:
563  * <br>
564  * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or
565  * system on which the client is running fails or is switched off, the current
566  * state of any in-flight messages is lost and some messages may not be
567  * delivered even at QoS1 and QoS2.
568  * <br>
569  * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based)
570  * persistence mechanism. Status about in-flight messages is held in persistent
571  * storage and provides some protection against message loss in the case of
572  * unexpected failure.
573  * <br>
574  * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence
575  * implementation. Using this type of persistence gives control of the
576  * persistence mechanism to the application. The application has to implement
577  * the MQTTClient_persistence interface.
578  * @param persistence_context If the application uses
579  * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should
580  * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it
581  * should be set to the location of the persistence directory (if set
582  * to NULL, the persistence directory used is the working directory).
583  * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this
584  * argument to point to a valid MQTTClient_persistence structure.
585  * @param options additional options for the create.
586  * @return ::MQTTCLIENT_SUCCESS if the client is successfully created, otherwise
587  * an error code is returned.
588  */
589 DLLExport int MQTTClient_createWithOptions(MQTTClient* handle, const char* serverURI, const char* clientId,
590 		int persistence_type, void* persistence_context, MQTTClient_createOptions* options);
591 
592 /**
593  * MQTTClient_willOptions defines the MQTT "Last Will and Testament" (LWT) settings for
594  * the client. In the event that a client unexpectedly loses its connection to
595  * the server, the server publishes the LWT message to the LWT topic on
596  * behalf of the client. This allows other clients (subscribed to the LWT topic)
597  * to be made aware that the client has disconnected. To enable the LWT
598  * function for a specific client, a valid pointer to an MQTTClient_willOptions
599  * structure is passed in the MQTTClient_connectOptions structure used in the
600  * MQTTClient_connect() call that connects the client to the server. The pointer
601  * to MQTTClient_willOptions can be set to NULL if the LWT function is not
602  * required.
603  */
604 typedef struct
605 {
606 	/** The eyecatcher for this structure.  must be MQTW. */
607 	char struct_id[4];
608 	/** The version number of this structure.  Must be 0 or 1
609 		   0 means there is no binary payload option
610 	 */
611 	int struct_version;
612 	/** The LWT topic to which the LWT message will be published. */
613 	const char* topicName;
614 	/** The LWT payload in string form. */
615 	const char* message;
616 	/**
617 	 * The retained flag for the LWT message (see MQTTClient_message.retained).
618 	 */
619 	int retained;
620 	/**
621 	 * The quality of service setting for the LWT message (see
622 	 * MQTTClient_message.qos and @ref qos).
623 	 */
624 	int qos;
625   /** The LWT payload in binary form. This is only checked and used if the message option is NULL */
626 	struct
627 	{
628 		int len;            /**< binary payload length */
629 		const void* data;  /**< binary payload data */
630 	} payload;
631 } MQTTClient_willOptions;
632 
633 #define MQTTClient_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, {0, NULL} }
634 
635 #define MQTT_SSL_VERSION_DEFAULT 0
636 #define MQTT_SSL_VERSION_TLS_1_0 1
637 #define MQTT_SSL_VERSION_TLS_1_1 2
638 #define MQTT_SSL_VERSION_TLS_1_2 3
639 
640 #if defined (__LITEOS__)
641 typedef struct
642 {
643 	const unsigned char* body;            /**< string of cert in PEM format */
644 	size_t size;  /**< binary payload data */
645 } cert_string;
646 
647 typedef struct
648 {
649 	const unsigned char* body;            /**< string of key in KEY forma */
650 	size_t size;  /**< binary payload data */
651 } key_string;
652 
653 #endif
654 /**
655 * MQTTClient_sslProperties defines the settings to establish an SSL/TLS connection using the
656 * OpenSSL library. It covers the following scenarios:
657 * - Server authentication: The client needs the digital certificate of the server. It is included
658 *   in a store containting trusted material (also known as "trust store").
659 * - Mutual authentication: Both client and server are authenticated during the SSL handshake. In
660 *   addition to the digital certificate of the server in a trust store, the client will need its own
661 *   digital certificate and the private key used to sign its digital certificate stored in a "key store".
662 * - Anonymous connection: Both client and server do not get authenticated and no credentials are needed
663 *   to establish an SSL connection. Note that this scenario is not fully secure since it is subject to
664 *   man-in-the-middle attacks.
665 */
666 typedef struct
667 {
668 	/** The eyecatcher for this structure.  Must be MQTS */
669 	char struct_id[4];
670 	/** The version number of this structure.  Must be 0, or 1 to enable TLS version selection. */
671 	int struct_version;
672 
673 	/** The file in PEM format containing the public digital certificates trusted by the client. */
674 	const char* trustStore;
675 
676 	/** The file in PEM format containing the public certificate chain of the client. It may also include
677 	* the client's private key.
678 	*/
679 	const char* keyStore;
680 
681 	/** If not included in the sslKeyStore, this setting points to the file in PEM format containing
682 	* the client's private key.
683 	*/
684 	const char* privateKey;
685 	/** The password to load the client's privateKey if encrypted. */
686 	const char* privateKeyPassword;
687 
688 	/**
689 	* The list of cipher suites that the client will present to the server during the SSL handshake. For a
690 	* full explanation of the cipher list format, please see the OpenSSL on-line documentation:
691 	* http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT
692 	* If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding
693 	* those offering no encryption- will be considered.
694 	* This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance).
695 	*/
696 	const char* enabledCipherSuites;
697 
698     /** True/False option to enable verification of the server certificate **/
699     int enableServerCertAuth;
700 
701     /** The SSL/TLS version to use. Specify one of MQTT_SSL_VERSION_DEFAULT (0),
702     * MQTT_SSL_VERSION_TLS_1_0 (1), MQTT_SSL_VERSION_TLS_1_1 (2) or MQTT_SSL_VERSION_TLS_1_2 (3).
703     * Only used if struct_version is >= 1.
704     */
705     int sslVersion;
706 
707     /**
708      * Whether to carry out post-connect checks, including that a certificate
709      * matches the given host name.
710      * Exists only if struct_version >= 2
711      */
712     int verify;
713 
714     /**
715      * From the OpenSSL documentation:
716      * If CApath is not NULL, it points to a directory containing CA certificates in PEM format.
717      * Exists only if struct_version >= 2
718 	 */
719 	const char* CApath;
720 
721     /**
722      * Callback function for OpenSSL error handler ERR_print_errors_cb
723      * Exists only if struct_version >= 3
724      */
725     int (*ssl_error_cb) (const char *str, size_t len, void *u);
726 
727     /**
728      * Application-specific contex for OpenSSL error handler ERR_print_errors_cb
729      * Exists only if struct_version >= 3
730      */
731     void* ssl_error_context;
732 
733 	/**
734 	 * Callback function for setting TLS-PSK options. Parameters correspond to that of
735 	 * SSL_CTX_set_psk_client_callback, except for u which is the pointer ssl_psk_context.
736 	 * Exists only if struct_version >= 4
737 	 */
738 	unsigned int (*ssl_psk_cb) (const char *hint, char *identity, unsigned int max_identity_len, unsigned char *psk, unsigned int max_psk_len, void *u);
739 
740 	/**
741 	 * Application-specific contex for ssl_psk_cb
742 	 * Exists only if struct_version >= 4
743 	 */
744 	void* ssl_psk_context;
745 
746 	/**
747 	 * Don't load default SSL CA. Should be used together with PSK to make sure
748 	 * regular servers with certificate in place is not accepted.
749 	 * Exists only if struct_version >= 4
750 	 */
751 	int disableDefaultTrustStore;
752 #if defined (__LITEOS__)
753 	/**  */
754 	const cert_string* los_trustStore;
755 
756 	/**  */
757 	const cert_string* los_keyStore;
758 
759 	/**  */
760 	const key_string* los_privateKey;
761 
762 #endif
763 
764 } MQTTClient_SSLOptions;
765 
766 #define MQTTClient_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 4, NULL, NULL, NULL, NULL, NULL, 1, MQTT_SSL_VERSION_DEFAULT, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, NULL }
767 
768 /**
769  * MQTTClient_connectOptions defines several settings that control the way the
770  * client connects to an MQTT server.
771  *
772  * <b>Note:</b> Default values are not defined for members of
773  * MQTTClient_connectOptions so it is good practice to specify all settings.
774  * If the MQTTClient_connectOptions structure is defined as an automatic
775  * variable, all members are set to random values and thus must be set by the
776  * client application. If the MQTTClient_connectOptions structure is defined
777  * as a static variable, initialization (in compliant compilers) sets all
778  * values to 0 (NULL for pointers). A #keepAliveInterval setting of 0 prevents
779  * correct operation of the client and so you <b>must</b> at least set a value
780  * for #keepAliveInterval.
781  */
782 typedef struct
783 {
784 	/** The eyecatcher for this structure.  must be MQTC. */
785 	char struct_id[4];
786 	/** The version number of this structure.  Must be 0, 1, 2, 3, 4, 5 or 6.
787 	 * 0 signifies no SSL options and no serverURIs
788 	 * 1 signifies no serverURIs
789 	 * 2 signifies no MQTTVersion
790 	 * 3 signifies no returned values
791 	 * 4 signifies no binary password option
792 	 * 5 signifies no maxInflightMessages and cleanstart
793 	 */
794 	int struct_version;
795 	/** The "keep alive" interval, measured in seconds, defines the maximum time
796    * that should pass without communication between the client and the server
797    * The client will ensure that at least one message travels across the
798    * network within each keep alive period.  In the absence of a data-related
799 	 * message during the time period, the client sends a very small MQTT
800    * "ping" message, which the server will acknowledge. The keep alive
801    * interval enables the client to detect when the server is no longer
802 	 * available without having to wait for the long TCP/IP timeout.
803 	 */
804 	int keepAliveInterval;
805 	/**
806    * This is a boolean value. The cleansession setting controls the behaviour
807    * of both the client and the server at connection and disconnection time.
808    * The client and server both maintain session state information. This
809    * information is used to ensure "at least once" and "exactly once"
810    * delivery, and "exactly once" receipt of messages. Session state also
811    * includes subscriptions created by an MQTT client. You can choose to
812    * maintain or discard state information between sessions.
813    *
814    * When cleansession is true, the state information is discarded at
815    * connect and disconnect. Setting cleansession to false keeps the state
816    * information. When you connect an MQTT client application with
817    * MQTTClient_connect(), the client identifies the connection using the
818    * client identifier and the address of the server. The server checks
819    * whether session information for this client
820    * has been saved from a previous connection to the server. If a previous
821    * session still exists, and cleansession=true, then the previous session
822    * information at the client and server is cleared. If cleansession=false,
823    * the previous session is resumed. If no previous session exists, a new
824    * session is started.
825 	 */
826 	int cleansession;
827 	/**
828    * This is a boolean value that controls how many messages can be in-flight
829    * simultaneously. Setting <i>reliable</i> to true means that a published
830    * message must be completed (acknowledgements received) before another
831    * can be sent. Attempts to publish additional messages receive an
832    * ::MQTTCLIENT_MAX_MESSAGES_INFLIGHT return code. Setting this flag to
833    * false allows up to 10 messages to be in-flight. This can increase
834    * overall throughput in some circumstances.
835 	 */
836 	int reliable;
837 	/**
838    * This is a pointer to an MQTTClient_willOptions structure. If your
839    * application does not make use of the Last Will and Testament feature,
840    * set this pointer to NULL.
841    */
842 	MQTTClient_willOptions* will;
843 	/**
844    * MQTT servers that support the MQTT v3.1.1 protocol provide authentication
845    * and authorisation by user name and password. This is the user name
846    * parameter.
847    */
848 	const char* username;
849 	/**
850    * MQTT servers that support the MQTT v3.1.1 protocol provide authentication
851    * and authorisation by user name and password. This is the password
852    * parameter.
853    */
854 	const char* password;
855 	/**
856    * The time interval in seconds to allow a connect to complete.
857    */
858 	int connectTimeout;
859 	/**
860 	 * The time interval in seconds after which unacknowledged publish requests are
861 	 * retried during a TCP session.  With MQTT 3.1.1 and later, retries are
862 	 * not required except on reconnect.  0 turns off in-session retries, and is the
863 	 * recommended setting.  Adding retries to an already overloaded network only
864 	 * exacerbates the problem.
865 	 */
866 	int retryInterval;
867 	/**
868    * This is a pointer to an MQTTClient_SSLOptions structure. If your
869    * application does not make use of SSL, set this pointer to NULL.
870    */
871 	MQTTClient_SSLOptions* ssl;
872 	/**
873 	 * The number of entries in the optional serverURIs array. Defaults to 0.
874 	 */
875 	int serverURIcount;
876 	/**
877    * An optional array of null-terminated strings specifying the servers to
878    * which the client will connect. Each string takes the form <i>protocol://host:port</i>.
879    * <i>protocol</i> must be <i>tcp</i> or <i>ssl</i>. For <i>host</i>, you can
880    * specify either an IP address or a host name. For instance, to connect to
881    * a server running on the local machines with the default MQTT port, specify
882    * <i>tcp://localhost:1883</i>.
883    * If this list is empty (the default), the server URI specified on MQTTClient_create()
884    * is used.
885    */
886 	char* const* serverURIs;
887 	/**
888 	 * Sets the version of MQTT to be used on the connect.
889 	 * MQTTVERSION_DEFAULT (0) = default: start with 3.1.1, and if that fails, fall back to 3.1
890 	 * MQTTVERSION_3_1 (3) = only try version 3.1
891 	 * MQTTVERSION_3_1_1 (4) = only try version 3.1.1
892 	 * MQTTVERSION_5 (5) = only try version 5.0
893 	 */
894 	int MQTTVersion;
895 	/**
896 	 * Returned from the connect when the MQTT version used to connect is 3.1.1
897 	 */
898 	struct
899 	{
900 		const char* serverURI;     /**< the serverURI connected to */
901 		int MQTTVersion;     /**< the MQTT version used to connect with */
902 		int sessionPresent;  /**< if the MQTT version is 3.1.1, the value of sessionPresent returned in the connack */
903 	} returned;
904 	/**
905    * Optional binary password.  Only checked and used if the password option is NULL
906    */
907 	struct
908 	{
909 		int len;           /**< binary password length */
910 		const void* data;  /**< binary password data */
911 	} binarypwd;
912 	/**
913 	 * The maximum number of messages in flight
914 	 */
915 	int maxInflightMessages;
916 	/*
917 	 * MQTT V5 clean start flag.  Only clears state at the beginning of the session.
918 	 */
919 	int cleanstart;
920 } MQTTClient_connectOptions;
921 
922 #define MQTTClient_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 6, 60, 1, 1, NULL, NULL, NULL, 30, 0, NULL, 0, NULL, MQTTVERSION_DEFAULT, {NULL, 0, 0}, {0, NULL}, -1, 0}
923 
924 #define MQTTClient_connectOptions_initializer5 { {'M', 'Q', 'T', 'C'}, 6, 60, 0, 1, NULL, NULL, NULL, 30, 0, NULL, 0, NULL, MQTTVERSION_5, {NULL, 0, 0}, {0, NULL}, -1, 1}
925 
926 /**
927   * MQTTClient_libraryInfo is used to store details relating to the currently used
928   * library such as the version in use, the time it was built and relevant openSSL
929   * options.
930   * There is one static instance of this struct in MQTTClient.c
931   */
932 
933 typedef struct
934 {
935 	const char* name;
936 	const char* value;
937 } MQTTClient_nameValue;
938 
939 /**
940   * This function returns version information about the library.
941   * no trace information will be returned.
942   * @return an array of strings describing the library.  The last entry is a NULL pointer.
943   */
944 DLLExport MQTTClient_nameValue* MQTTClient_getVersionInfo(void);
945 
946 /**
947   * This function attempts to connect a previously-created client (see
948   * MQTTClient_create()) to an MQTT server using the specified options. If you
949   * want to enable asynchronous message and status notifications, you must call
950   * MQTTClient_setCallbacks() prior to MQTTClient_connect().
951   * @param handle A valid client handle from a successful call to
952   * MQTTClient_create().
953   * @param options A pointer to a valid MQTTClient_connectOptions
954   * structure.
955   * @return ::MQTTCLIENT_SUCCESS if the client successfully connects to the
956   * server. An error code is returned if the client was unable to connect to
957   * the server.
958   * Error codes greater than 0 are returned by the MQTT protocol:<br><br>
959   * <b>1</b>: Connection refused: Unacceptable protocol version<br>
960   * <b>2</b>: Connection refused: Identifier rejected<br>
961   * <b>3</b>: Connection refused: Server unavailable<br>
962   * <b>4</b>: Connection refused: Bad user name or password<br>
963   * <b>5</b>: Connection refused: Not authorized<br>
964   * <b>6-255</b>: Reserved for future use<br>
965   */
966 DLLExport int MQTTClient_connect(MQTTClient handle, MQTTClient_connectOptions* options);
967 
968 
969 typedef struct MQTTResponse
970 {
971 	int version;
972 	enum MQTTReasonCodes reasonCode;
973 	int reasonCodeCount;	               /* used for subscribeMany5 and unsubscribeMany5 */
974 	enum MQTTReasonCodes* reasonCodes;  /* used for subscribeMany5 and unsubscribeMany5 */
975 	MQTTProperties* properties;         /* optional */
976 } MQTTResponse;
977 
978 #define MQTTResponse_initializer {1, MQTTREASONCODE_SUCCESS, 0, NULL, NULL}
979 
980 DLLExport void MQTTResponse_free(MQTTResponse response);
981 
982 DLLExport MQTTResponse MQTTClient_connect5(MQTTClient handle, MQTTClient_connectOptions* options,
983 		MQTTProperties* connectProperties, MQTTProperties* willProperties);
984 
985 /**
986   * This function attempts to disconnect the client from the MQTT
987   * server. In order to allow the client time to complete handling of messages
988   * that are in-flight when this function is called, a timeout period is
989   * specified. When the timeout period has expired, the client disconnects even
990   * if there are still outstanding message acknowledgements.
991   * The next time the client connects to the same server, any QoS 1 or 2
992   * messages which have not completed will be retried depending on the
993   * cleansession settings for both the previous and the new connection (see
994   * MQTTClient_connectOptions.cleansession and MQTTClient_connect()).
995   * @param handle A valid client handle from a successful call to
996   * MQTTClient_create().
997   * @param timeout The client delays disconnection for up to this time (in
998   * milliseconds) in order to allow in-flight message transfers to complete.
999   * @return ::MQTTCLIENT_SUCCESS if the client successfully disconnects from
1000   * the server. An error code is returned if the client was unable to disconnect
1001   * from the server
1002   */
1003 DLLExport int MQTTClient_disconnect(MQTTClient handle, int timeout);
1004 
1005 DLLExport int MQTTClient_disconnect5(MQTTClient handle, int timeout, enum MQTTReasonCodes reason, MQTTProperties* props);
1006 
1007 /**
1008   * This function allows the client application to test whether or not a
1009   * client is currently connected to the MQTT server.
1010   * @param handle A valid client handle from a successful call to
1011   * MQTTClient_create().
1012   * @return Boolean true if the client is connected, otherwise false.
1013   */
1014 DLLExport int MQTTClient_isConnected(MQTTClient handle);
1015 
1016 
1017 /* Subscribe is synchronous.  QoS list parameter is changed on return to granted QoSs.
1018    Returns return code, MQTTCLIENT_SUCCESS == success, non-zero some sort of error (TBD) */
1019 
1020 /**
1021   * This function attempts to subscribe a client to a single topic, which may
1022   * contain wildcards (see @ref wildcard). This call also specifies the
1023   * @ref qos requested for the subscription
1024   * (see also MQTTClient_subscribeMany()).
1025   * @param handle A valid client handle from a successful call to
1026   * MQTTClient_create().
1027   * @param topic The subscription topic, which may include wildcards.
1028   * @param qos The requested quality of service for the subscription.
1029   * @return ::MQTTCLIENT_SUCCESS if the subscription request is successful.
1030   * An error code is returned if there was a problem registering the
1031   * subscription.
1032   */
1033 DLLExport int MQTTClient_subscribe(MQTTClient handle, const char* topic, int qos);
1034 
1035 
1036 DLLExport MQTTResponse MQTTClient_subscribe5(MQTTClient handle, const char* topic, int qos,
1037 		MQTTSubscribe_options* opts, MQTTProperties* props);
1038 
1039 /**
1040   * This function attempts to subscribe a client to a list of topics, which may
1041   * contain wildcards (see @ref wildcard). This call also specifies the
1042   * @ref qos requested for each topic (see also MQTTClient_subscribe()).
1043   * @param handle A valid client handle from a successful call to
1044   * MQTTClient_create().
1045   * @param count The number of topics for which the client is requesting
1046   * subscriptions.
1047   * @param topic An array (of length <i>count</i>) of pointers to
1048   * topics, each of which may include wildcards.
1049   * @param qos An array (of length <i>count</i>) of @ref qos
1050   * values. qos[n] is the requested QoS for topic[n].
1051   * @return ::MQTTCLIENT_SUCCESS if the subscription request is successful.
1052   * An error code is returned if there was a problem registering the
1053   * subscriptions.
1054   */
1055 DLLExport int MQTTClient_subscribeMany(MQTTClient handle, int count, char* const* topic, int* qos);
1056 
1057 DLLExport MQTTResponse MQTTClient_subscribeMany5(MQTTClient handle, int count, char* const* topic,
1058 		int* qos, MQTTSubscribe_options* opts, MQTTProperties* props);
1059 
1060 /**
1061   * This function attempts to remove an existing subscription made by the
1062   * specified client.
1063   * @param handle A valid client handle from a successful call to
1064   * MQTTClient_create().
1065   * @param topic The topic for the subscription to be removed, which may
1066   * include wildcards (see @ref wildcard).
1067   * @return ::MQTTCLIENT_SUCCESS if the subscription is removed.
1068   * An error code is returned if there was a problem removing the
1069   * subscription.
1070   */
1071 DLLExport int MQTTClient_unsubscribe(MQTTClient handle, const char* topic);
1072 
1073 DLLExport MQTTResponse MQTTClient_unsubscribe5(MQTTClient handle, const char* topic, MQTTProperties* props);
1074 
1075 /**
1076   * This function attempts to remove existing subscriptions to a list of topics
1077   * made by the specified client.
1078   * @param handle A valid client handle from a successful call to
1079   * MQTTClient_create().
1080   * @param count The number subscriptions to be removed.
1081   * @param topic An array (of length <i>count</i>) of pointers to the topics of
1082   * the subscriptions to be removed, each of which may include wildcards.
1083   * @return ::MQTTCLIENT_SUCCESS if the subscriptions are removed.
1084   * An error code is returned if there was a problem removing the subscriptions.
1085   */
1086 DLLExport int MQTTClient_unsubscribeMany(MQTTClient handle, int count, char* const* topic);
1087 
1088 DLLExport MQTTResponse MQTTClient_unsubscribeMany5(MQTTClient handle, int count, char* const* topic, MQTTProperties* props);
1089 
1090 /**
1091   * This function attempts to publish a message to a given topic (see also
1092   * MQTTClient_publishMessage()). An ::MQTTClient_deliveryToken is issued when
1093   * this function returns successfully. If the client application needs to
1094   * test for succesful delivery of QoS1 and QoS2 messages, this can be done
1095   * either asynchronously or synchronously (see @ref async,
1096   * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()).
1097   * @param handle A valid client handle from a successful call to
1098   * MQTTClient_create().
1099   * @param topicName The topic associated with this message.
1100   * @param payloadlen The length of the payload in bytes.
1101   * @param payload A pointer to the byte array payload of the message.
1102   * @param qos The @ref qos of the message.
1103   * @param retained The retained flag for the message.
1104   * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated
1105   * with a token representing the message when the function returns
1106   * successfully. If your application does not use delivery tokens, set this
1107   * argument to NULL.
1108   * @return ::MQTTCLIENT_SUCCESS if the message is accepted for publication.
1109   * An error code is returned if there was a problem accepting the message.
1110   */
1111 DLLExport int MQTTClient_publish(MQTTClient handle, const char* topicName, int payloadlen, const void* payload, int qos, int retained,
1112 																 MQTTClient_deliveryToken* dt);
1113 
1114 DLLExport MQTTResponse MQTTClient_publish5(MQTTClient handle, const char* topicName, int payloadlen, const void* payload,
1115 		int qos, int retained, MQTTProperties* properties, MQTTClient_deliveryToken* dt);
1116 /**
1117   * This function attempts to publish a message to a given topic (see also
1118   * MQTTClient_publish()). An ::MQTTClient_deliveryToken is issued when
1119   * this function returns successfully. If the client application needs to
1120   * test for succesful delivery of QoS1 and QoS2 messages, this can be done
1121   * either asynchronously or synchronously (see @ref async,
1122   * ::MQTTClient_waitForCompletion and MQTTClient_deliveryComplete()).
1123   * @param handle A valid client handle from a successful call to
1124   * MQTTClient_create().
1125   * @param topicName The topic associated with this message.
1126   * @param msg A pointer to a valid MQTTClient_message structure containing
1127   * the payload and attributes of the message to be published.
1128   * @param dt A pointer to an ::MQTTClient_deliveryToken. This is populated
1129   * with a token representing the message when the function returns
1130   * successfully. If your application does not use delivery tokens, set this
1131   * argument to NULL.
1132   * @return ::MQTTCLIENT_SUCCESS if the message is accepted for publication.
1133   * An error code is returned if there was a problem accepting the message.
1134   */
1135 DLLExport int MQTTClient_publishMessage(MQTTClient handle, const char* topicName, MQTTClient_message* msg, MQTTClient_deliveryToken* dt);
1136 
1137 
1138 DLLExport MQTTResponse MQTTClient_publishMessage5(MQTTClient handle, const char* topicName, MQTTClient_message* msg,
1139 		MQTTClient_deliveryToken* dt);
1140 
1141 /**
1142   * This function is called by the client application to synchronize execution
1143   * of the main thread with completed publication of a message. When called,
1144   * MQTTClient_waitForCompletion() blocks execution until the message has been
1145   * successful delivered or the specified timeout has expired. See @ref async.
1146   * @param handle A valid client handle from a successful call to
1147   * MQTTClient_create().
1148   * @param dt The ::MQTTClient_deliveryToken that represents the message being
1149   * tested for successful delivery. Delivery tokens are issued by the
1150   * publishing functions MQTTClient_publish() and MQTTClient_publishMessage().
1151   * @param timeout The maximum time to wait in milliseconds.
1152   * @return ::MQTTCLIENT_SUCCESS if the message was successfully delivered.
1153   * An error code is returned if the timeout expires or there was a problem
1154   * checking the token.
1155   */
1156 DLLExport int MQTTClient_waitForCompletion(MQTTClient handle, MQTTClient_deliveryToken dt, unsigned long timeout);
1157 
1158 
1159 /**
1160   * This function sets a pointer to an array of delivery tokens for
1161   * messages that are currently in-flight (pending completion).
1162   *
1163   * <b>Important note:</b> The memory used to hold the array of tokens is
1164   * malloc()'d in this function. The client application is responsible for
1165   * freeing this memory when it is no longer required.
1166   * @param handle A valid client handle from a successful call to
1167   * MQTTClient_create().
1168   * @param tokens The address of a pointer to an ::MQTTClient_deliveryToken.
1169   * When the function returns successfully, the pointer is set to point to an
1170   * array of tokens representing messages pending completion. The last member of
1171   * the array is set to -1 to indicate there are no more tokens. If no tokens
1172   * are pending, the pointer is set to NULL.
1173   * @return ::MQTTCLIENT_SUCCESS if the function returns successfully.
1174   * An error code is returned if there was a problem obtaining the list of
1175   * pending tokens.
1176   */
1177 DLLExport int MQTTClient_getPendingDeliveryTokens(MQTTClient handle, MQTTClient_deliveryToken **tokens);
1178 
1179 /**
1180   * When implementing a single-threaded client, call this function periodically
1181   * to allow processing of message retries and to send MQTT keepalive pings.
1182   * If the application is calling MQTTClient_receive() regularly, then it is
1183   * not necessary to call this function.
1184   */
1185 DLLExport void MQTTClient_yield(void);
1186 
1187 /**
1188   * This function performs a synchronous receive of incoming messages. It should
1189   * be used only when the client application has not set callback methods to
1190   * support asynchronous receipt of messages (see @ref async and
1191   * MQTTClient_setCallbacks()). Using this function allows a single-threaded
1192   * client subscriber application to be written. When called, this function
1193   * blocks until the next message arrives or the specified timeout expires
1194   *(see also MQTTClient_yield()).
1195   *
1196   * <b>Important note:</b> The application must free() the memory allocated
1197   * to the topic and the message when processing is complete (see
1198   * MQTTClient_freeMessage()).
1199   * @param handle A valid client handle from a successful call to
1200   * MQTTClient_create().
1201   * @param topicName The address of a pointer to a topic. This function
1202   * allocates the memory for the topic and returns it to the application
1203   * by setting <i>topicName</i> to point to the topic.
1204   * @param topicLen The length of the topic. If the return code from this
1205   * function is ::MQTTCLIENT_TOPICNAME_TRUNCATED, the topic contains embedded
1206   * NULL characters and the full topic should be retrieved by using
1207   * <i>topicLen</i>.
1208   * @param message The address of a pointer to the received message. This
1209   * function allocates the memory for the message and returns it to the
1210   * application by setting <i>message</i> to point to the received message.
1211   * The pointer is set to NULL if the timeout expires.
1212   * @param timeout The length of time to wait for a message in milliseconds.
1213   * @return ::MQTTCLIENT_SUCCESS or ::MQTTCLIENT_TOPICNAME_TRUNCATED if a
1214   * message is received. ::MQTTCLIENT_SUCCESS can also indicate that the
1215   * timeout expired, in which case <i>message</i> is NULL. An error code is
1216   * returned if there was a problem trying to receive a message.
1217   */
1218 DLLExport int MQTTClient_receive(MQTTClient handle, char** topicName, int* topicLen, MQTTClient_message** message,
1219 		unsigned long timeout);
1220 
1221 /**
1222   * This function frees memory allocated to an MQTT message, including the
1223   * additional memory allocated to the message payload. The client application
1224   * calls this function when the message has been fully processed. <b>Important
1225   * note:</b> This function does not free the memory allocated to a message
1226   * topic string. It is the responsibility of the client application to free
1227   * this memory using the MQTTClient_free() library function.
1228   * @param msg The address of a pointer to the ::MQTTClient_message structure
1229   * to be freed.
1230   */
1231 DLLExport void MQTTClient_freeMessage(MQTTClient_message** msg);
1232 
1233 /**
1234   * This function frees memory allocated by the MQTT C client library, especially the
1235   * topic name. This is needed on Windows when the client libary and application
1236   * program have been compiled with different versions of the C compiler.  It is
1237   * thus good policy to always use this function when freeing any MQTT C client-
1238   * allocated memory.
1239   * @param ptr The pointer to the client library storage to be freed.
1240   */
1241 DLLExport void MQTTClient_free(void* ptr);
1242 
1243 /**
1244   * This function frees the memory allocated to an MQTT client (see
1245   * MQTTClient_create()). It should be called when the client is no longer
1246   * required.
1247   * @param handle A pointer to the handle referring to the ::MQTTClient
1248   * structure to be freed.
1249   */
1250 DLLExport void MQTTClient_destroy(MQTTClient* handle);
1251 
1252 
1253 enum MQTTCLIENT_TRACE_LEVELS
1254 {
1255 	MQTTCLIENT_TRACE_MAXIMUM = 1,
1256 	MQTTCLIENT_TRACE_MEDIUM,
1257 	MQTTCLIENT_TRACE_MINIMUM,
1258 	MQTTCLIENT_TRACE_PROTOCOL,
1259 	MQTTCLIENT_TRACE_ERROR,
1260 	MQTTCLIENT_TRACE_SEVERE,
1261 	MQTTCLIENT_TRACE_FATAL,
1262 };
1263 
1264 
1265 /**
1266   * This function sets the level of trace information which will be
1267   * returned in the trace callback.
1268   * @param level the trace level required
1269   */
1270 DLLExport void MQTTClient_setTraceLevel(enum MQTTCLIENT_TRACE_LEVELS level);
1271 
1272 
1273 /**
1274   * This is a callback function prototype which must be implemented if you want
1275   * to receive trace information.
1276   * @param level the trace level of the message returned
1277   * @param message the trace message.  This is a pointer to a static buffer which
1278   * will be overwritten on each call.  You must copy the data if you want to keep
1279   * it for later.
1280   */
1281 typedef void MQTTClient_traceCallback(enum MQTTCLIENT_TRACE_LEVELS level, char* message);
1282 
1283 /**
1284   * This function sets the trace callback if needed.  If set to NULL,
1285   * no trace information will be returned.  The default trace level is
1286   * MQTTASYNC_TRACE_MINIMUM.
1287   * @param callback a pointer to the function which will handle the trace information
1288   */
1289 DLLExport void MQTTClient_setTraceCallback(MQTTClient_traceCallback* callback);
1290 
1291 /**
1292  * Returns a pointer to the string representation of the error or NULL.
1293  *
1294  * Do not free after use. Returns NULL if the error code is unknown.
1295  */
1296 DLLExport const char* MQTTClient_strerror(int code);
1297 
1298 #ifdef __cplusplus
1299      }
1300 #endif
1301 
1302 #endif
1303 
1304 /**
1305   * @cond MQTTClient_main
1306   * @page async Asynchronous vs synchronous client applications
1307   * The client library supports two modes of operation. These are referred to
1308   * as <b>synchronous</b> and <b>asynchronous</b> modes. If your application
1309   * calls MQTTClient_setCallbacks(), this puts the client into asynchronous
1310   * mode, otherwise it operates in synchronous mode.
1311   *
1312   * In synchronous mode, the client application runs on a single thread.
1313   * Messages are published using the MQTTClient_publish() and
1314   * MQTTClient_publishMessage() functions. To determine that a QoS1 or QoS2
1315   * (see @ref qos) message has been successfully delivered, the application
1316   * must call the MQTTClient_waitForCompletion() function. An example showing
1317   * synchronous publication is shown in @ref pubsync. Receiving messages in
1318   * synchronous mode uses the MQTTClient_receive() function. Client applications
1319   * must call either MQTTClient_receive() or MQTTClient_yield() relatively
1320   * frequently in order to allow processing of acknowledgements and the MQTT
1321   * "pings" that keep the network connection to the server alive.
1322   *
1323   * In asynchronous mode, the client application runs on several threads. The
1324   * main program calls functions in the client library to publish and subscribe,
1325   * just as for the synchronous mode. Processing of handshaking and maintaining
1326   * the network connection is performed in the background, however.
1327   * Notifications of status and message reception are provided to the client
1328   * application using callbacks registered with the library by the call to
1329   * MQTTClient_setCallbacks() (see MQTTClient_messageArrived(),
1330   * MQTTClient_connectionLost() and MQTTClient_deliveryComplete()).
1331   * This API is not thread safe however - it is not possible to call it from multiple
1332   * threads without synchronization.  You can use the MQTTAsync API for that.
1333   *
1334   * @page wildcard Subscription wildcards
1335   * Every MQTT message includes a topic that classifies it. MQTT servers use
1336   * topics to determine which subscribers should receive messages published to
1337   * the server.
1338   *
1339   * Consider the server receiving messages from several environmental sensors.
1340   * Each sensor publishes its measurement data as a message with an associated
1341   * topic. Subscribing applications need to know which sensor originally
1342   * published each received message. A unique topic is thus used to identify
1343   * each sensor and measurement type. Topics such as SENSOR1TEMP,
1344   * SENSOR1HUMIDITY, SENSOR2TEMP and so on achieve this but are not very
1345   * flexible. If additional sensors are added to the system at a later date,
1346   * subscribing applications must be modified to receive them.
1347   *
1348   * To provide more flexibility, MQTT supports a hierarchical topic namespace.
1349   * This allows application designers to organize topics to simplify their
1350   * management. Levels in the hierarchy are delimited by the '/' character,
1351   * such as SENSOR/1/HUMIDITY. Publishers and subscribers use these
1352   * hierarchical topics as already described.
1353   *
1354   * For subscriptions, two wildcard characters are supported:
1355   * <ul>
1356   * <li>A '#' character represents a complete sub-tree of the hierarchy and
1357   * thus must be the last character in a subscription topic string, such as
1358   * SENSOR/#. This will match any topic starting with SENSOR/, such as
1359   * SENSOR/1/TEMP and SENSOR/2/HUMIDITY.</li>
1360   * <li> A '+' character represents a single level of the hierarchy and is
1361   * used between delimiters. For example, SENSOR/+/TEMP will match
1362   * SENSOR/1/TEMP and SENSOR/2/TEMP.</li>
1363   * </ul>
1364   * Publishers are not allowed to use the wildcard characters in their topic
1365   * names.
1366   *
1367   * Deciding on your topic hierarchy is an important step in your system design.
1368   *
1369   * @page qos Quality of service
1370   * The MQTT protocol provides three qualities of service for delivering
1371   * messages between clients and servers: "at most once", "at least once" and
1372   * "exactly once".
1373   *
1374   * Quality of service (QoS) is an attribute of an individual message being
1375   * published. An application sets the QoS for a specific message by setting the
1376   * MQTTClient_message.qos field to the required value.
1377   *
1378   * A subscribing client can set the maximum quality of service a server uses
1379   * to send messages that match the client subscriptions. The
1380   * MQTTClient_subscribe() and MQTTClient_subscribeMany() functions set this
1381   * maximum. The QoS of a message forwarded to a subscriber thus might be
1382   * different to the QoS given to the message by the original publisher.
1383   * The lower of the two values is used to forward a message.
1384   *
1385   * The three levels are:
1386   *
1387   * <b>QoS0, At most once:</b> The message is delivered at most once, or it
1388   * may not be delivered at all. Its delivery across the network is not
1389   * acknowledged. The message is not stored. The message could be lost if the
1390   * client is disconnected, or if the server fails. QoS0 is the fastest mode of
1391   * transfer. It is sometimes called "fire and forget".
1392   *
1393   * The MQTT protocol does not require servers to forward publications at QoS0
1394   * to a client. If the client is disconnected at the time the server receives
1395   * the publication, the publication might be discarded, depending on the
1396   * server implementation.
1397   *
1398   * <b>QoS1, At least once:</b> The message is always delivered at least once.
1399   * It might be delivered multiple times if there is a failure before an
1400   * acknowledgment is received by the sender. The message must be stored
1401   * locally at the sender, until the sender receives confirmation that the
1402   * message has been published by the receiver. The message is stored in case
1403   * the message must be sent again.
1404   *
1405   * <b>QoS2, Exactly once:</b> The message is always delivered exactly once.
1406   * The message must be stored locally at the sender, until the sender receives
1407   * confirmation that the message has been published by the receiver. The
1408   * message is stored in case the message must be sent again. QoS2 is the
1409   * safest, but slowest mode of transfer. A more sophisticated handshaking
1410   * and acknowledgement sequence is used than for QoS1 to ensure no duplication
1411   * of messages occurs.
1412   * @page pubsync Synchronous publication example
1413 @code
1414 #include <stdio.h>
1415 #include <stdlib.h>
1416 #include <string.h>
1417 #include "MQTTClient.h"
1418 
1419 #define ADDRESS     "tcp://localhost:1883"
1420 #define CLIENTID    "ExampleClientPub"
1421 #define TOPIC       "MQTT Examples"
1422 #define PAYLOAD     "Hello World!"
1423 #define QOS         1
1424 #define TIMEOUT     10000L
1425 
1426 int main(int argc, char* argv[])
1427 {
1428     MQTTClient client;
1429     MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
1430     MQTTClient_message pubmsg = MQTTClient_message_initializer;
1431     MQTTClient_deliveryToken token;
1432     int rc;
1433 
1434     MQTTClient_create(&client, ADDRESS, CLIENTID,
1435         MQTTCLIENT_PERSISTENCE_NONE, NULL);
1436     conn_opts.keepAliveInterval = 20;
1437     conn_opts.cleansession = 1;
1438 
1439     if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
1440     {
1441         printf("Failed to connect, return code %d\n", rc);
1442         exit(EXIT_FAILURE);
1443     }
1444     pubmsg.payload = PAYLOAD;
1445     pubmsg.payloadlen = strlen(PAYLOAD);
1446     pubmsg.qos = QOS;
1447     pubmsg.retained = 0;
1448     MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token);
1449     printf("Waiting for up to %d seconds for publication of %s\n"
1450             "on topic %s for client with ClientID: %s\n",
1451             (int)(TIMEOUT/1000), PAYLOAD, TOPIC, CLIENTID);
1452     rc = MQTTClient_waitForCompletion(client, token, TIMEOUT);
1453     printf("Message with delivery token %d delivered\n", token);
1454     MQTTClient_disconnect(client, 10000);
1455     MQTTClient_destroy(&client);
1456     return rc;
1457 }
1458 
1459   * @endcode
1460   *
1461   * @page pubasync Asynchronous publication example
1462 @code{.c}
1463 #include <stdio.h>
1464 #include <stdlib.h>
1465 #include <string.h>
1466 #include "MQTTClient.h"
1467 
1468 #define ADDRESS     "tcp://localhost:1883"
1469 #define CLIENTID    "ExampleClientPub"
1470 #define TOPIC       "MQTT Examples"
1471 #define PAYLOAD     "Hello World!"
1472 #define QOS         1
1473 #define TIMEOUT     10000L
1474 
1475 volatile MQTTClient_deliveryToken deliveredtoken;
1476 
1477 void delivered(void *context, MQTTClient_deliveryToken dt)
1478 {
1479     printf("Message with token value %d delivery confirmed\n", dt);
1480     deliveredtoken = dt;
1481 }
1482 
1483 int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
1484 {
1485     int i;
1486     char* payloadptr;
1487 
1488     printf("Message arrived\n");
1489     printf("     topic: %s\n", topicName);
1490     printf("   message: ");
1491 
1492     payloadptr = message->payload;
1493     for(i=0; i<message->payloadlen; i++)
1494     {
1495         putchar(*payloadptr++);
1496     }
1497     putchar('\n');
1498     MQTTClient_freeMessage(&message);
1499     MQTTClient_free(topicName);
1500     return 1;
1501 }
1502 
1503 void connlost(void *context, char *cause)
1504 {
1505     printf("\nConnection lost\n");
1506     printf("     cause: %s\n", cause);
1507 }
1508 
1509 int main(int argc, char* argv[])
1510 {
1511     MQTTClient client;
1512     MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
1513     MQTTClient_message pubmsg = MQTTClient_message_initializer;
1514     MQTTClient_deliveryToken token;
1515     int rc;
1516 
1517     MQTTClient_create(&client, ADDRESS, CLIENTID,
1518         MQTTCLIENT_PERSISTENCE_NONE, NULL);
1519     conn_opts.keepAliveInterval = 20;
1520     conn_opts.cleansession = 1;
1521 
1522     MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered);
1523 
1524     if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
1525     {
1526         printf("Failed to connect, return code %d\n", rc);
1527         exit(EXIT_FAILURE);
1528     }
1529     pubmsg.payload = PAYLOAD;
1530     pubmsg.payloadlen = strlen(PAYLOAD);
1531     pubmsg.qos = QOS;
1532     pubmsg.retained = 0;
1533     deliveredtoken = 0;
1534     MQTTClient_publishMessage(client, TOPIC, &pubmsg, &token);
1535     printf("Waiting for publication of %s\n"
1536             "on topic %s for client with ClientID: %s\n",
1537             PAYLOAD, TOPIC, CLIENTID);
1538     while(deliveredtoken != token);
1539     MQTTClient_disconnect(client, 10000);
1540     MQTTClient_destroy(&client);
1541     return rc;
1542 }
1543 
1544   * @endcode
1545   * @page subasync Asynchronous subscription example
1546 @code
1547 #include <stdio.h>
1548 #include <stdlib.h>
1549 #include <string.h>
1550 #include "MQTTClient.h"
1551 
1552 #define ADDRESS     "tcp://localhost:1883"
1553 #define CLIENTID    "ExampleClientSub"
1554 #define TOPIC       "MQTT Examples"
1555 #define PAYLOAD     "Hello World!"
1556 #define QOS         1
1557 #define TIMEOUT     10000L
1558 
1559 volatile MQTTClient_deliveryToken deliveredtoken;
1560 
1561 void delivered(void *context, MQTTClient_deliveryToken dt)
1562 {
1563     printf("Message with token value %d delivery confirmed\n", dt);
1564     deliveredtoken = dt;
1565 }
1566 
1567 int msgarrvd(void *context, char *topicName, int topicLen, MQTTClient_message *message)
1568 {
1569     int i;
1570     char* payloadptr;
1571 
1572     printf("Message arrived\n");
1573     printf("     topic: %s\n", topicName);
1574     printf("   message: ");
1575 
1576     payloadptr = message->payload;
1577     for(i=0; i<message->payloadlen; i++)
1578     {
1579         putchar(*payloadptr++);
1580     }
1581     putchar('\n');
1582     MQTTClient_freeMessage(&message);
1583     MQTTClient_free(topicName);
1584     return 1;
1585 }
1586 
1587 void connlost(void *context, char *cause)
1588 {
1589     printf("\nConnection lost\n");
1590     printf("     cause: %s\n", cause);
1591 }
1592 
1593 int main(int argc, char* argv[])
1594 {
1595     MQTTClient client;
1596     MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
1597     int rc;
1598     int ch;
1599 
1600     MQTTClient_create(&client, ADDRESS, CLIENTID,
1601         MQTTCLIENT_PERSISTENCE_NONE, NULL);
1602     conn_opts.keepAliveInterval = 20;
1603     conn_opts.cleansession = 1;
1604 
1605     MQTTClient_setCallbacks(client, NULL, connlost, msgarrvd, delivered);
1606 
1607     if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
1608     {
1609         printf("Failed to connect, return code %d\n", rc);
1610         exit(EXIT_FAILURE);
1611     }
1612     printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n"
1613            "Press Q<Enter> to quit\n\n", TOPIC, CLIENTID, QOS);
1614     MQTTClient_subscribe(client, TOPIC, QOS);
1615 
1616     do
1617     {
1618         ch = getchar();
1619     } while(ch!='Q' && ch != 'q');
1620 
1621     MQTTClient_disconnect(client, 10000);
1622     MQTTClient_destroy(&client);
1623     return rc;
1624 }
1625 
1626   * @endcode
1627   * @page tracing Tracing
1628   *
1629   * Runtime tracing is controlled by environment variables.
1630   *
1631   * Tracing is switched on by setting MQTT_C_CLIENT_TRACE.  A value of ON, or stdout, prints to
1632   * stdout, any other value is interpreted as a file name to use.
1633   *
1634   * The amount of trace detail is controlled with the MQTT_C_CLIENT_TRACE_LEVEL environment
1635   * variable - valid values are ERROR, PROTOCOL, MINIMUM, MEDIUM and MAXIMUM
1636   * (from least to most verbose).
1637   *
1638   * The variable MQTT_C_CLIENT_TRACE_MAX_LINES limits the number of lines of trace that are output
1639   * to a file.  Two files are used at most, when they are full, the last one is overwritten with the
1640   * new trace entries.  The default size is 1000 lines.
1641   *
1642   * ### MQTT Packet Tracing
1643   *
1644   * A feature that can be very useful is printing the MQTT packets that are sent and received.  To
1645   * achieve this, use the following environment variable settings:
1646   * @code
1647     MQTT_C_CLIENT_TRACE=ON
1648     MQTT_C_CLIENT_TRACE_LEVEL=PROTOCOL
1649   * @endcode
1650   * The output you should see looks like this:
1651   * @code
1652     20130528 155936.813 3 stdout-subscriber -> CONNECT cleansession: 1 (0)
1653     20130528 155936.813 3 stdout-subscriber <- CONNACK rc: 0
1654     20130528 155936.813 3 stdout-subscriber -> SUBSCRIBE msgid: 1 (0)
1655     20130528 155936.813 3 stdout-subscriber <- SUBACK msgid: 1
1656     20130528 155941.818 3 stdout-subscriber -> DISCONNECT (0)
1657   * @endcode
1658   * where the fields are:
1659   * 1. date
1660   * 2. time
1661   * 3. socket number
1662   * 4. client id
1663   * 5. direction (-> from client to server, <- from server to client)
1664   * 6. packet details
1665   *
1666   * ### Default Level Tracing
1667   *
1668   * This is an extract of a default level trace of a call to connect:
1669   * @code
1670     19700101 010000.000 (1152206656) (0)> MQTTClient_connect:893
1671     19700101 010000.000 (1152206656)  (1)> MQTTClient_connectURI:716
1672     20130528 160447.479 Connecting to serverURI localhost:1883
1673     20130528 160447.479 (1152206656)   (2)> MQTTProtocol_connect:98
1674     20130528 160447.479 (1152206656)    (3)> MQTTProtocol_addressPort:48
1675     20130528 160447.479 (1152206656)    (3)< MQTTProtocol_addressPort:73
1676     20130528 160447.479 (1152206656)    (3)> Socket_new:599
1677     20130528 160447.479 New socket 4 for localhost, port 1883
1678     20130528 160447.479 (1152206656)     (4)> Socket_addSocket:163
1679     20130528 160447.479 (1152206656)      (5)> Socket_setnonblocking:73
1680     20130528 160447.479 (1152206656)      (5)< Socket_setnonblocking:78 (0)
1681     20130528 160447.479 (1152206656)     (4)< Socket_addSocket:176 (0)
1682     20130528 160447.479 (1152206656)     (4)> Socket_error:95
1683     20130528 160447.479 (1152206656)     (4)< Socket_error:104 (115)
1684     20130528 160447.479 Connect pending
1685     20130528 160447.479 (1152206656)    (3)< Socket_new:683 (115)
1686     20130528 160447.479 (1152206656)   (2)< MQTTProtocol_connect:131 (115)
1687   * @endcode
1688   * where the fields are:
1689   * 1. date
1690   * 2. time
1691   * 3. thread id
1692   * 4. function nesting level
1693   * 5. function entry (>) or exit (<)
1694   * 6. function name : line of source code file
1695   * 7. return value (if there is one)
1696   *
1697   * ### Memory Allocation Tracing
1698   *
1699   * Setting the trace level to maximum causes memory allocations and frees to be traced along with
1700   * the default trace entries, with messages like the following:
1701   * @code
1702     20130528 161819.657 Allocating 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 177 ptr 0x179f930
1703 
1704     20130528 161819.657 Freeing 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 201, heap use now 896 bytes
1705   * @endcode
1706   * When the last MQTT client object is destroyed, if the trace is being recorded
1707   * and all memory allocated by the client library has not been freed, an error message will be
1708   * written to the trace.  This can help with fixing memory leaks.  The message will look like this:
1709   * @code
1710     20130528 163909.208 Some memory not freed at shutdown, possible memory leak
1711     20130528 163909.208 Heap scan start, total 880 bytes
1712     20130528 163909.208 Heap element size 32, line 354, file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c, ptr 0x260cb00
1713     20130528 163909.208   Content
1714     20130528 163909.209 Heap scan end
1715   * @endcode
1716   * @endcond
1717   */
1718