• 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
15  *    Ian Craggs, Allan Stockdill-Mander - SSL connections
16  *    Ian Craggs - multiple server connection support
17  *    Ian Craggs - MQTT 3.1.1 support
18  *    Ian Craggs - fix for bug 444103 - success/failure callbacks not invoked
19  *    Ian Craggs - automatic reconnect and offline buffering (send while disconnected)
20  *    Ian Craggs - binary will message
21  *    Ian Craggs - binary password
22  *    Ian Craggs - remove const on eyecatchers #168
23  *    Ian Craggs - MQTT 5.0
24  *******************************************************************************/
25 
26 /********************************************************************/
27 
28 /**
29  * @cond MQTTAsync_main
30  * @mainpage Asynchronous MQTT client library for C
31  *
32  * © Copyright IBM Corp. 2009, 2018
33  *
34  * @brief An Asynchronous MQTT client library for C.
35  *
36  * An MQTT client application connects to MQTT-capable servers.
37  * A typical client is responsible for collecting information from a telemetry
38  * device and publishing the information to the server. It can also subscribe
39  * to topics, receive messages, and use this information to control the
40  * telemetry device.
41  *
42  * MQTT clients implement the published MQTT v3 protocol. You can write your own
43  * API to the MQTT protocol using the programming language and platform of your
44  * choice. This can be time-consuming and error-prone.
45  *
46  * To simplify writing MQTT client applications, this library encapsulates
47  * the MQTT v3 protocol for you. Using this library enables a fully functional
48  * MQTT client application to be written in a few lines of code.
49  * The information presented here documents the API provided
50  * by the Asynchronous MQTT Client library for C.
51  *
52  * <b>Using the client</b><br>
53  * Applications that use the client library typically use a similar structure:
54  * <ul>
55  * <li>Create a client object</li>
56  * <li>Set the options to connect to an MQTT server</li>
57  * <li>Set up callback functions</li>
58  * <li>Connect the client to an MQTT server</li>
59  * <li>Subscribe to any topics the client needs to receive</li>
60  * <li>Repeat until finished:</li>
61  *     <ul>
62  *     <li>Publish any messages the client needs to</li>
63  *     <li>Handle any incoming messages</li>
64  *     </ul>
65  * <li>Disconnect the client</li>
66  * <li>Free any memory being used by the client</li>
67  * </ul>
68  * Some simple examples are shown here:
69  * <ul>
70  * <li>@ref publish</li>
71  * <li>@ref subscribe</li>
72  * </ul>
73  * Additional information about important concepts is provided here:
74  * <ul>
75  * <li>@ref async</li>
76  * <li>@ref wildcard</li>
77  * <li>@ref qos</li>
78  * <li>@ref tracing</li>
79  * <li>@ref auto_reconnect</li>
80  * <li>@ref offline_publish</li>
81  * </ul>
82  * @endcond
83  */
84 
85 /*
86 /// @cond EXCLUDE
87 */
88 #if !defined(MQTTASYNC_H)
89 #define MQTTASYNC_H
90 
91 #if defined(__cplusplus)
92  extern "C" {
93 #endif
94 
95 #if defined(WIN32) || defined(WIN64)
96   #define DLLImport __declspec(dllimport)
97   #define DLLExport __declspec(dllexport)
98 #else
99   #define DLLImport extern
100   #define DLLExport  __attribute__ ((visibility ("default")))
101 #endif
102 
103 #include <stdio.h>
104 /*
105 /// @endcond
106 */
107 
108 #include "MQTTProperties.h"
109 #include "MQTTReasonCodes.h"
110 #include "MQTTSubscribeOpts.h"
111 #if !defined(NO_PERSISTENCE)
112 #include "MQTTClientPersistence.h"
113 #endif
114 
115 /**
116  * Return code: No error. Indicates successful completion of an MQTT client
117  * operation.
118  */
119 #define MQTTASYNC_SUCCESS 0
120 /**
121  * Return code: A generic error code indicating the failure of an MQTT client
122  * operation.
123  */
124 #define MQTTASYNC_FAILURE -1
125 
126 /* error code -2 is MQTTAsync_PERSISTENCE_ERROR */
127 
128 #define MQTTASYNC_PERSISTENCE_ERROR -2
129 
130 /**
131  * Return code: The client is disconnected.
132  */
133 #define MQTTASYNC_DISCONNECTED -3
134 /**
135  * Return code: The maximum number of messages allowed to be simultaneously
136  * in-flight has been reached.
137  */
138 #define MQTTASYNC_MAX_MESSAGES_INFLIGHT -4
139 /**
140  * Return code: An invalid UTF-8 string has been detected.
141  */
142 #define MQTTASYNC_BAD_UTF8_STRING -5
143 /**
144  * Return code: A NULL parameter has been supplied when this is invalid.
145  */
146 #define MQTTASYNC_NULL_PARAMETER -6
147 /**
148  * Return code: The topic has been truncated (the topic string includes
149  * embedded NULL characters). String functions will not access the full topic.
150  * Use the topic length value to access the full topic.
151  */
152 #define MQTTASYNC_TOPICNAME_TRUNCATED -7
153 /**
154  * Return code: A structure parameter does not have the correct eyecatcher
155  * and version number.
156  */
157 #define MQTTASYNC_BAD_STRUCTURE -8
158 /**
159  * Return code: A qos parameter is not 0, 1 or 2
160  */
161 #define MQTTASYNC_BAD_QOS -9
162 /**
163  * Return code: All 65535 MQTT msgids are being used
164  */
165 #define MQTTASYNC_NO_MORE_MSGIDS -10
166 /**
167  * Return code: the request is being discarded when not complete
168  */
169 #define MQTTASYNC_OPERATION_INCOMPLETE -11
170 /**
171  * Return code: no more messages can be buffered
172  */
173 #define MQTTASYNC_MAX_BUFFERED_MESSAGES -12
174 /**
175  * Return code: Attempting SSL connection using non-SSL version of library
176  */
177 #define MQTTASYNC_SSL_NOT_SUPPORTED -13
178  /**
179   * Return code: protocol prefix in serverURI should be tcp://, ssl://, ws:// or wss://
180   * The TLS enabled prefixes (ssl, wss) are only valid if the TLS version of the library
181   * is linked with.
182   */
183 #define MQTTASYNC_BAD_PROTOCOL -14
184  /**
185   * Return code: don't use options for another version of MQTT
186   */
187  #define MQTTASYNC_BAD_MQTT_OPTION -15
188  /**
189   * Return code: call not applicable to the client's version of MQTT
190   */
191  #define MQTTASYNC_WRONG_MQTT_VERSION -16
192 
193 
194 /**
195  * Default MQTT version to connect with.  Use 3.1.1 then fall back to 3.1
196  */
197 #define MQTTVERSION_DEFAULT 0
198 /**
199  * MQTT version to connect with: 3.1
200  */
201 #define MQTTVERSION_3_1 3
202 /**
203  * MQTT version to connect with: 3.1.1
204  */
205 #define MQTTVERSION_3_1_1 4
206 /**
207  * MQTT version to connect with: 5
208  */
209 #define MQTTVERSION_5 5
210 /**
211  * Bad return code from subscribe, as defined in the 3.1.1 specification
212  */
213 #define MQTT_BAD_SUBSCRIBE 0x80
214 
215 
216 /**
217  *  Initialization options
218  */
219 typedef struct
220 {
221 	/** The eyecatcher for this structure.  Must be MQTG. */
222 	char struct_id[4];
223 	/** The version number of this structure.  Must be 0 */
224 	int struct_version;
225 	/** 1 = we do openssl init, 0 = leave it to the application */
226 	int do_openssl_init;
227 } MQTTAsync_init_options;
228 
229 #define MQTTAsync_init_options_initializer { {'M', 'Q', 'T', 'G'}, 0, 0 }
230 
231 /**
232  * Global init of mqtt library. Call once on program start to set global behaviour.
233  * handle_openssl_init - if mqtt library should handle openssl init (1) or rely on the caller to init it before using mqtt (0)
234  */
235 DLLExport void MQTTAsync_global_init(MQTTAsync_init_options* inits);
236 
237 /**
238  * A handle representing an MQTT client. A valid client handle is available
239  * following a successful call to MQTTAsync_create().
240  */
241 typedef void* MQTTAsync;
242 /**
243  * A value representing an MQTT message. A token is returned to the
244  * client application when a message is published. The token can then be used to
245  * check that the message was successfully delivered to its destination (see
246  * MQTTAsync_publish(),
247  * MQTTAsync_publishMessage(),
248  * MQTTAsync_deliveryComplete(), and
249  * MQTTAsync_getPendingTokens()).
250  */
251 typedef int MQTTAsync_token;
252 
253 /**
254  * A structure representing the payload and attributes of an MQTT message. The
255  * message topic is not part of this structure (see MQTTAsync_publishMessage(),
256  * MQTTAsync_publish(), MQTTAsync_receive(), MQTTAsync_freeMessage()
257  * and MQTTAsync_messageArrived()).
258  */
259 typedef struct
260 {
261 	/** The eyecatcher for this structure.  must be MQTM. */
262 	char struct_id[4];
263 	/** The version number of this structure.  Must be 0 or 1.
264 	 *  0 indicates no message properties */
265 	int struct_version;
266 	/** The length of the MQTT message payload in bytes. */
267 	int payloadlen;
268 	/** A pointer to the payload of the MQTT message. */
269 	void* payload;
270 	/**
271      * The quality of service (QoS) assigned to the message.
272      * There are three levels of QoS:
273      * <DL>
274      * <DT><B>QoS0</B></DT>
275      * <DD>Fire and forget - the message may not be delivered</DD>
276      * <DT><B>QoS1</B></DT>
277      * <DD>At least once - the message will be delivered, but may be
278      * delivered more than once in some circumstances.</DD>
279      * <DT><B>QoS2</B></DT>
280      * <DD>Once and one only - the message will be delivered exactly once.</DD>
281      * </DL>
282      */
283 	int qos;
284 	/**
285      * The retained flag serves two purposes depending on whether the message
286      * it is associated with is being published or received.
287      *
288      * <b>retained = true</b><br>
289      * For messages being published, a true setting indicates that the MQTT
290      * server should retain a copy of the message. The message will then be
291      * transmitted to new subscribers to a topic that matches the message topic.
292      * For subscribers registering a new subscription, the flag being true
293      * indicates that the received message is not a new one, but one that has
294      * been retained by the MQTT server.
295      *
296      * <b>retained = false</b> <br>
297      * For publishers, this indicates that this message should not be retained
298      * by the MQTT server. For subscribers, a false setting indicates this is
299      * a normal message, received as a result of it being published to the
300      * server.
301      */
302 	int retained;
303 	/**
304       * The dup flag indicates whether or not this message is a duplicate.
305       * It is only meaningful when receiving QoS1 messages. When true, the
306       * client application should take appropriate action to deal with the
307       * duplicate message.
308       */
309 	int dup;
310 	/** The message identifier is normally reserved for internal use by the
311       * MQTT client and server.
312       */
313 	int msgid;
314 	/**
315 	 * The MQTT V5 properties associated with the message.
316 	 */
317 	MQTTProperties properties;
318 } MQTTAsync_message;
319 
320 #define MQTTAsync_message_initializer { {'M', 'Q', 'T', 'M'}, 1, 0, NULL, 0, 0, 0, 0, MQTTProperties_initializer }
321 
322 /**
323  * This is a callback function. The client application
324  * must provide an implementation of this function to enable asynchronous
325  * receipt of messages. The function is registered with the client library by
326  * passing it as an argument to MQTTAsync_setCallbacks(). It is
327  * called by the client library when a new message that matches a client
328  * subscription has been received from the server. This function is executed on
329  * a separate thread to the one on which the client application is running.
330  * @param context A pointer to the <i>context</i> value originally passed to
331  * MQTTAsync_setCallbacks(), which contains any application-specific context.
332  * @param topicName The topic associated with the received message.
333  * @param topicLen The length of the topic if there are one
334  * more NULL characters embedded in <i>topicName</i>, otherwise <i>topicLen</i>
335  * is 0. If <i>topicLen</i> is 0, the value returned by <i>strlen(topicName)</i>
336  * can be trusted. If <i>topicLen</i> is greater than 0, the full topic name
337  * can be retrieved by accessing <i>topicName</i> as a byte array of length
338  * <i>topicLen</i>.
339  * @param message The MQTTAsync_message structure for the received message.
340  * This structure contains the message payload and attributes.
341  * @return This function must return a boolean value indicating whether or not
342  * the message has been safely received by the client application. Returning
343  * true indicates that the message has been successfully handled.
344  * Returning false indicates that there was a problem. In this
345  * case, the client library will reinvoke MQTTAsync_messageArrived() to
346  * attempt to deliver the message to the application again.
347  */
348 typedef int MQTTAsync_messageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* message);
349 
350 /**
351  * This is a callback function. The client application
352  * must provide an implementation of this function to enable asynchronous
353  * notification of delivery of messages to the server. The function is
354  * registered with the client library by passing it as an argument to MQTTAsync_setCallbacks().
355  * It is called by the client library after the client application has
356  * published a message to the server. It indicates that the necessary
357  * handshaking and acknowledgements for the requested quality of service (see
358  * MQTTAsync_message.qos) have been completed. This function is executed on a
359  * separate thread to the one on which the client application is running.
360  * @param context A pointer to the <i>context</i> value originally passed to
361  * MQTTAsync_setCallbacks(), which contains any application-specific context.
362  * @param token The ::MQTTAsync_token associated with
363  * the published message. Applications can check that all messages have been
364  * correctly published by matching the tokens returned from calls to
365  * MQTTAsync_send() and MQTTAsync_sendMessage() with the tokens passed
366  * to this callback.
367  */
368 typedef void MQTTAsync_deliveryComplete(void* context, MQTTAsync_token token);
369 
370 /**
371  * This is a callback function. The client application
372  * must provide an implementation of this function to enable asynchronous
373  * notification of the loss of connection to the server. The function is
374  * registered with the client library by passing it as an argument to
375  * MQTTAsync_setCallbacks(). It is called by the client library if the client
376  * loses its connection to the server. The client application must take
377  * appropriate action, such as trying to reconnect or reporting the problem.
378  * This function is executed on a separate thread to the one on which the
379  * client application is running.
380  * @param context A pointer to the <i>context</i> value originally passed to
381  * MQTTAsync_setCallbacks(), which contains any application-specific context.
382  * @param cause The reason for the disconnection.
383  * Currently, <i>cause</i> is always set to NULL.
384  */
385 typedef void MQTTAsync_connectionLost(void* context, char* cause);
386 
387 
388 /**
389  * This is a callback function, which will be called when the client
390  * library successfully connects.  This is superfluous when the connection
391  * is made in response to a MQTTAsync_connect call, because the onSuccess
392  * callback can be used.  It is intended for use when automatic reconnect
393  * is enabled, so that when a reconnection attempt succeeds in the background,
394  * the application is notified and can take any required actions.
395  * @param context A pointer to the <i>context</i> value originally passed to
396  * MQTTAsync_setCallbacks(), which contains any application-specific context.
397  * @param cause The reason for the disconnection.
398  * Currently, <i>cause</i> is always set to NULL.
399  */
400 typedef void MQTTAsync_connected(void* context, char* cause);
401 
402 /**
403  * This is a callback function, which will be called when the client
404  * library receives a disconnect packet.
405  * @param context A pointer to the <i>context</i> value originally passed to
406  * MQTTAsync_setCallbacks(), which contains any application-specific context.
407  * @param properties the properties in the disconnect packet.
408  * @param properties the reason code from the disconnect packet
409  * Currently, <i>cause</i> is always set to NULL.
410  */
411 typedef void MQTTAsync_disconnected(void* context, MQTTProperties* properties,
412 		enum MQTTReasonCodes reasonCode);
413 
414 /**
415  * Sets the MQTTAsync_disconnected() callback function for a client.
416  * @param handle A valid client handle from a successful call to
417  * MQTTAsync_create().
418  * @param context A pointer to any application-specific context. The
419  * the <i>context</i> pointer is passed to each of the callback functions to
420  * provide access to the context information in the callback.
421  * @param co A pointer to an MQTTAsync_connected() callback
422  * function.  NULL removes the callback setting.
423  * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set,
424  * ::MQTTASYNC_FAILURE if an error occurred.
425  */
426 DLLExport int MQTTAsync_setDisconnected(MQTTAsync handle, void* context, MQTTAsync_disconnected* co);
427 
428 
429 /** The data returned on completion of an unsuccessful API call in the response callback onFailure. */
430 typedef struct
431 {
432 	/** A token identifying the failed request. */
433 	MQTTAsync_token token;
434 	/** A numeric code identifying the error. */
435 	int code;
436 	/** Optional text explaining the error. Can be NULL. */
437 	const char *message;
438 } MQTTAsync_failureData;
439 
440 
441 /** The data returned on completion of an unsuccessful API call in the response callback onFailure. */
442 typedef struct
443 {
444 	/** The eyecatcher for this structure.  Will be MQFD. */
445 	char struct_id[4];
446 	/** The version number of this structure.  Will be 0 */
447 	int struct_version;
448 	/** A token identifying the failed request. */
449 	MQTTAsync_token token;
450 	/** The MQTT reason code returned. */
451 	enum MQTTReasonCodes reasonCode;
452 	/** The MQTT properties on the ack, if any. */
453 	MQTTProperties properties;
454 	/** A numeric code identifying the MQTT client library error. */
455 	int code;
456 	/** Optional further text explaining the error. Can be NULL. */
457 	const char *message;
458 	/** Packet type on which the failure occurred - used for publish QoS 1/2 exchanges*/
459 	int packet_type;
460 } MQTTAsync_failureData5;
461 
462 #define MQTTAsync_failureData5_initializer {{'M', 'Q', 'F', 'D'}, 0, 0, MQTTREASONCODE_SUCCESS, MQTTProperties_initializer, 0, NULL, 0}
463 
464 /** The data returned on completion of a successful API call in the response callback onSuccess. */
465 typedef struct
466 {
467 	/** A token identifying the successful request. Can be used to refer to the request later. */
468 	MQTTAsync_token token;
469 	/** A union of the different values that can be returned for subscribe, unsubscribe and publish. */
470 	union
471 	{
472 		/** For subscribe, the granted QoS of the subscription returned by the server. */
473 		int qos;
474 		/** For subscribeMany, the list of granted QoSs of the subscriptions returned by the server. */
475 		int* qosList;
476 		/** For publish, the message being sent to the server. */
477 		struct
478 		{
479 			MQTTAsync_message message;
480 			char* destinationName;
481 		} pub;
482 		/* For connect, the server connected to, MQTT version used, and sessionPresent flag */
483 		struct
484 		{
485 			char* serverURI;
486 			int MQTTVersion;
487 			int sessionPresent;
488 		} connect;
489 	} alt;
490 } MQTTAsync_successData;
491 
492 
493 /** The data returned on completion of a successful API call in the response callback onSuccess. */
494 typedef struct
495 {
496 	char struct_id[4];    	/**< The eyecatcher for this structure.  Will be MQSD. */
497 	int struct_version;  	/**< The version number of this structure.  Will be 0 */
498 	/** A token identifying the successful request. Can be used to refer to the request later. */
499 	MQTTAsync_token token;
500 	enum MQTTReasonCodes reasonCode;  	/**< MQTT V5 reason code returned */
501 	MQTTProperties properties;  	        /**< MQTT V5 properties returned, if any */
502 	/** A union of the different values that can be returned for subscribe, unsubscribe and publish. */
503 	union
504 	{
505 		/** For subscribeMany, the list of reasonCodes returned by the server. */
506 		struct
507 		{
508 			int reasonCodeCount; /**< the number of reason codes in the reasonCodes array */
509 			enum MQTTReasonCodes* reasonCodes; /**< an array of reasonCodes */
510 		} sub;
511 		/** For publish, the message being sent to the server. */
512 		struct
513 		{
514 			MQTTAsync_message message; /**< the message being sent to the server */
515 			char* destinationName;     /**< the topic destination for the message */
516 		} pub;
517 		/* For connect, the server connected to, MQTT version used, and sessionPresent flag */
518 		struct
519 		{
520 			char* serverURI;  /**< the connection string of the server */
521 			int MQTTVersion;  /**< the version of MQTT being used */
522 			int sessionPresent;  /**< the session present flag returned from the server */
523 		} connect;
524 		/** For unsubscribeMany, the list of reasonCodes returned by the server. */
525 		struct
526 		{
527 			int reasonCodeCount; /**< the number of reason codes in the reasonCodes array */
528 			enum MQTTReasonCodes* reasonCodes; /**< an array of reasonCodes */
529 		} unsub;
530 	} alt;
531 } MQTTAsync_successData5;
532 #define MQTTalt_initializer {.sub.reasonCodeCount = 0, .sub.reasonCodes = NULL}
533 #define MQTTAsync_successData5_initializer {{'M', 'Q', 'S', 'D'}, 0, 0, MQTTREASONCODE_SUCCESS, MQTTProperties_initializer, MQTTalt_initializer}
534 
535 /**
536  * This is a callback function. The client application
537  * must provide an implementation of this function to enable asynchronous
538  * notification of the successful completion of an API call. The function is
539  * registered with the client library by passing it as an argument in
540  * ::MQTTAsync_responseOptions.
541  * @param context A pointer to the <i>context</i> value originally passed to
542  * ::MQTTAsync_responseOptions, which contains any application-specific context.
543  * @param response Any success data associated with the API completion.
544  */
545 typedef void MQTTAsync_onSuccess(void* context, MQTTAsync_successData* response);
546 
547 /**
548  * This is a callback function, the MQTT V5 version of ::MQTTAsync_onSuccess.
549  * The client application
550  * must provide an implementation of this function to enable asynchronous
551  * notification of the successful completion of an API call. The function is
552  * registered with the client library by passing it as an argument in
553  * ::MQTTAsync_responseOptions.
554  * @param context A pointer to the <i>context</i> value originally passed to
555  * ::MQTTAsync_responseOptions, which contains any application-specific context.
556  * @param response Any success data associated with the API completion.
557  */
558 typedef void MQTTAsync_onSuccess5(void* context, MQTTAsync_successData5* response);
559 
560 /**
561  * This is a callback function. The client application
562  * must provide an implementation of this function to enable asynchronous
563  * notification of the unsuccessful completion of an API call. The function is
564  * registered with the client library by passing it as an argument in
565  * ::MQTTAsync_responseOptions.
566  * @param context A pointer to the <i>context</i> value originally passed to
567  * ::MQTTAsync_responseOptions, which contains any application-specific context.
568  * @param response Failure data associated with the API completion.
569  */
570 typedef void MQTTAsync_onFailure(void* context,  MQTTAsync_failureData* response);
571 
572 /**
573  * This is a callback function, the MQTT V5 version of ::MQTTAsync_onFailure.
574  * The application must provide an implementation of this function to enable asynchronous
575  * notification of the unsuccessful completion of an API call. The function is
576  * registered with the client library by passing it as an argument in
577  * ::MQTTAsync_responseOptions.
578  * @param context A pointer to the <i>context</i> value originally passed to
579  * ::MQTTAsync_responseOptions, which contains any application-specific context.
580  * @param response Failure data associated with the API completion.
581  */
582 typedef void MQTTAsync_onFailure5(void* context,  MQTTAsync_failureData5* response);
583 
584 typedef struct MQTTAsync_responseOptions
585 {
586 	/** The eyecatcher for this structure.  Must be MQTR */
587 	char struct_id[4];
588 	/** The version number of this structure.  Must be 0 or 1
589 	 *   if 0, no MQTTV5 options */
590 	int struct_version;
591 	/**
592     * A pointer to a callback function to be called if the API call successfully
593     * completes.  Can be set to NULL, in which case no indication of successful
594     * completion will be received.
595     */
596 	MQTTAsync_onSuccess* onSuccess;
597 	/**
598     * A pointer to a callback function to be called if the API call fails.
599     * Can be set to NULL, in which case no indication of unsuccessful
600     * completion will be received.
601     */
602 	MQTTAsync_onFailure* onFailure;
603 	/**
604     * A pointer to any application-specific context. The
605     * the <i>context</i> pointer is passed to success or failure callback functions to
606     * provide access to the context information in the callback.
607     */
608 	void* context;
609 	/**
610     * A token is returned from the call.  It can be used to track
611     * the state of this request, both in the callbacks and in future calls
612     * such as ::MQTTAsync_waitForCompletion.
613     */
614 	MQTTAsync_token token;
615 	/**
616     * A pointer to a callback function to be called if the API call successfully
617     * completes.  Can be set to NULL, in which case no indication of successful
618     * completion will be received.
619     */
620 	MQTTAsync_onSuccess5* onSuccess5;
621 	/**
622     * A pointer to a callback function to be called if the API call successfully
623     * completes.  Can be set to NULL, in which case no indication of successful
624     * completion will be received.
625     */
626 	MQTTAsync_onFailure5* onFailure5;
627 	/**
628 	 * MQTT V5 input properties
629 	 */
630 	MQTTProperties properties;
631 	/*
632 	 * MQTT V5 subscribe options, when used with subscribe only.
633 	 */
634 	MQTTSubscribe_options subscribeOptions;
635 	/*
636 	 * MQTT V5 subscribe option count, when used with subscribeMany only.
637 	 * The number of entries in the subscribe_options_list array.
638 	 */
639 	int subscribeOptionsCount;
640 	/*
641 	 * MQTT V5 subscribe option array, when used with subscribeMany only.
642 	 */
643 	MQTTSubscribe_options* subscribeOptionsList;
644 } MQTTAsync_responseOptions;
645 
646 #define MQTTAsync_responseOptions_initializer { {'M', 'Q', 'T', 'R'}, 1, NULL, NULL, 0, 0, NULL, NULL, MQTTProperties_initializer, MQTTSubscribe_options_initializer, 0, NULL}
647 
648 typedef struct MQTTAsync_responseOptions MQTTAsync_callOptions;
649 #define MQTTAsync_callOptions_initializer MQTTAsync_responseOptions_initializer
650 
651 /**
652  * This function sets the global callback functions for a specific client.
653  * If your client application doesn't use a particular callback, set the
654  * relevant parameter to NULL. Any necessary message acknowledgements and
655  * status communications are handled in the background without any intervention
656  * from the client application.  If you do not set a messageArrived callback
657  * function, you will not be notified of the receipt of any messages as a
658  * result of a subscription.
659  *
660  * <b>Note:</b> The MQTT client must be disconnected when this function is
661  * called.
662  * @param handle A valid client handle from a successful call to
663  * MQTTAsync_create().
664  * @param context A pointer to any application-specific context. The
665  * the <i>context</i> pointer is passed to each of the callback functions to
666  * provide access to the context information in the callback.
667  * @param cl A pointer to an MQTTAsync_connectionLost() callback
668  * function. You can set this to NULL if your application doesn't handle
669  * disconnections.
670  * @param ma A pointer to an MQTTAsync_messageArrived() callback
671  * function.  You can set this to NULL if your application doesn't handle
672  * receipt of messages.
673  * @param dc A pointer to an MQTTAsync_deliveryComplete() callback
674  * function. You can set this to NULL if you do not want to check
675  * for successful delivery.
676  * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set,
677  * ::MQTTASYNC_FAILURE if an error occurred.
678  */
679 DLLExport int MQTTAsync_setCallbacks(MQTTAsync handle, void* context, MQTTAsync_connectionLost* cl,
680 									 MQTTAsync_messageArrived* ma, MQTTAsync_deliveryComplete* dc);
681 
682 /**
683  * This function sets the callback function for a connection lost event for
684  * a specific client. Any necessary message acknowledgements and status
685  * communications are handled in the background without any intervention
686  * from the client application.
687  *
688  * <b>Note:</b> The MQTT client must be disconnected when this function is
689  * called.
690  * @param handle A valid client handle from a successful call to
691  * MQTTAsync_create().
692  * @param context A pointer to any application-specific context. The
693  * the <i>context</i> pointer is passed the callback functions to provide
694  * access to the context information in the callback.
695  * @param cl A pointer to an MQTTAsync_connectionLost() callback
696  * function. You can set this to NULL if your application doesn't handle
697  * disconnections.
698  * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set,
699  * ::MQTTASYNC_FAILURE if an error occurred.
700  */
701 
702 DLLExport int MQTTAsync_setConnectionLostCallback(MQTTAsync handle, void* context,
703 												  MQTTAsync_connectionLost* cl);
704 
705 /**
706  * This function sets the callback function for a message arrived event for
707  * a specific client. Any necessary message acknowledgements and status
708  * communications are handled in the background without any intervention
709  * from the client application.  If you do not set a messageArrived callback
710  * function, you will not be notified of the receipt of any messages as a
711  * result of a subscription.
712  *
713  * <b>Note:</b> The MQTT client must be disconnected when this function is
714  * called.
715  * @param handle A valid client handle from a successful call to
716  * MQTTAsync_create().
717  * @param context A pointer to any application-specific context. The
718  * the <i>context</i> pointer is passed to the callback functions to provide
719  * access to the context information in the callback.
720  * @param ma A pointer to an MQTTAsync_messageArrived() callback
721  * function.  You can set this to NULL if your application doesn't handle
722  * receipt of messages.
723  * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set,
724  * ::MQTTASYNC_FAILURE if an error occurred.
725  */
726 DLLExport int MQTTAsync_setMessageArrivedCallback(MQTTAsync handle, void* context,
727 												  MQTTAsync_messageArrived* ma);
728 
729 /**
730  * This function sets the callback function for a delivery complete event
731  * for a specific client. Any necessary message acknowledgements and status
732  * communications are handled in the background without any intervention
733  * from the client application.
734  *
735  * <b>Note:</b> The MQTT client must be disconnected when this function is
736  * called.
737  * @param handle A valid client handle from a successful call to
738  * MQTTAsync_create().
739  * @param context A pointer to any application-specific context. The
740  * the <i>context</i> pointer is passed to the callback functions to provide
741  * access to the context information in the callback.
742  * @param dc A pointer to an MQTTAsync_deliveryComplete() callback
743  * function. You can set this to NULL if you do not want to check
744  * for successful delivery.
745  * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set,
746  * ::MQTTASYNC_FAILURE if an error occurred.
747  */
748 DLLExport int MQTTAsync_setDeliveryCompleteCallback(MQTTAsync handle, void* context,
749 													MQTTAsync_deliveryComplete* dc);
750 
751 /**
752  * Sets the MQTTAsync_connected() callback function for a client.
753  * @param handle A valid client handle from a successful call to
754  * MQTTAsync_create().
755  * @param context A pointer to any application-specific context. The
756  * the <i>context</i> pointer is passed to each of the callback functions to
757  * provide access to the context information in the callback.
758  * @param co A pointer to an MQTTAsync_connected() callback
759  * function.  NULL removes the callback setting.
760  * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set,
761  * ::MQTTASYNC_FAILURE if an error occurred.
762  */
763 DLLExport int MQTTAsync_setConnected(MQTTAsync handle, void* context, MQTTAsync_connected* co);
764 
765 
766 /**
767  * Reconnects a client with the previously used connect options.  Connect
768  * must have previously been called for this to work.
769  * @param handle A valid client handle from a successful call to
770  * MQTTAsync_create().
771  * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set,
772  * ::MQTTASYNC_FAILURE if an error occurred.
773  */
774 DLLExport int MQTTAsync_reconnect(MQTTAsync handle);
775 
776 
777 /**
778  * This function creates an MQTT client ready for connection to the
779  * specified server and using the specified persistent storage (see
780  * MQTTAsync_persistence). See also MQTTAsync_destroy().
781  * @param handle A pointer to an ::MQTTAsync handle. The handle is
782  * populated with a valid client reference following a successful return from
783  * this function.
784  * @param serverURI A null-terminated string specifying the server to
785  * which the client will connect. It takes the form <i>protocol://host:port</i>.
786  * <i>protocol</i> must be <i>tcp</i> or <i>ssl</i>. For <i>host</i>, you can
787  * specify either an IP address or a host name. For instance, to connect to
788  * a server running on the local machines with the default MQTT port, specify
789  * <i>tcp://localhost:1883</i>.
790  * @param clientId The client identifier passed to the server when the
791  * client connects to it. It is a null-terminated UTF-8 encoded string.
792  * @param persistence_type The type of persistence to be used by the client:
793  * <br>
794  * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or
795  * system on which the client is running fails or is switched off, the current
796  * state of any in-flight messages is lost and some messages may not be
797  * delivered even at QoS1 and QoS2.
798  * <br>
799  * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based)
800  * persistence mechanism. Status about in-flight messages is held in persistent
801  * storage and provides some protection against message loss in the case of
802  * unexpected failure.
803  * <br>
804  * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence
805  * implementation. Using this type of persistence gives control of the
806  * persistence mechanism to the application. The application has to implement
807  * the MQTTClient_persistence interface.
808  * @param persistence_context If the application uses
809  * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should
810  * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it
811  * should be set to the location of the persistence directory (if set
812  * to NULL, the persistence directory used is the working directory).
813  * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this
814  * argument to point to a valid MQTTClient_persistence structure.
815  * @return ::MQTTASYNC_SUCCESS if the client is successfully created, otherwise
816  * an error code is returned.
817  */
818 DLLExport int MQTTAsync_create(MQTTAsync* handle, const char* serverURI, const char* clientId,
819 		int persistence_type, void* persistence_context);
820 
821 typedef struct
822 {
823 	/** The eyecatcher for this structure.  must be MQCO. */
824 	char struct_id[4];
825 	/** The version number of this structure.  Must be 0 or 1
826 	 * 0 means no MQTTVersion
827 	 */
828 	int struct_version;
829 	/** Whether to allow messages to be sent when the client library is not connected. */
830 	int sendWhileDisconnected;
831 	/** the maximum number of messages allowed to be buffered while not connected. */
832 	int maxBufferedMessages;
833 	/** Whether the MQTT version is 3.1, 3.1.1, or 5.  To use V5, this must be set.
834 	 *  MQTT V5 has to be chosen here, because during the create call the message persistence
835 	 *  is initialized, and we want to know whether the format of any persisted messages
836 	 *  is appropriate for the MQTT version we are going to connect with.  Selecting 3.1 or
837 	 *  3.1.1 and attempting to read 5.0 persisted messages will result in an error on create.  */
838 	int MQTTVersion;
839 } MQTTAsync_createOptions;
840 
841 #define MQTTAsync_createOptions_initializer { {'M', 'Q', 'C', 'O'}, 0, 0, 100, MQTTVERSION_DEFAULT }
842 
843 
844 DLLExport int MQTTAsync_createWithOptions(MQTTAsync* handle, const char* serverURI, const char* clientId,
845 		int persistence_type, void* persistence_context, MQTTAsync_createOptions* options);
846 
847 /**
848  * MQTTAsync_willOptions defines the MQTT "Last Will and Testament" (LWT) settings for
849  * the client. In the event that a client unexpectedly loses its connection to
850  * the server, the server publishes the LWT message to the LWT topic on
851  * behalf of the client. This allows other clients (subscribed to the LWT topic)
852  * to be made aware that the client has disconnected. To enable the LWT
853  * function for a specific client, a valid pointer to an MQTTAsync_willOptions
854  * structure is passed in the MQTTAsync_connectOptions structure used in the
855  * MQTTAsync_connect() call that connects the client to the server. The pointer
856  * to MQTTAsync_willOptions can be set to NULL if the LWT function is not
857  * required.
858  */
859 typedef struct
860 {
861 	/** The eyecatcher for this structure.  must be MQTW. */
862 	char struct_id[4];
863 	/** The version number of this structure.  Must be 0 or 1
864 	    0 indicates no binary will message support
865 	 */
866 	int struct_version;
867 	/** The LWT topic to which the LWT message will be published. */
868 	const char* topicName;
869 	/** The LWT payload. */
870 	const char* message;
871 	/**
872       * The retained flag for the LWT message (see MQTTAsync_message.retained).
873       */
874 	int retained;
875 	/**
876       * The quality of service setting for the LWT message (see
877       * MQTTAsync_message.qos and @ref qos).
878       */
879 	int qos;
880 	/** The LWT payload in binary form. This is only checked and used if the message option is NULL */
881 	struct
882 	{
883   	int len;            /**< binary payload length */
884 		const void* data;  /**< binary payload data */
885 	} payload;
886 } MQTTAsync_willOptions;
887 
888 #define MQTTAsync_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, { 0, NULL } }
889 
890 #define MQTT_SSL_VERSION_DEFAULT 0
891 #define MQTT_SSL_VERSION_TLS_1_0 1
892 #define MQTT_SSL_VERSION_TLS_1_1 2
893 #define MQTT_SSL_VERSION_TLS_1_2 3
894 
895 /**
896 * MQTTAsync_sslProperties defines the settings to establish an SSL/TLS connection using the
897 * OpenSSL library. It covers the following scenarios:
898 * - Server authentication: The client needs the digital certificate of the server. It is included
899 *   in a store containting trusted material (also known as "trust store").
900 * - Mutual authentication: Both client and server are authenticated during the SSL handshake. In
901 *   addition to the digital certificate of the server in a trust store, the client will need its own
902 *   digital certificate and the private key used to sign its digital certificate stored in a "key store".
903 * - Anonymous connection: Both client and server do not get authenticated and no credentials are needed
904 *   to establish an SSL connection. Note that this scenario is not fully secure since it is subject to
905 *   man-in-the-middle attacks.
906 */
907 typedef struct
908 {
909 	/** The eyecatcher for this structure.  Must be MQTS */
910 	char struct_id[4];
911 	/** The version number of this structure.    Must be 0, or 1 to enable TLS version selection. */
912 	int struct_version;
913 
914 	/** The file in PEM format containing the public digital certificates trusted by the client. */
915 	const char* trustStore;
916 
917 	/** The file in PEM format containing the public certificate chain of the client. It may also include
918 	* the client's private key.
919 	*/
920 	const char* keyStore;
921 
922 	/** If not included in the sslKeyStore, this setting points to the file in PEM format containing
923 	* the client's private key.
924 	*/
925 	const char* privateKey;
926 	/** The password to load the client's privateKey if encrypted. */
927 	const char* privateKeyPassword;
928 
929 	/**
930 	* The list of cipher suites that the client will present to the server during the SSL handshake. For a
931 	* full explanation of the cipher list format, please see the OpenSSL on-line documentation:
932 	* http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT
933 	* If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding
934 	* those offering no encryption- will be considered.
935 	* This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance).
936 	*/
937 	const char* enabledCipherSuites;
938 
939     /** True/False option to enable verification of the server certificate **/
940     int enableServerCertAuth;
941 
942     /** The SSL/TLS version to use. Specify one of MQTT_SSL_VERSION_DEFAULT (0),
943     * MQTT_SSL_VERSION_TLS_1_0 (1), MQTT_SSL_VERSION_TLS_1_1 (2) or MQTT_SSL_VERSION_TLS_1_2 (3).
944     * Only used if struct_version is >= 1.
945     */
946     int sslVersion;
947 
948     /**
949      * Whether to carry out post-connect checks, including that a certificate
950      * matches the given host name.
951      * Exists only if struct_version >= 2
952      */
953     int verify;
954 
955     /**
956      * From the OpenSSL documentation:
957      * If CApath is not NULL, it points to a directory containing CA certificates in PEM format.
958      * Exists only if struct_version >= 2
959 	 */
960 	const char* CApath;
961 
962     /**
963      * Callback function for OpenSSL error handler ERR_print_errors_cb
964      * Exists only if struct_version >= 3
965      */
966     int (*ssl_error_cb) (const char *str, size_t len, void *u);
967 
968     /**
969      * Application-specific contex for OpenSSL error handler ERR_print_errors_cb
970      * Exists only if struct_version >= 3
971      */
972     void* ssl_error_context;
973 
974 	/**
975 	 * Callback function for setting TLS-PSK options. Parameters correspond to that of
976 	 * SSL_CTX_set_psk_client_callback, except for u which is the pointer ssl_psk_context.
977 	 * Exists only if struct_version >= 4
978 	 */
979 	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);
980 
981 	/**
982 	 * Application-specific contex for ssl_psk_cb
983 	 * Exists only if struct_version >= 4
984 	 */
985 	void* ssl_psk_context;
986 
987 	/**
988 	 * Don't load default SSL CA. Should be used together with PSK to make sure
989 	 * regular servers with certificate in place is not accepted.
990 	 * Exists only if struct_version >= 4
991 	 */
992 	int disableDefaultTrustStore;
993 #if defined (__LITEOS__)
994 		/**  */
995 		const cert_string* los_trustStore;
996 
997 		/**  */
998 		const cert_string* los_keyStore;
999 
1000 		/**  */
1001 		const key_string* los_privateKey;
1002 
1003 #endif
1004 
1005 } MQTTAsync_SSLOptions;
1006 
1007 #define MQTTAsync_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}
1008 
1009 /**
1010  * MQTTAsync_connectOptions defines several settings that control the way the
1011  * client connects to an MQTT server.  Default values are set in
1012  * MQTTAsync_connectOptions_initializer.
1013  */
1014 typedef struct
1015 {
1016 	/** The eyecatcher for this structure.  must be MQTC. */
1017 	char struct_id[4];
1018 	/** The version number of this structure.  Must be 0, 1, 2, 3 4 5 or 6.
1019 	  * 0 signifies no SSL options and no serverURIs
1020 	  * 1 signifies no serverURIs
1021     * 2 signifies no MQTTVersion
1022     * 3 signifies no automatic reconnect options
1023     * 4 signifies no binary password option (just string)
1024     * 5 signifies no MQTTV5 properties
1025 	  */
1026 	int struct_version;
1027 	/** The "keep alive" interval, measured in seconds, defines the maximum time
1028       * that should pass without communication between the client and the server
1029       * The client will ensure that at least one message travels across the
1030       * network within each keep alive period.  In the absence of a data-related
1031 	  * message during the time period, the client sends a very small MQTT
1032       * "ping" message, which the server will acknowledge. The keep alive
1033       * interval enables the client to detect when the server is no longer
1034 	  * available without having to wait for the long TCP/IP timeout.
1035 	  * Set to 0 if you do not want any keep alive processing.
1036 	  */
1037 	int keepAliveInterval;
1038 	/**
1039       * This is a boolean value. The cleansession setting controls the behaviour
1040       * of both the client and the server at connection and disconnection time.
1041       * The client and server both maintain session state information. This
1042       * information is used to ensure "at least once" and "exactly once"
1043       * delivery, and "exactly once" receipt of messages. Session state also
1044       * includes subscriptions created by an MQTT client. You can choose to
1045       * maintain or discard state information between sessions.
1046       *
1047       * When cleansession is true, the state information is discarded at
1048       * connect and disconnect. Setting cleansession to false keeps the state
1049       * information. When you connect an MQTT client application with
1050       * MQTTAsync_connect(), the client identifies the connection using the
1051       * client identifier and the address of the server. The server checks
1052       * whether session information for this client
1053       * has been saved from a previous connection to the server. If a previous
1054       * session still exists, and cleansession=true, then the previous session
1055       * information at the client and server is cleared. If cleansession=false,
1056       * the previous session is resumed. If no previous session exists, a new
1057       * session is started.
1058 	  */
1059 	int cleansession;
1060 	/**
1061       * This controls how many messages can be in-flight simultaneously.
1062 	  */
1063 	int maxInflight;
1064 	/**
1065       * This is a pointer to an MQTTAsync_willOptions structure. If your
1066       * application does not make use of the Last Will and Testament feature,
1067       * set this pointer to NULL.
1068       */
1069 	MQTTAsync_willOptions* will;
1070 	/**
1071       * MQTT servers that support the MQTT v3.1 protocol provide authentication
1072       * and authorisation by user name and password. This is the user name
1073       * parameter.
1074       */
1075 	const char* username;
1076 	/**
1077       * MQTT servers that support the MQTT v3.1 protocol provide authentication
1078       * and authorisation by user name and password. This is the password
1079       * parameter.
1080       */
1081 	const char* password;
1082 	/**
1083       * The time interval in seconds to allow a connect to complete.
1084       */
1085 	int connectTimeout;
1086 	/**
1087 	 * The time interval in seconds after which unacknowledged publish requests are
1088 	 * retried during a TCP session.  With MQTT 3.1.1 and later, retries are
1089 	 * not required except on reconnect.  0 turns off in-session retries, and is the
1090 	 * recommended setting.  Adding retries to an already overloaded network only
1091 	 * exacerbates the problem.
1092 	 */
1093 	int retryInterval;
1094 	/**
1095       * This is a pointer to an MQTTAsync_SSLOptions structure. If your
1096       * application does not make use of SSL, set this pointer to NULL.
1097       */
1098 	MQTTAsync_SSLOptions* ssl;
1099 	/**
1100       * A pointer to a callback function to be called if the connect successfully
1101       * completes.  Can be set to NULL, in which case no indication of successful
1102       * completion will be received.
1103       */
1104 	MQTTAsync_onSuccess* onSuccess;
1105 	/**
1106       * A pointer to a callback function to be called if the connect fails.
1107       * Can be set to NULL, in which case no indication of unsuccessful
1108       * completion will be received.
1109       */
1110 	MQTTAsync_onFailure* onFailure;
1111 	/**
1112 	  * A pointer to any application-specific context. The
1113       * the <i>context</i> pointer is passed to success or failure callback functions to
1114       * provide access to the context information in the callback.
1115       */
1116 	void* context;
1117 	/**
1118 	  * The number of entries in the serverURIs array.
1119 	  */
1120 	int serverURIcount;
1121 	/**
1122 	  * An array of null-terminated strings specifying the servers to
1123       * which the client will connect. Each string takes the form <i>protocol://host:port</i>.
1124       * <i>protocol</i> must be <i>tcp</i> or <i>ssl</i>. For <i>host</i>, you can
1125       * specify either an IP address or a domain name. For instance, to connect to
1126       * a server running on the local machines with the default MQTT port, specify
1127       * <i>tcp://localhost:1883</i>.
1128       */
1129 	char* const* serverURIs;
1130 	/**
1131       * Sets the version of MQTT to be used on the connect.
1132       * MQTTVERSION_DEFAULT (0) = default: start with 3.1.1, and if that fails, fall back to 3.1
1133       * MQTTVERSION_3_1 (3) = only try version 3.1
1134       * MQTTVERSION_3_1_1 (4) = only try version 3.1.1
1135 	  */
1136 	int MQTTVersion;
1137 	/**
1138 	  * Reconnect automatically in the case of a connection being lost?
1139 	  */
1140 	int automaticReconnect;
1141 	/**
1142 	  * Minimum retry interval in seconds.  Doubled on each failed retry.
1143 	  */
1144 	int minRetryInterval;
1145 	/**
1146 	  * Maximum retry interval in seconds.  The doubling stops here on failed retries.
1147 	  */
1148 	int maxRetryInterval;
1149 	/**
1150 	 * Optional binary password.  Only checked and used if the password option is NULL
1151 	 */
1152 	struct {
1153 		int len;            /**< binary password length */
1154 		const void* data;  /**< binary password data */
1155 	} binarypwd;
1156 	/*
1157 	 * MQTT V5 clean start flag.  Only clears state at the beginning of the session.
1158 	 */
1159 	int cleanstart;
1160 	/**
1161 	 * MQTT V5 properties for connect
1162 	 */
1163 	MQTTProperties *connectProperties;
1164 	/**
1165 	 * MQTT V5 properties for the will message in the connect
1166 	 */
1167 	MQTTProperties *willProperties;
1168 	/**
1169       * A pointer to a callback function to be called if the connect successfully
1170       * completes.  Can be set to NULL, in which case no indication of successful
1171       * completion will be received.
1172       */
1173 	MQTTAsync_onSuccess5* onSuccess5;
1174 	/**
1175       * A pointer to a callback function to be called if the connect fails.
1176       * Can be set to NULL, in which case no indication of unsuccessful
1177       * completion will be received.
1178       */
1179 	MQTTAsync_onFailure5* onFailure5;
1180 } MQTTAsync_connectOptions;
1181 
1182 
1183 #define MQTTAsync_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 6, 60, 1, 65535, NULL, NULL, NULL, 30, 0,\
1184 NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_DEFAULT, 0, 1, 60, {0, NULL}, 0, NULL, NULL, NULL, NULL}
1185 
1186 #define MQTTAsync_connectOptions_initializer5 { {'M', 'Q', 'T', 'C'}, 6, 60, 0, 65535, NULL, NULL, NULL, 30, 0,\
1187 NULL, NULL, NULL, NULL, 0, NULL, MQTTVERSION_5, 0, 1, 60, {0, NULL}, 1, NULL, NULL, NULL, NULL}
1188 
1189 
1190 /**
1191   * This function attempts to connect a previously-created client (see
1192   * MQTTAsync_create()) to an MQTT server using the specified options. If you
1193   * want to enable asynchronous message and status notifications, you must call
1194   * MQTTAsync_setCallbacks() prior to MQTTAsync_connect().
1195   * @param handle A valid client handle from a successful call to
1196   * MQTTAsync_create().
1197   * @param options A pointer to a valid MQTTAsync_connectOptions
1198   * structure.
1199   * @return ::MQTTASYNC_SUCCESS if the client connect request was accepted.
1200   * If the client was unable to connect to the server, an error code is
1201   * returned via the onFailure callback, if set.
1202   * Error codes greater than 0 are returned by the MQTT protocol:<br><br>
1203   * <b>1</b>: Connection refused: Unacceptable protocol version<br>
1204   * <b>2</b>: Connection refused: Identifier rejected<br>
1205   * <b>3</b>: Connection refused: Server unavailable<br>
1206   * <b>4</b>: Connection refused: Bad user name or password<br>
1207   * <b>5</b>: Connection refused: Not authorized<br>
1208   * <b>6-255</b>: Reserved for future use<br>
1209   */
1210 DLLExport int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options);
1211 
1212 
1213 typedef struct
1214 {
1215 	/** The eyecatcher for this structure. Must be MQTD. */
1216 	char struct_id[4];
1217 	/** The version number of this structure.  Must be 0 or 1.  0 signifies no V5 properties */
1218 	int struct_version;
1219 	/**
1220       * The client delays disconnection for up to this time (in
1221       * milliseconds) in order to allow in-flight message transfers to complete.
1222       */
1223 	int timeout;
1224 	/**
1225     * A pointer to a callback function to be called if the disconnect successfully
1226     * completes.  Can be set to NULL, in which case no indication of successful
1227     * completion will be received.
1228     */
1229 	MQTTAsync_onSuccess* onSuccess;
1230 	/**
1231     * A pointer to a callback function to be called if the disconnect fails.
1232     * Can be set to NULL, in which case no indication of unsuccessful
1233     * completion will be received.
1234     */
1235 	MQTTAsync_onFailure* onFailure;
1236 	/**
1237 	* A pointer to any application-specific context. The
1238     * the <i>context</i> pointer is passed to success or failure callback functions to
1239     * provide access to the context information in the callback.
1240     */
1241 	void* context;
1242 	/**
1243 	 * MQTT V5 input properties
1244 	 */
1245 	MQTTProperties properties;
1246 	/**
1247 	 * Reason code for MQTTV5 disconnect
1248 	 */
1249 	enum MQTTReasonCodes reasonCode;
1250 	/**
1251     * A pointer to a callback function to be called if the disconnect successfully
1252     * completes.  Can be set to NULL, in which case no indication of successful
1253     * completion will be received.
1254     */
1255 	MQTTAsync_onSuccess5* onSuccess5;
1256 	/**
1257     * A pointer to a callback function to be called if the disconnect fails.
1258     * Can be set to NULL, in which case no indication of unsuccessful
1259     * completion will be received.
1260     */
1261 	MQTTAsync_onFailure5* onFailure5;
1262 } MQTTAsync_disconnectOptions;
1263 
1264 #define MQTTAsync_disconnectOptions_initializer { {'M', 'Q', 'T', 'D'}, 1, 0, NULL, NULL, NULL, MQTTProperties_initializer, MQTTREASONCODE_SUCCESS, NULL, NULL}
1265 
1266 #define MQTTAsync_disconnectOptions_initializer5 { {'M', 'Q', 'T', 'D'}, 1, 0, NULL, NULL, NULL,\
1267 	MQTTProperties_initializer, MQTTREASONCODE_SUCCESS, NULL, NULL }
1268 
1269 /**
1270   * This function attempts to disconnect the client from the MQTT
1271   * server. In order to allow the client time to complete handling of messages
1272   * that are in-flight when this function is called, a timeout period is
1273   * specified. When the timeout period has expired, the client disconnects even
1274   * if there are still outstanding message acknowledgements.
1275   * The next time the client connects to the same server, any QoS 1 or 2
1276   * messages which have not completed will be retried depending on the
1277   * cleansession settings for both the previous and the new connection (see
1278   * MQTTAsync_connectOptions.cleansession and MQTTAsync_connect()).
1279   * @param handle A valid client handle from a successful call to
1280   * MQTTAsync_create().
1281   * @param options The client delays disconnection for up to this time (in
1282   * milliseconds) in order to allow in-flight message transfers to complete.
1283   * @return ::MQTTASYNC_SUCCESS if the client successfully disconnects from
1284   * the server. An error code is returned if the client was unable to disconnect
1285   * from the server
1286   */
1287 DLLExport int MQTTAsync_disconnect(MQTTAsync handle, const MQTTAsync_disconnectOptions* options);
1288 
1289 
1290 /**
1291   * This function allows the client application to test whether or not a
1292   * client is currently connected to the MQTT server.
1293   * @param handle A valid client handle from a successful call to
1294   * MQTTAsync_create().
1295   * @return Boolean true if the client is connected, otherwise false.
1296   */
1297 DLLExport int MQTTAsync_isConnected(MQTTAsync handle);
1298 
1299 
1300 /**
1301   * This function attempts to subscribe a client to a single topic, which may
1302   * contain wildcards (see @ref wildcard). This call also specifies the
1303   * @ref qos requested for the subscription
1304   * (see also MQTTAsync_subscribeMany()).
1305   * @param handle A valid client handle from a successful call to
1306   * MQTTAsync_create().
1307   * @param topic The subscription topic, which may include wildcards.
1308   * @param qos The requested quality of service for the subscription.
1309   * @param response A pointer to a response options structure. Used to set callback functions.
1310   * @return ::MQTTASYNC_SUCCESS if the subscription request is successful.
1311   * An error code is returned if there was a problem registering the
1312   * subscription.
1313   */
1314 DLLExport int MQTTAsync_subscribe(MQTTAsync handle, const char* topic, int qos, MQTTAsync_responseOptions* response);
1315 
1316 
1317 /**
1318   * This function attempts to subscribe a client to a list of topics, which may
1319   * contain wildcards (see @ref wildcard). This call also specifies the
1320   * @ref qos requested for each topic (see also MQTTAsync_subscribe()).
1321   * @param handle A valid client handle from a successful call to
1322   * MQTTAsync_create().
1323   * @param count The number of topics for which the client is requesting
1324   * subscriptions.
1325   * @param topic An array (of length <i>count</i>) of pointers to
1326   * topics, each of which may include wildcards.
1327   * @param qos An array (of length <i>count</i>) of @ref qos
1328   * values. qos[n] is the requested QoS for topic[n].
1329   * @param response A pointer to a response options structure. Used to set callback functions.
1330   * @return ::MQTTASYNC_SUCCESS if the subscription request is successful.
1331   * An error code is returned if there was a problem registering the
1332   * subscriptions.
1333   */
1334 DLLExport int MQTTAsync_subscribeMany(MQTTAsync handle, int count, char* const* topic, int* qos, MQTTAsync_responseOptions* response);
1335 
1336 /**
1337   * This function attempts to remove an existing subscription made by the
1338   * specified client.
1339   * @param handle A valid client handle from a successful call to
1340   * MQTTAsync_create().
1341   * @param topic The topic for the subscription to be removed, which may
1342   * include wildcards (see @ref wildcard).
1343   * @param response A pointer to a response options structure. Used to set callback functions.
1344   * @return ::MQTTASYNC_SUCCESS if the subscription is removed.
1345   * An error code is returned if there was a problem removing the
1346   * subscription.
1347   */
1348 DLLExport int MQTTAsync_unsubscribe(MQTTAsync handle, const char* topic, MQTTAsync_responseOptions* response);
1349 
1350 /**
1351   * This function attempts to remove existing subscriptions to a list of topics
1352   * made by the specified client.
1353   * @param handle A valid client handle from a successful call to
1354   * MQTTAsync_create().
1355   * @param count The number subscriptions to be removed.
1356   * @param topic An array (of length <i>count</i>) of pointers to the topics of
1357   * the subscriptions to be removed, each of which may include wildcards.
1358   * @param response A pointer to a response options structure. Used to set callback functions.
1359   * @return ::MQTTASYNC_SUCCESS if the subscriptions are removed.
1360   * An error code is returned if there was a problem removing the subscriptions.
1361   */
1362 DLLExport int MQTTAsync_unsubscribeMany(MQTTAsync handle, int count, char* const* topic, MQTTAsync_responseOptions* response);
1363 
1364 
1365 /**
1366   * This function attempts to publish a message to a given topic (see also
1367   * ::MQTTAsync_sendMessage()). An ::MQTTAsync_token is issued when
1368   * this function returns successfully. If the client application needs to
1369   * test for successful delivery of messages, a callback should be set
1370   * (see ::MQTTAsync_onSuccess() and ::MQTTAsync_deliveryComplete()).
1371   * @param handle A valid client handle from a successful call to
1372   * MQTTAsync_create().
1373   * @param destinationName The topic associated with this message.
1374   * @param payloadlen The length of the payload in bytes.
1375   * @param payload A pointer to the byte array payload of the message.
1376   * @param qos The @ref qos of the message.
1377   * @param retained The retained flag for the message.
1378   * @param response A pointer to an ::MQTTAsync_responseOptions structure. Used to set callback functions.
1379   * This is optional and can be set to NULL.
1380   * @return ::MQTTASYNC_SUCCESS if the message is accepted for publication.
1381   * An error code is returned if there was a problem accepting the message.
1382   */
1383 DLLExport int MQTTAsync_send(MQTTAsync handle, const char* destinationName, int payloadlen, const void* payload, int qos,
1384 		int retained, MQTTAsync_responseOptions* response);
1385 
1386 
1387 /**
1388   * This function attempts to publish a message to a given topic (see also
1389   * MQTTAsync_publish()). An ::MQTTAsync_token is issued when
1390   * this function returns successfully. If the client application needs to
1391   * test for successful delivery of messages, a callback should be set
1392   * (see ::MQTTAsync_onSuccess() and ::MQTTAsync_deliveryComplete()).
1393   * @param handle A valid client handle from a successful call to
1394   * MQTTAsync_create().
1395   * @param destinationName The topic associated with this message.
1396   * @param msg A pointer to a valid MQTTAsync_message structure containing
1397   * the payload and attributes of the message to be published.
1398   * @param response A pointer to an ::MQTTAsync_responseOptions structure. Used to set callback functions.
1399   * @return ::MQTTASYNC_SUCCESS if the message is accepted for publication.
1400   * An error code is returned if there was a problem accepting the message.
1401   */
1402 DLLExport int MQTTAsync_sendMessage(MQTTAsync handle, const char* destinationName, const MQTTAsync_message* msg, MQTTAsync_responseOptions* response);
1403 
1404 
1405 /**
1406   * This function sets a pointer to an array of tokens for
1407   * messages that are currently in-flight (pending completion).
1408   *
1409   * <b>Important note:</b> The memory used to hold the array of tokens is
1410   * malloc()'d in this function. The client application is responsible for
1411   * freeing this memory when it is no longer required.
1412   * @param handle A valid client handle from a successful call to
1413   * MQTTAsync_create().
1414   * @param tokens The address of a pointer to an ::MQTTAsync_token.
1415   * When the function returns successfully, the pointer is set to point to an
1416   * array of tokens representing messages pending completion. The last member of
1417   * the array is set to -1 to indicate there are no more tokens. If no tokens
1418   * are pending, the pointer is set to NULL.
1419   * @return ::MQTTASYNC_SUCCESS if the function returns successfully.
1420   * An error code is returned if there was a problem obtaining the list of
1421   * pending tokens.
1422   */
1423 DLLExport int MQTTAsync_getPendingTokens(MQTTAsync handle, MQTTAsync_token **tokens);
1424 
1425 /**
1426  * Tests whether a request corresponding to a token is complete.
1427  *
1428  * @param handle A valid client handle from a successful call to
1429  * MQTTAsync_create().
1430  * @param token An ::MQTTAsync_token associated with a request.
1431  * @return 1 if the request has been completed, 0 if not.
1432  */
1433 #define MQTTASYNC_TRUE 1
1434 DLLExport int MQTTAsync_isComplete(MQTTAsync handle, MQTTAsync_token token);
1435 
1436 
1437 /**
1438  * Waits for a request corresponding to a token to complete.
1439  *
1440  * @param handle A valid client handle from a successful call to
1441  * MQTTAsync_create().
1442  * @param token An ::MQTTAsync_token associated with a request.
1443  * @param timeout the maximum time to wait for completion, in milliseconds
1444  * @return ::MQTTASYNC_SUCCESS if the request has been completed in the time allocated,
1445  *  ::MQTTASYNC_FAILURE if not.
1446  */
1447 DLLExport int MQTTAsync_waitForCompletion(MQTTAsync handle, MQTTAsync_token token, unsigned long timeout);
1448 
1449 
1450 /**
1451   * This function frees memory allocated to an MQTT message, including the
1452   * additional memory allocated to the message payload. The client application
1453   * calls this function when the message has been fully processed. <b>Important
1454   * note:</b> This function does not free the memory allocated to a message
1455   * topic string. It is the responsibility of the client application to free
1456   * this memory using the MQTTAsync_free() library function.
1457   * @param msg The address of a pointer to the ::MQTTAsync_message structure
1458   * to be freed.
1459   */
1460 DLLExport void MQTTAsync_freeMessage(MQTTAsync_message** msg);
1461 
1462 /**
1463   * This function frees memory allocated by the MQTT C client library, especially the
1464   * topic name. This is needed on Windows when the client libary and application
1465   * program have been compiled with different versions of the C compiler.  It is
1466   * thus good policy to always use this function when freeing any MQTT C client-
1467   * allocated memory.
1468   * @param ptr The pointer to the client library storage to be freed.
1469   */
1470 DLLExport void MQTTAsync_free(void* ptr);
1471 
1472 /**
1473   * This function frees the memory allocated to an MQTT client (see
1474   * MQTTAsync_create()). It should be called when the client is no longer
1475   * required.
1476   * @param handle A pointer to the handle referring to the ::MQTTAsync
1477   * structure to be freed.
1478   */
1479 DLLExport void MQTTAsync_destroy(MQTTAsync* handle);
1480 
1481 
1482 
1483 enum MQTTASYNC_TRACE_LEVELS
1484 {
1485 	MQTTASYNC_TRACE_MAXIMUM = 1,
1486 	MQTTASYNC_TRACE_MEDIUM,
1487 	MQTTASYNC_TRACE_MINIMUM,
1488 	MQTTASYNC_TRACE_PROTOCOL,
1489 	MQTTASYNC_TRACE_ERROR,
1490 	MQTTASYNC_TRACE_SEVERE,
1491 	MQTTASYNC_TRACE_FATAL,
1492 };
1493 
1494 
1495 /**
1496   * This function sets the level of trace information which will be
1497   * returned in the trace callback.
1498   * @param level the trace level required
1499   */
1500 DLLExport void MQTTAsync_setTraceLevel(enum MQTTASYNC_TRACE_LEVELS level);
1501 
1502 
1503 /**
1504   * This is a callback function prototype which must be implemented if you want
1505   * to receive trace information.
1506   * @param level the trace level of the message returned
1507   * @param message the trace message.  This is a pointer to a static buffer which
1508   * will be overwritten on each call.  You must copy the data if you want to keep
1509   * it for later.
1510   */
1511 typedef void MQTTAsync_traceCallback(enum MQTTASYNC_TRACE_LEVELS level, char* message);
1512 
1513 /**
1514   * This function sets the trace callback if needed.  If set to NULL,
1515   * no trace information will be returned.  The default trace level is
1516   * MQTTASYNC_TRACE_MINIMUM.
1517   * @param callback a pointer to the function which will handle the trace information
1518   */
1519 DLLExport void MQTTAsync_setTraceCallback(MQTTAsync_traceCallback* callback);
1520 
1521 
1522 typedef struct
1523 {
1524 	const char* name;
1525 	const char* value;
1526 } MQTTAsync_nameValue;
1527 
1528 /**
1529   * This function returns version information about the library.
1530   * no trace information will be returned.  The default trace level is
1531   * MQTTASYNC_TRACE_MINIMUM
1532   * @return an array of strings describing the library.  The last entry is a NULL pointer.
1533   */
1534 DLLExport MQTTAsync_nameValue* MQTTAsync_getVersionInfo(void);
1535 
1536 /**
1537  * Returns a pointer to a string representation of the error code, or NULL.
1538  * Do not free after use. Returns NULL if the error code is unknown.
1539  * @param code the MQTTASYNC_ return code.
1540  * @return a static string representation of the error code.
1541  */
1542 DLLExport const char* MQTTAsync_strerror(int code);
1543 
1544 
1545 /**
1546   * @cond MQTTAsync_main
1547   * @page async Threading
1548   * The client application runs on several threads.
1549   * Processing of handshaking and maintaining
1550   * the network connection is performed in the background.
1551   * This API is thread safe: functions may be called by multiple application
1552   * threads.
1553   * Notifications of status and message reception are provided to the client
1554   * application using callbacks registered with the library by the call to
1555   * MQTTAsync_setCallbacks() (see MQTTAsync_messageArrived(),
1556   * MQTTAsync_connectionLost() and MQTTAsync_deliveryComplete()).
1557   * In addition, some functions allow success and failure callbacks to be set
1558   * for individual requests, in the ::MQTTAsync_responseOptions structure.  Applications
1559   * can be written as a chain of callback functions. Note that it is a theoretically
1560   * possible but unlikely event, that a success or failure callback could be called
1561   * before function requesting the callback has returned.  In this case the token
1562   * delivered in the callback would not yet be known to the application program (see
1563   * Race condition for MQTTAsync_token in MQTTAsync.c
1564   * https://bugs.eclipse.org/bugs/show_bug.cgi?id=444093)
1565   *
1566   * @page auto_reconnect Automatic Reconnect
1567   * The ability for the client library to reconnect automatically in the event
1568   * of a connection failure was added in 1.1.  The connection lost callback
1569   * allows a flexible response to the loss of a connection, so almost any
1570   * behaviour can be implemented in that way.  Automatic reconnect does have the
1571   * advantage of being a little simpler to use.
1572   *
1573   * To switch on automatic reconnect, the connect options field
1574   * automaticReconnect should be set to non-zero.  The minimum and maximum times
1575   * before the next connection attempt can also be set, the defaults being 1 and
1576   * 60 seconds.  At each failure to reconnect, the retry interval is doubled until
1577   * the maximum value is reached, and there it stays until the connection is
1578   * successfully re-established whereupon it is reset.
1579   *
1580   * When a reconnection attempt is successful, the ::MQTTAsync_connected callback
1581   * function is invoked, if set by calling ::MQTTAsync_setConnected.  This allows
1582   * the application to take any actions needed, such as amending subscriptions.
1583   *
1584   * @page offline_publish Publish While Disconnected
1585   * This feature was not originally available because with persistence enabled,
1586   * messages could be stored locally without ever knowing if they could be sent.
1587   * The client application could have created the client with an erroneous broker
1588   * address or port for instance.
1589   *
1590   * To enable messages to be published when the application is disconnected
1591   * ::MQTTAsync_createWithOptions must be used instead of ::MQTTAsync_create to
1592   * create the client object.  The ::createOptions field sendWhileDisconnected
1593   * must be set to non-zero, and the maxBufferedMessages field set as required -
1594   * the default being 100.
1595   *
1596   * ::MQTTAsync_getPendingTokens can be called to return the ids of the messages
1597   * waiting to be sent, or for which the sending process has not completed.
1598   *
1599   * @page wildcard Subscription wildcards
1600   * Every MQTT message includes a topic that classifies it. MQTT servers use
1601   * topics to determine which subscribers should receive messages published to
1602   * the server.
1603   *
1604   * Consider the server receiving messages from several environmental sensors.
1605   * Each sensor publishes its measurement data as a message with an associated
1606   * topic. Subscribing applications need to know which sensor originally
1607   * published each received message. A unique topic is thus used to identify
1608   * each sensor and measurement type. Topics such as SENSOR1TEMP,
1609   * SENSOR1HUMIDITY, SENSOR2TEMP and so on achieve this but are not very
1610   * flexible. If additional sensors are added to the system at a later date,
1611   * subscribing applications must be modified to receive them.
1612   *
1613   * To provide more flexibility, MQTT supports a hierarchical topic namespace.
1614   * This allows application designers to organize topics to simplify their
1615   * management. Levels in the hierarchy are delimited by the '/' character,
1616   * such as SENSOR/1/HUMIDITY. Publishers and subscribers use these
1617   * hierarchical topics as already described.
1618   *
1619   * For subscriptions, two wildcard characters are supported:
1620   * <ul>
1621   * <li>A '#' character represents a complete sub-tree of the hierarchy and
1622   * thus must be the last character in a subscription topic string, such as
1623   * SENSOR/#. This will match any topic starting with SENSOR/, such as
1624   * SENSOR/1/TEMP and SENSOR/2/HUMIDITY.</li>
1625   * <li> A '+' character represents a single level of the hierarchy and is
1626   * used between delimiters. For example, SENSOR/+/TEMP will match
1627   * SENSOR/1/TEMP and SENSOR/2/TEMP.</li>
1628   * </ul>
1629   * Publishers are not allowed to use the wildcard characters in their topic
1630   * names.
1631   *
1632   * Deciding on your topic hierarchy is an important step in your system design.
1633   *
1634   * @page qos Quality of service
1635   * The MQTT protocol provides three qualities of service for delivering
1636   * messages between clients and servers: "at most once", "at least once" and
1637   * "exactly once".
1638   *
1639   * Quality of service (QoS) is an attribute of an individual message being
1640   * published. An application sets the QoS for a specific message by setting the
1641   * MQTTAsync_message.qos field to the required value.
1642   *
1643   * A subscribing client can set the maximum quality of service a server uses
1644   * to send messages that match the client subscriptions. The
1645   * MQTTAsync_subscribe() and MQTTAsync_subscribeMany() functions set this
1646   * maximum. The QoS of a message forwarded to a subscriber thus might be
1647   * different to the QoS given to the message by the original publisher.
1648   * The lower of the two values is used to forward a message.
1649   *
1650   * The three levels are:
1651   *
1652   * <b>QoS0, At most once:</b> The message is delivered at most once, or it
1653   * may not be delivered at all. Its delivery across the network is not
1654   * acknowledged. The message is not stored. The message could be lost if the
1655   * client is disconnected, or if the server fails. QoS0 is the fastest mode of
1656   * transfer. It is sometimes called "fire and forget".
1657   *
1658   * The MQTT protocol does not require servers to forward publications at QoS0
1659   * to a client. If the client is disconnected at the time the server receives
1660   * the publication, the publication might be discarded, depending on the
1661   * server implementation.
1662   *
1663   * <b>QoS1, At least once:</b> The message is always delivered at least once.
1664   * It might be delivered multiple times if there is a failure before an
1665   * acknowledgment is received by the sender. The message must be stored
1666   * locally at the sender, until the sender receives confirmation that the
1667   * message has been published by the receiver. The message is stored in case
1668   * the message must be sent again.
1669   *
1670   * <b>QoS2, Exactly once:</b> The message is always delivered exactly once.
1671   * The message must be stored locally at the sender, until the sender receives
1672   * confirmation that the message has been published by the receiver. The
1673   * message is stored in case the message must be sent again. QoS2 is the
1674   * safest, but slowest mode of transfer. A more sophisticated handshaking
1675   * and acknowledgement sequence is used than for QoS1 to ensure no duplication
1676   * of messages occurs.
1677 
1678 
1679   * @page publish Publication example
1680 @code
1681 #include <stdio.h>
1682 #include <stdlib.h>
1683 #include <string.h>
1684 #include "MQTTAsync.h"
1685 
1686 #define ADDRESS     "tcp://localhost:1883"
1687 #define CLIENTID    "ExampleClientPub"
1688 #define TOPIC       "MQTT Examples"
1689 #define PAYLOAD     "Hello World!"
1690 #define QOS         1
1691 #define TIMEOUT     10000L
1692 
1693 volatile MQTTAsync_token deliveredtoken;
1694 
1695 int finished = 0;
1696 
1697 void connlost(void *context, char *cause)
1698 {
1699 	MQTTAsync client = (MQTTAsync)context;
1700 	MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
1701 	int rc;
1702 
1703 	printf("\nConnection lost\n");
1704 	printf("     cause: %s\n", cause);
1705 
1706 	printf("Reconnecting\n");
1707 	conn_opts.keepAliveInterval = 20;
1708 	conn_opts.cleansession = 1;
1709 	if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
1710 	{
1711 		printf("Failed to start connect, return code %d\n", rc);
1712  		finished = 1;
1713 	}
1714 }
1715 
1716 
1717 void onDisconnect(void* context, MQTTAsync_successData* response)
1718 {
1719 	printf("Successful disconnection\n");
1720 	finished = 1;
1721 }
1722 
1723 
1724 void onSend(void* context, MQTTAsync_successData* response)
1725 {
1726 	MQTTAsync client = (MQTTAsync)context;
1727 	MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer;
1728 	int rc;
1729 
1730 	printf("Message with token value %d delivery confirmed\n", response->token);
1731 
1732 	opts.onSuccess = onDisconnect;
1733 	opts.context = client;
1734 
1735 	if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS)
1736 	{
1737 		printf("Failed to start sendMessage, return code %d\n", rc);
1738 		exit(EXIT_FAILURE);
1739 	}
1740 }
1741 
1742 
1743 void onConnectFailure(void* context, MQTTAsync_failureData* response)
1744 {
1745 	printf("Connect failed, rc %d\n", response ? response->code : 0);
1746 	finished = 1;
1747 }
1748 
1749 
1750 void onConnect(void* context, MQTTAsync_successData* response)
1751 {
1752 	MQTTAsync client = (MQTTAsync)context;
1753 	MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
1754 	MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
1755 	int rc;
1756 
1757 	printf("Successful connection\n");
1758 
1759 	opts.onSuccess = onSend;
1760 	opts.context = client;
1761 
1762 	pubmsg.payload = PAYLOAD;
1763 	pubmsg.payloadlen = strlen(PAYLOAD);
1764 	pubmsg.qos = QOS;
1765 	pubmsg.retained = 0;
1766 	deliveredtoken = 0;
1767 
1768 	if ((rc = MQTTAsync_sendMessage(client, TOPIC, &pubmsg, &opts)) != MQTTASYNC_SUCCESS)
1769 	{
1770 		printf("Failed to start sendMessage, return code %d\n", rc);
1771 		exit(EXIT_FAILURE);
1772 	}
1773 }
1774 
1775 
1776 int main(int argc, char* argv[])
1777 {
1778 	MQTTAsync client;
1779 	MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
1780 	MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
1781 	MQTTAsync_token token;
1782 	int rc;
1783 
1784 	MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
1785 
1786 	MQTTAsync_setCallbacks(client, NULL, connlost, NULL, NULL);
1787 
1788 	conn_opts.keepAliveInterval = 20;
1789 	conn_opts.cleansession = 1;
1790 	conn_opts.onSuccess = onConnect;
1791 	conn_opts.onFailure = onConnectFailure;
1792 	conn_opts.context = client;
1793 	if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
1794 	{
1795 		printf("Failed to start connect, return code %d\n", rc);
1796 		exit(EXIT_FAILURE);
1797 	}
1798 
1799 	printf("Waiting for publication of %s\n"
1800          "on topic %s for client with ClientID: %s\n",
1801          PAYLOAD, TOPIC, CLIENTID);
1802 	while (!finished)
1803 		#if defined(WIN32) || defined(WIN64)
1804 			Sleep(100);
1805 		#else
1806 			usleep(10000L);
1807 		#endif
1808 
1809 	MQTTAsync_destroy(&client);
1810  	return rc;
1811 }
1812 
1813   * @endcode
1814   * @page subscribe Subscription example
1815 @code
1816 #include <stdio.h>
1817 #include <stdlib.h>
1818 #include <string.h>
1819 #include "MQTTAsync.h"
1820 
1821 #define ADDRESS     "tcp://localhost:1883"
1822 #define CLIENTID    "ExampleClientSub"
1823 #define TOPIC       "MQTT Examples"
1824 #define PAYLOAD     "Hello World!"
1825 #define QOS         1
1826 #define TIMEOUT     10000L
1827 
1828 volatile MQTTAsync_token deliveredtoken;
1829 
1830 int disc_finished = 0;
1831 int subscribed = 0;
1832 int finished = 0;
1833 
1834 void connlost(void *context, char *cause)
1835 {
1836 	MQTTAsync client = (MQTTAsync)context;
1837 	MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
1838 	int rc;
1839 
1840 	printf("\nConnection lost\n");
1841 	printf("     cause: %s\n", cause);
1842 
1843 	printf("Reconnecting\n");
1844 	conn_opts.keepAliveInterval = 20;
1845 	conn_opts.cleansession = 1;
1846 	if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
1847 	{
1848 		printf("Failed to start connect, return code %d\n", rc);
1849 	    finished = 1;
1850 	}
1851 }
1852 
1853 
1854 int msgarrvd(void *context, char *topicName, int topicLen, MQTTAsync_message *message)
1855 {
1856     int i;
1857     char* payloadptr;
1858 
1859     printf("Message arrived\n");
1860     printf("     topic: %s\n", topicName);
1861     printf("   message: ");
1862 
1863     payloadptr = message->payload;
1864     for(i=0; i<message->payloadlen; i++)
1865     {
1866         putchar(*payloadptr++);
1867     }
1868     putchar('\n');
1869     MQTTAsync_freeMessage(&message);
1870     MQTTAsync_free(topicName);
1871     return 1;
1872 }
1873 
1874 
1875 void onDisconnect(void* context, MQTTAsync_successData* response)
1876 {
1877 	printf("Successful disconnection\n");
1878 	disc_finished = 1;
1879 }
1880 
1881 
1882 void onSubscribe(void* context, MQTTAsync_successData* response)
1883 {
1884 	printf("Subscribe succeeded\n");
1885 	subscribed = 1;
1886 }
1887 
1888 void onSubscribeFailure(void* context, MQTTAsync_failureData* response)
1889 {
1890 	printf("Subscribe failed, rc %d\n", response ? response->code : 0);
1891 	finished = 1;
1892 }
1893 
1894 
1895 void onConnectFailure(void* context, MQTTAsync_failureData* response)
1896 {
1897 	printf("Connect failed, rc %d\n", response ? response->code : 0);
1898 	finished = 1;
1899 }
1900 
1901 
1902 void onConnect(void* context, MQTTAsync_successData* response)
1903 {
1904 	MQTTAsync client = (MQTTAsync)context;
1905 	MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
1906 	MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
1907 	int rc;
1908 
1909 	printf("Successful connection\n");
1910 
1911 	printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n"
1912            "Press Q<Enter> to quit\n\n", TOPIC, CLIENTID, QOS);
1913 	opts.onSuccess = onSubscribe;
1914 	opts.onFailure = onSubscribeFailure;
1915 	opts.context = client;
1916 
1917 	deliveredtoken = 0;
1918 
1919 	if ((rc = MQTTAsync_subscribe(client, TOPIC, QOS, &opts)) != MQTTASYNC_SUCCESS)
1920 	{
1921 		printf("Failed to start subscribe, return code %d\n", rc);
1922 		exit(EXIT_FAILURE);
1923 	}
1924 }
1925 
1926 
1927 int main(int argc, char* argv[])
1928 {
1929 	MQTTAsync client;
1930 	MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
1931 	MQTTAsync_disconnectOptions disc_opts = MQTTAsync_disconnectOptions_initializer;
1932 	MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
1933 	MQTTAsync_token token;
1934 	int rc;
1935 	int ch;
1936 
1937 	MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
1938 
1939 	MQTTAsync_setCallbacks(client, NULL, connlost, msgarrvd, NULL);
1940 
1941 	conn_opts.keepAliveInterval = 20;
1942 	conn_opts.cleansession = 1;
1943 	conn_opts.onSuccess = onConnect;
1944 	conn_opts.onFailure = onConnectFailure;
1945 	conn_opts.context = client;
1946 	if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
1947 	{
1948 		printf("Failed to start connect, return code %d\n", rc);
1949 		exit(EXIT_FAILURE);
1950 	}
1951 
1952 	while	(!subscribed)
1953 		#if defined(WIN32) || defined(WIN64)
1954 			Sleep(100);
1955 		#else
1956 			usleep(10000L);
1957 		#endif
1958 
1959 	if (finished)
1960 		goto exit;
1961 
1962 	do
1963 	{
1964 		ch = getchar();
1965 	} while (ch!='Q' && ch != 'q');
1966 
1967 	disc_opts.onSuccess = onDisconnect;
1968 	if ((rc = MQTTAsync_disconnect(client, &disc_opts)) != MQTTASYNC_SUCCESS)
1969 	{
1970 		printf("Failed to start disconnect, return code %d\n", rc);
1971 		exit(EXIT_FAILURE);
1972 	}
1973  	while	(!disc_finished)
1974 		#if defined(WIN32) || defined(WIN64)
1975 			Sleep(100);
1976 		#else
1977 			usleep(10000L);
1978 		#endif
1979 
1980 exit:
1981 	MQTTAsync_destroy(&client);
1982  	return rc;
1983 }
1984 
1985   * @endcode
1986 * @page tracing Tracing
1987   *
1988   * Runtime tracing can be controlled by environment variables or API calls.
1989   *
1990   * #### Environment variables
1991   *
1992   * Tracing is switched on by setting the MQTT_C_CLIENT_TRACE environment variable.
1993   * A value of ON, or stdout, prints to stdout, any other value is interpreted as a file name to use.
1994   *
1995   * The amount of trace detail is controlled with the MQTT_C_CLIENT_TRACE_LEVEL environment
1996   * variable - valid values are ERROR, PROTOCOL, MINIMUM, MEDIUM and MAXIMUM
1997   * (from least to most verbose).
1998   *
1999   * The variable MQTT_C_CLIENT_TRACE_MAX_LINES limits the number of lines of trace that are output
2000   * to a file.  Two files are used at most, when they are full, the last one is overwritten with the
2001   * new trace entries.  The default size is 1000 lines.
2002   *
2003   * #### Trace API calls
2004   *
2005   * MQTTAsync_traceCallback() is used to set a callback function which is called whenever trace
2006   * information is available.  This will be the same information as that printed if the
2007   * environment variables were used to control the trace.
2008   *
2009   * The MQTTAsync_setTraceLevel() calls is used to set the maximum level of trace entries that will be
2010   * passed to the callback function.  The levels are:
2011   * 1. ::MQTTASYNC_TRACE_MAXIMUM
2012   * 2. ::MQTTASYNC_TRACE_MEDIUM
2013   * 3. ::MQTTASYNC_TRACE_MINIMUM
2014   * 4. ::MQTTASYNC_TRACE_PROTOCOL
2015   * 5. ::MQTTASYNC_TRACE_ERROR
2016   * 6. ::MQTTASYNC_TRACE_SEVERE
2017   * 7. ::MQTTASYNC_TRACE_FATAL
2018   *
2019   * Selecting ::MQTTASYNC_TRACE_MAXIMUM will cause all trace entries at all levels to be returned.
2020   * Choosing ::MQTTASYNC_TRACE_ERROR will cause ERROR, SEVERE and FATAL trace entries to be returned
2021   * to the callback function.
2022   *
2023   * ### MQTT Packet Tracing
2024   *
2025   * A feature that can be very useful is printing the MQTT packets that are sent and received.  To
2026   * achieve this, use the following environment variable settings:
2027   * @code
2028     MQTT_C_CLIENT_TRACE=ON
2029     MQTT_C_CLIENT_TRACE_LEVEL=PROTOCOL
2030   * @endcode
2031   * The output you should see looks like this:
2032   * @code
2033     20130528 155936.813 3 stdout-subscriber -> CONNECT cleansession: 1 (0)
2034     20130528 155936.813 3 stdout-subscriber <- CONNACK rc: 0
2035     20130528 155936.813 3 stdout-subscriber -> SUBSCRIBE msgid: 1 (0)
2036     20130528 155936.813 3 stdout-subscriber <- SUBACK msgid: 1
2037     20130528 155941.818 3 stdout-subscriber -> DISCONNECT (0)
2038   * @endcode
2039   * where the fields are:
2040   * 1. date
2041   * 2. time
2042   * 3. socket number
2043   * 4. client id
2044   * 5. direction (-> from client to server, <- from server to client)
2045   * 6. packet details
2046   *
2047   * ### Default Level Tracing
2048   *
2049   * This is an extract of a default level trace of a call to connect:
2050   * @code
2051     19700101 010000.000 (1152206656) (0)> MQTTClient_connect:893
2052     19700101 010000.000 (1152206656)  (1)> MQTTClient_connectURI:716
2053     20130528 160447.479 Connecting to serverURI localhost:1883
2054     20130528 160447.479 (1152206656)   (2)> MQTTProtocol_connect:98
2055     20130528 160447.479 (1152206656)    (3)> MQTTProtocol_addressPort:48
2056     20130528 160447.479 (1152206656)    (3)< MQTTProtocol_addressPort:73
2057     20130528 160447.479 (1152206656)    (3)> Socket_new:599
2058     20130528 160447.479 New socket 4 for localhost, port 1883
2059     20130528 160447.479 (1152206656)     (4)> Socket_addSocket:163
2060     20130528 160447.479 (1152206656)      (5)> Socket_setnonblocking:73
2061     20130528 160447.479 (1152206656)      (5)< Socket_setnonblocking:78 (0)
2062     20130528 160447.479 (1152206656)     (4)< Socket_addSocket:176 (0)
2063     20130528 160447.479 (1152206656)     (4)> Socket_error:95
2064     20130528 160447.479 (1152206656)     (4)< Socket_error:104 (115)
2065     20130528 160447.479 Connect pending
2066     20130528 160447.479 (1152206656)    (3)< Socket_new:683 (115)
2067     20130528 160447.479 (1152206656)   (2)< MQTTProtocol_connect:131 (115)
2068   * @endcode
2069   * where the fields are:
2070   * 1. date
2071   * 2. time
2072   * 3. thread id
2073   * 4. function nesting level
2074   * 5. function entry (>) or exit (<)
2075   * 6. function name : line of source code file
2076   * 7. return value (if there is one)
2077   *
2078   * ### Memory Allocation Tracing
2079   *
2080   * Setting the trace level to maximum causes memory allocations and frees to be traced along with
2081   * the default trace entries, with messages like the following:
2082   * @code
2083     20130528 161819.657 Allocating 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 177 ptr 0x179f930
2084 
2085     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
2086   * @endcode
2087   * When the last MQTT client object is destroyed, if the trace is being recorded
2088   * and all memory allocated by the client library has not been freed, an error message will be
2089   * written to the trace.  This can help with fixing memory leaks.  The message will look like this:
2090   * @code
2091     20130528 163909.208 Some memory not freed at shutdown, possible memory leak
2092     20130528 163909.208 Heap scan start, total 880 bytes
2093     20130528 163909.208 Heap element size 32, line 354, file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c, ptr 0x260cb00
2094     20130528 163909.208   Content
2095     20130528 163909.209 Heap scan end
2096   * @endcode
2097   * @endcond
2098   */
2099 
2100 #ifdef __cplusplus
2101      }
2102 #endif
2103 
2104 #endif
2105