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