MQTTAsync.h 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717
  1. /*******************************************************************************
  2. * Copyright (c) 2009, 2017 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. *******************************************************************************/
  24. /********************************************************************/
  25. /**
  26. * @cond MQTTAsync_main
  27. * @mainpage Asynchronous MQTT client library for C
  28. *
  29. * © Copyright IBM Corp. 2009, 2017
  30. *
  31. * @brief An Asynchronous MQTT client library for C.
  32. *
  33. * An MQTT client application connects to MQTT-capable servers.
  34. * A typical client is responsible for collecting information from a telemetry
  35. * device and publishing the information to the server. It can also subscribe
  36. * to topics, receive messages, and use this information to control the
  37. * telemetry device.
  38. *
  39. * MQTT clients implement the published MQTT v3 protocol. You can write your own
  40. * API to the MQTT protocol using the programming language and platform of your
  41. * choice. This can be time-consuming and error-prone.
  42. *
  43. * To simplify writing MQTT client applications, this library encapsulates
  44. * the MQTT v3 protocol for you. Using this library enables a fully functional
  45. * MQTT client application to be written in a few lines of code.
  46. * The information presented here documents the API provided
  47. * by the Asynchronous MQTT Client library for C.
  48. *
  49. * <b>Using the client</b><br>
  50. * Applications that use the client library typically use a similar structure:
  51. * <ul>
  52. * <li>Create a client object</li>
  53. * <li>Set the options to connect to an MQTT server</li>
  54. * <li>Set up callback functions</li>
  55. * <li>Connect the client to an MQTT server</li>
  56. * <li>Subscribe to any topics the client needs to receive</li>
  57. * <li>Repeat until finished:</li>
  58. * <ul>
  59. * <li>Publish any messages the client needs to</li>
  60. * <li>Handle any incoming messages</li>
  61. * </ul>
  62. * <li>Disconnect the client</li>
  63. * <li>Free any memory being used by the client</li>
  64. * </ul>
  65. * Some simple examples are shown here:
  66. * <ul>
  67. * <li>@ref publish</li>
  68. * <li>@ref subscribe</li>
  69. * </ul>
  70. * Additional information about important concepts is provided here:
  71. * <ul>
  72. * <li>@ref async</li>
  73. * <li>@ref wildcard</li>
  74. * <li>@ref qos</li>
  75. * <li>@ref tracing</li>
  76. * <li>@ref auto_reconnect</li>
  77. * <li>@ref offline_publish</li>
  78. * </ul>
  79. * @endcond
  80. */
  81. /*
  82. /// @cond EXCLUDE
  83. */
  84. #if defined(__cplusplus)
  85. extern "C" {
  86. #endif
  87. #if !defined(MQTTASYNC_H)
  88. #define MQTTASYNC_H
  89. #if defined(WIN32) || defined(WIN64)
  90. #define DLLImport __declspec(dllimport)
  91. #define DLLExport __declspec(dllexport)
  92. #else
  93. #define DLLImport extern
  94. #define DLLExport __attribute__ ((visibility ("default")))
  95. #endif
  96. #include <stdio.h>
  97. /*
  98. /// @endcond
  99. */
  100. #if !defined(NO_PERSISTENCE)
  101. #include "MQTTClientPersistence.h"
  102. #endif
  103. /**
  104. * Return code: No error. Indicates successful completion of an MQTT client
  105. * operation.
  106. */
  107. #define MQTTASYNC_SUCCESS 0
  108. /**
  109. * Return code: A generic error code indicating the failure of an MQTT client
  110. * operation.
  111. */
  112. #define MQTTASYNC_FAILURE -1
  113. /* error code -2 is MQTTAsync_PERSISTENCE_ERROR */
  114. #define MQTTASYNC_PERSISTENCE_ERROR -2
  115. /**
  116. * Return code: The client is disconnected.
  117. */
  118. #define MQTTASYNC_DISCONNECTED -3
  119. /**
  120. * Return code: The maximum number of messages allowed to be simultaneously
  121. * in-flight has been reached.
  122. */
  123. #define MQTTASYNC_MAX_MESSAGES_INFLIGHT -4
  124. /**
  125. * Return code: An invalid UTF-8 string has been detected.
  126. */
  127. #define MQTTASYNC_BAD_UTF8_STRING -5
  128. /**
  129. * Return code: A NULL parameter has been supplied when this is invalid.
  130. */
  131. #define MQTTASYNC_NULL_PARAMETER -6
  132. /**
  133. * Return code: The topic has been truncated (the topic string includes
  134. * embedded NULL characters). String functions will not access the full topic.
  135. * Use the topic length value to access the full topic.
  136. */
  137. #define MQTTASYNC_TOPICNAME_TRUNCATED -7
  138. /**
  139. * Return code: A structure parameter does not have the correct eyecatcher
  140. * and version number.
  141. */
  142. #define MQTTASYNC_BAD_STRUCTURE -8
  143. /**
  144. * Return code: A qos parameter is not 0, 1 or 2
  145. */
  146. #define MQTTASYNC_BAD_QOS -9
  147. /**
  148. * Return code: All 65535 MQTT msgids are being used
  149. */
  150. #define MQTTASYNC_NO_MORE_MSGIDS -10
  151. /**
  152. * Return code: the request is being discarded when not complete
  153. */
  154. #define MQTTASYNC_OPERATION_INCOMPLETE -11
  155. /**
  156. * Return code: no more messages can be buffered
  157. */
  158. #define MQTTASYNC_MAX_BUFFERED_MESSAGES -12
  159. /**
  160. * Return code: Attempting SSL connection using non-SSL version of library
  161. */
  162. #define MQTTASYNC_SSL_NOT_SUPPORTED -13
  163. /**
  164. * Default MQTT version to connect with. Use 3.1.1 then fall back to 3.1
  165. */
  166. #define MQTTVERSION_DEFAULT 0
  167. /**
  168. * MQTT version to connect with: 3.1
  169. */
  170. #define MQTTVERSION_3_1 3
  171. /**
  172. * MQTT version to connect with: 3.1.1
  173. */
  174. #define MQTTVERSION_3_1_1 4
  175. /**
  176. * Bad return code from subscribe, as defined in the 3.1.1 specification
  177. */
  178. #define MQTT_BAD_SUBSCRIBE 0x80
  179. /**
  180. * Initialization options
  181. */
  182. typedef struct
  183. {
  184. /** The eyecatcher for this structure. Must be MQTG. */
  185. char struct_id[4];
  186. /** The version number of this structure. Must be 0 */
  187. int struct_version;
  188. /** 1 = we do openssl init, 0 = leave it to the application */
  189. int do_openssl_init;
  190. } MQTTAsync_init_options;
  191. #define MQTTAsync_init_options_initializer { {'M', 'Q', 'T', 'G'}, 0, 0 }
  192. /**
  193. * Global init of mqtt library. Call once on program start to set global behaviour.
  194. * handle_openssl_init - if mqtt library should handle openssl init (1) or rely on the caller to init it before using mqtt (0)
  195. */
  196. DLLExport void MQTTAsync_global_init(MQTTAsync_init_options* inits);
  197. /**
  198. * A handle representing an MQTT client. A valid client handle is available
  199. * following a successful call to MQTTAsync_create().
  200. */
  201. typedef void* MQTTAsync;
  202. /**
  203. * A value representing an MQTT message. A token is returned to the
  204. * client application when a message is published. The token can then be used to
  205. * check that the message was successfully delivered to its destination (see
  206. * MQTTAsync_publish(),
  207. * MQTTAsync_publishMessage(),
  208. * MQTTAsync_deliveryComplete(), and
  209. * MQTTAsync_getPendingTokens()).
  210. */
  211. typedef int MQTTAsync_token;
  212. /**
  213. * A structure representing the payload and attributes of an MQTT message. The
  214. * message topic is not part of this structure (see MQTTAsync_publishMessage(),
  215. * MQTTAsync_publish(), MQTTAsync_receive(), MQTTAsync_freeMessage()
  216. * and MQTTAsync_messageArrived()).
  217. */
  218. typedef struct
  219. {
  220. /** The eyecatcher for this structure. must be MQTM. */
  221. char struct_id[4];
  222. /** The version number of this structure. Must be 0 */
  223. int struct_version;
  224. /** The length of the MQTT message payload in bytes. */
  225. int payloadlen;
  226. /** A pointer to the payload of the MQTT message. */
  227. void* payload;
  228. /**
  229. * The quality of service (QoS) assigned to the message.
  230. * There are three levels of QoS:
  231. * <DL>
  232. * <DT><B>QoS0</B></DT>
  233. * <DD>Fire and forget - the message may not be delivered</DD>
  234. * <DT><B>QoS1</B></DT>
  235. * <DD>At least once - the message will be delivered, but may be
  236. * delivered more than once in some circumstances.</DD>
  237. * <DT><B>QoS2</B></DT>
  238. * <DD>Once and one only - the message will be delivered exactly once.</DD>
  239. * </DL>
  240. */
  241. int qos;
  242. /**
  243. * The retained flag serves two purposes depending on whether the message
  244. * it is associated with is being published or received.
  245. *
  246. * <b>retained = true</b><br>
  247. * For messages being published, a true setting indicates that the MQTT
  248. * server should retain a copy of the message. The message will then be
  249. * transmitted to new subscribers to a topic that matches the message topic.
  250. * For subscribers registering a new subscription, the flag being true
  251. * indicates that the received message is not a new one, but one that has
  252. * been retained by the MQTT server.
  253. *
  254. * <b>retained = false</b> <br>
  255. * For publishers, this ndicates that this message should not be retained
  256. * by the MQTT server. For subscribers, a false setting indicates this is
  257. * a normal message, received as a result of it being published to the
  258. * server.
  259. */
  260. int retained;
  261. /**
  262. * The dup flag indicates whether or not this message is a duplicate.
  263. * It is only meaningful when receiving QoS1 messages. When true, the
  264. * client application should take appropriate action to deal with the
  265. * duplicate message.
  266. */
  267. int dup;
  268. /** The message identifier is normally reserved for internal use by the
  269. * MQTT client and server.
  270. */
  271. int msgid;
  272. } MQTTAsync_message;
  273. #define MQTTAsync_message_initializer { {'M', 'Q', 'T', 'M'}, 0, 0, NULL, 0, 0, 0, 0 }
  274. /**
  275. * This is a callback function. The client application
  276. * must provide an implementation of this function to enable asynchronous
  277. * receipt of messages. The function is registered with the client library by
  278. * passing it as an argument to MQTTAsync_setCallbacks(). It is
  279. * called by the client library when a new message that matches a client
  280. * subscription has been received from the server. This function is executed on
  281. * a separate thread to the one on which the client application is running.
  282. * @param context A pointer to the <i>context</i> value originally passed to
  283. * MQTTAsync_setCallbacks(), which contains any application-specific context.
  284. * @param topicName The topic associated with the received message.
  285. * @param topicLen The length of the topic if there are one
  286. * more NULL characters embedded in <i>topicName</i>, otherwise <i>topicLen</i>
  287. * is 0. If <i>topicLen</i> is 0, the value returned by <i>strlen(topicName)</i>
  288. * can be trusted. If <i>topicLen</i> is greater than 0, the full topic name
  289. * can be retrieved by accessing <i>topicName</i> as a byte array of length
  290. * <i>topicLen</i>.
  291. * @param message The MQTTAsync_message structure for the received message.
  292. * This structure contains the message payload and attributes.
  293. * @return This function must return a boolean value indicating whether or not
  294. * the message has been safely received by the client application. Returning
  295. * true indicates that the message has been successfully handled.
  296. * Returning false indicates that there was a problem. In this
  297. * case, the client library will reinvoke MQTTAsync_messageArrived() to
  298. * attempt to deliver the message to the application again.
  299. */
  300. typedef int MQTTAsync_messageArrived(void* context, char* topicName, int topicLen, MQTTAsync_message* message);
  301. /**
  302. * This is a callback function. The client application
  303. * must provide an implementation of this function to enable asynchronous
  304. * notification of delivery of messages to the server. The function is
  305. * registered with the client library by passing it as an argument to MQTTAsync_setCallbacks().
  306. * It is called by the client library after the client application has
  307. * published a message to the server. It indicates that the necessary
  308. * handshaking and acknowledgements for the requested quality of service (see
  309. * MQTTAsync_message.qos) have been completed. This function is executed on a
  310. * separate thread to the one on which the client application is running.
  311. * @param context A pointer to the <i>context</i> value originally passed to
  312. * MQTTAsync_setCallbacks(), which contains any application-specific context.
  313. * @param token The ::MQTTAsync_token associated with
  314. * the published message. Applications can check that all messages have been
  315. * correctly published by matching the tokens returned from calls to
  316. * MQTTAsync_send() and MQTTAsync_sendMessage() with the tokens passed
  317. * to this callback.
  318. */
  319. typedef void MQTTAsync_deliveryComplete(void* context, MQTTAsync_token token);
  320. /**
  321. * This is a callback function. The client application
  322. * must provide an implementation of this function to enable asynchronous
  323. * notification of the loss of connection to the server. The function is
  324. * registered with the client library by passing it as an argument to
  325. * MQTTAsync_setCallbacks(). It is called by the client library if the client
  326. * loses its connection to the server. The client application must take
  327. * appropriate action, such as trying to reconnect or reporting the problem.
  328. * This function is executed on a separate thread to the one on which the
  329. * 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 cause The reason for the disconnection.
  333. * Currently, <i>cause</i> is always set to NULL.
  334. */
  335. typedef void MQTTAsync_connectionLost(void* context, char* cause);
  336. /**
  337. * This is a callback function, which will be called when the client
  338. * library successfully connects. This is superfluous when the connection
  339. * is made in response to a MQTTAsync_connect call, because the onSuccess
  340. * callback can be used. It is intended for use when automatic reconnect
  341. * is enabled, so that when a reconnection attempt succeeds in the background,
  342. * the application is notified and can take any required actions.
  343. * @param context A pointer to the <i>context</i> value originally passed to
  344. * MQTTAsync_setCallbacks(), which contains any application-specific context.
  345. * @param cause The reason for the disconnection.
  346. * Currently, <i>cause</i> is always set to NULL.
  347. */
  348. typedef void MQTTAsync_connected(void* context, char* cause);
  349. /** The data returned on completion of an unsuccessful API call in the response callback onFailure. */
  350. typedef struct
  351. {
  352. /** A token identifying the failed request. */
  353. MQTTAsync_token token;
  354. /** A numeric code identifying the error. */
  355. int code;
  356. /** Optional text explaining the error. Can be NULL. */
  357. const char *message;
  358. } MQTTAsync_failureData;
  359. /** The data returned on completion of a successful API call in the response callback onSuccess. */
  360. typedef struct
  361. {
  362. /** A token identifying the successful request. Can be used to refer to the request later. */
  363. MQTTAsync_token token;
  364. /** A union of the different values that can be returned for subscribe, unsubscribe and publish. */
  365. union
  366. {
  367. /** For subscribe, the granted QoS of the subscription returned by the server. */
  368. int qos;
  369. /** For subscribeMany, the list of granted QoSs of the subscriptions returned by the server. */
  370. int* qosList;
  371. /** For publish, the message being sent to the server. */
  372. struct
  373. {
  374. MQTTAsync_message message;
  375. char* destinationName;
  376. } pub;
  377. /* For connect, the server connected to, MQTT version used, and sessionPresent flag */
  378. struct
  379. {
  380. char* serverURI;
  381. int MQTTVersion;
  382. int sessionPresent;
  383. } connect;
  384. } alt;
  385. } MQTTAsync_successData;
  386. /**
  387. * This is a callback function. The client application
  388. * must provide an implementation of this function to enable asynchronous
  389. * notification of the successful completion of an API call. The function is
  390. * registered with the client library by passing it as an argument in
  391. * ::MQTTAsync_responseOptions.
  392. * @param context A pointer to the <i>context</i> value originally passed to
  393. * ::MQTTAsync_responseOptions, which contains any application-specific context.
  394. * @param response Any success data associated with the API completion.
  395. */
  396. typedef void MQTTAsync_onSuccess(void* context, MQTTAsync_successData* response);
  397. /**
  398. * This is a callback function. The client application
  399. * must provide an implementation of this function to enable asynchronous
  400. * notification of the unsuccessful completion of an API call. The function is
  401. * registered with the client library by passing it as an argument in
  402. * ::MQTTAsync_responseOptions.
  403. * @param context A pointer to the <i>context</i> value originally passed to
  404. * ::MQTTAsync_responseOptions, which contains any application-specific context.
  405. * @param response Any failure data associated with the API completion.
  406. */
  407. typedef void MQTTAsync_onFailure(void* context, MQTTAsync_failureData* response);
  408. typedef struct
  409. {
  410. /** The eyecatcher for this structure. Must be MQTR */
  411. char struct_id[4];
  412. /** The version number of this structure. Must be 0 */
  413. int struct_version;
  414. /**
  415. * A pointer to a callback function to be called if the API call successfully
  416. * completes. Can be set to NULL, in which case no indication of successful
  417. * completion will be received.
  418. */
  419. MQTTAsync_onSuccess* onSuccess;
  420. /**
  421. * A pointer to a callback function to be called if the API call fails.
  422. * Can be set to NULL, in which case no indication of unsuccessful
  423. * completion will be received.
  424. */
  425. MQTTAsync_onFailure* onFailure;
  426. /**
  427. * A pointer to any application-specific context. The
  428. * the <i>context</i> pointer is passed to success or failure callback functions to
  429. * provide access to the context information in the callback.
  430. */
  431. void* context;
  432. MQTTAsync_token token; /* output */
  433. } MQTTAsync_responseOptions;
  434. #define MQTTAsync_responseOptions_initializer { {'M', 'Q', 'T', 'R'}, 0, NULL, NULL, 0, 0 }
  435. /**
  436. * This function sets the global callback functions for a specific client.
  437. * If your client application doesn't use a particular callback, set the
  438. * relevant parameter to NULL. Any necessary message acknowledgements and
  439. * status communications are handled in the background without any intervention
  440. * from the client application. If you do not set a messageArrived callback
  441. * function, you will not be notified of the receipt of any messages as a
  442. * result of a subscription.
  443. *
  444. * <b>Note:</b> The MQTT client must be disconnected when this function is
  445. * called.
  446. * @param handle A valid client handle from a successful call to
  447. * MQTTAsync_create().
  448. * @param context A pointer to any application-specific context. The
  449. * the <i>context</i> pointer is passed to each of the callback functions to
  450. * provide access to the context information in the callback.
  451. * @param cl A pointer to an MQTTAsync_connectionLost() callback
  452. * function. You can set this to NULL if your application doesn't handle
  453. * disconnections.
  454. * @param ma A pointer to an MQTTAsync_messageArrived() callback
  455. * function. You can set this to NULL if your application doesn't handle
  456. * receipt of messages.
  457. * @param dc A pointer to an MQTTAsync_deliveryComplete() callback
  458. * function. You can set this to NULL if you do not want to check
  459. * for successful delivery.
  460. * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set,
  461. * ::MQTTASYNC_FAILURE if an error occurred.
  462. */
  463. DLLExport int MQTTAsync_setCallbacks(MQTTAsync handle, void* context, MQTTAsync_connectionLost* cl,
  464. MQTTAsync_messageArrived* ma, MQTTAsync_deliveryComplete* dc);
  465. /**
  466. * Sets the MQTTAsync_connected() callback function for a client.
  467. * @param handle A valid client handle from a successful call to
  468. * MQTTAsync_create().
  469. * @param context A pointer to any application-specific context. The
  470. * the <i>context</i> pointer is passed to each of the callback functions to
  471. * provide access to the context information in the callback.
  472. * @param co A pointer to an MQTTAsync_connected() callback
  473. * function. NULL removes the callback setting.
  474. * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set,
  475. * ::MQTTASYNC_FAILURE if an error occurred.
  476. */
  477. DLLExport int MQTTAsync_setConnected(MQTTAsync handle, void* context, MQTTAsync_connected* co);
  478. /**
  479. * Reconnects a client with the previously used connect options. Connect
  480. * must have previously been called for this to work.
  481. * @param handle A valid client handle from a successful call to
  482. * MQTTAsync_create().
  483. * @return ::MQTTASYNC_SUCCESS if the callbacks were correctly set,
  484. * ::MQTTASYNC_FAILURE if an error occurred.
  485. */
  486. DLLExport int MQTTAsync_reconnect(MQTTAsync handle);
  487. /**
  488. * This function creates an MQTT client ready for connection to the
  489. * specified server and using the specified persistent storage (see
  490. * MQTTAsync_persistence). See also MQTTAsync_destroy().
  491. * @param handle A pointer to an ::MQTTAsync handle. The handle is
  492. * populated with a valid client reference following a successful return from
  493. * this function.
  494. * @param serverURI A null-terminated string specifying the server to
  495. * which the client will connect. It takes the form <i>protocol://host:port</i>.
  496. * <i>protocol</i> must be <i>tcp</i> or <i>ssl</i>. For <i>host</i>, you can
  497. * specify either an IP address or a host name. For instance, to connect to
  498. * a server running on the local machines with the default MQTT port, specify
  499. * <i>tcp://localhost:1883</i>.
  500. * @param clientId The client identifier passed to the server when the
  501. * client connects to it. It is a null-terminated UTF-8 encoded string.
  502. * @param persistence_type The type of persistence to be used by the client:
  503. * <br>
  504. * ::MQTTCLIENT_PERSISTENCE_NONE: Use in-memory persistence. If the device or
  505. * system on which the client is running fails or is switched off, the current
  506. * state of any in-flight messages is lost and some messages may not be
  507. * delivered even at QoS1 and QoS2.
  508. * <br>
  509. * ::MQTTCLIENT_PERSISTENCE_DEFAULT: Use the default (file system-based)
  510. * persistence mechanism. Status about in-flight messages is held in persistent
  511. * storage and provides some protection against message loss in the case of
  512. * unexpected failure.
  513. * <br>
  514. * ::MQTTCLIENT_PERSISTENCE_USER: Use an application-specific persistence
  515. * implementation. Using this type of persistence gives control of the
  516. * persistence mechanism to the application. The application has to implement
  517. * the MQTTClient_persistence interface.
  518. * @param persistence_context If the application uses
  519. * ::MQTTCLIENT_PERSISTENCE_NONE persistence, this argument is unused and should
  520. * be set to NULL. For ::MQTTCLIENT_PERSISTENCE_DEFAULT persistence, it
  521. * should be set to the location of the persistence directory (if set
  522. * to NULL, the persistence directory used is the working directory).
  523. * Applications that use ::MQTTCLIENT_PERSISTENCE_USER persistence set this
  524. * argument to point to a valid MQTTClient_persistence structure.
  525. * @return ::MQTTASYNC_SUCCESS if the client is successfully created, otherwise
  526. * an error code is returned.
  527. */
  528. DLLExport int MQTTAsync_create(MQTTAsync* handle, const char* serverURI, const char* clientId,
  529. int persistence_type, void* persistence_context);
  530. typedef struct
  531. {
  532. /** The eyecatcher for this structure. must be MQCO. */
  533. char struct_id[4];
  534. /** The version number of this structure. Must be 0 */
  535. int struct_version;
  536. /** Whether to allow messages to be sent when the client library is not connected. */
  537. int sendWhileDisconnected;
  538. /** the maximum number of messages allowed to be buffered while not connected. */
  539. int maxBufferedMessages;
  540. } MQTTAsync_createOptions;
  541. #define MQTTAsync_createOptions_initializer { {'M', 'Q', 'C', 'O'}, 0, 0, 100 }
  542. DLLExport int MQTTAsync_createWithOptions(MQTTAsync* handle, const char* serverURI, const char* clientId,
  543. int persistence_type, void* persistence_context, MQTTAsync_createOptions* options);
  544. /**
  545. * MQTTAsync_willOptions defines the MQTT "Last Will and Testament" (LWT) settings for
  546. * the client. In the event that a client unexpectedly loses its connection to
  547. * the server, the server publishes the LWT message to the LWT topic on
  548. * behalf of the client. This allows other clients (subscribed to the LWT topic)
  549. * to be made aware that the client has disconnected. To enable the LWT
  550. * function for a specific client, a valid pointer to an MQTTAsync_willOptions
  551. * structure is passed in the MQTTAsync_connectOptions structure used in the
  552. * MQTTAsync_connect() call that connects the client to the server. The pointer
  553. * to MQTTAsync_willOptions can be set to NULL if the LWT function is not
  554. * required.
  555. */
  556. typedef struct
  557. {
  558. /** The eyecatcher for this structure. must be MQTW. */
  559. char struct_id[4];
  560. /** The version number of this structure. Must be 0 or 1
  561. 0 indicates no binary will message support
  562. */
  563. int struct_version;
  564. /** The LWT topic to which the LWT message will be published. */
  565. const char* topicName;
  566. /** The LWT payload. */
  567. const char* message;
  568. /**
  569. * The retained flag for the LWT message (see MQTTAsync_message.retained).
  570. */
  571. int retained;
  572. /**
  573. * The quality of service setting for the LWT message (see
  574. * MQTTAsync_message.qos and @ref qos).
  575. */
  576. int qos;
  577. /** The LWT payload in binary form. This is only checked and used if the message option is NULL */
  578. struct
  579. {
  580. int len; /**< binary payload length */
  581. const void* data; /**< binary payload data */
  582. } payload;
  583. } MQTTAsync_willOptions;
  584. #define MQTTAsync_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 1, NULL, NULL, 0, 0, { 0, NULL } }
  585. /**
  586. * MQTTAsync_sslProperties defines the settings to establish an SSL/TLS connection using the
  587. * OpenSSL library. It covers the following scenarios:
  588. * - Server authentication: The client needs the digital certificate of the server. It is included
  589. * in a store containting trusted material (also known as "trust store").
  590. * - Mutual authentication: Both client and server are authenticated during the SSL handshake. In
  591. * addition to the digital certificate of the server in a trust store, the client will need its own
  592. * digital certificate and the private key used to sign its digital certificate stored in a "key store".
  593. * - Anonymous connection: Both client and server do not get authenticated and no credentials are needed
  594. * to establish an SSL connection. Note that this scenario is not fully secure since it is subject to
  595. * man-in-the-middle attacks.
  596. */
  597. typedef struct
  598. {
  599. /** The eyecatcher for this structure. Must be MQTS */
  600. char struct_id[4];
  601. /** The version number of this structure. Must be 0 */
  602. int struct_version;
  603. /** The file in PEM format containing the public digital certificates trusted by the client. */
  604. const char* trustStore;
  605. /** The file in PEM format containing the public certificate chain of the client. It may also include
  606. * the client's private key.
  607. */
  608. const char* keyStore;
  609. /** If not included in the sslKeyStore, this setting points to the file in PEM format containing
  610. * the client's private key.
  611. */
  612. const char* privateKey;
  613. /** The password to load the client's privateKey if encrypted. */
  614. const char* privateKeyPassword;
  615. /**
  616. * The list of cipher suites that the client will present to the server during the SSL handshake. For a
  617. * full explanation of the cipher list format, please see the OpenSSL on-line documentation:
  618. * http://www.openssl.org/docs/apps/ciphers.html#CIPHER_LIST_FORMAT
  619. * If this setting is ommitted, its default value will be "ALL", that is, all the cipher suites -excluding
  620. * those offering no encryption- will be considered.
  621. * This setting can be used to set an SSL anonymous connection ("aNULL" string value, for instance).
  622. */
  623. const char* enabledCipherSuites;
  624. /** True/False option to enable verification of the server certificate **/
  625. int enableServerCertAuth;
  626. } MQTTAsync_SSLOptions;
  627. #define MQTTAsync_SSLOptions_initializer { {'M', 'Q', 'T', 'S'}, 0, NULL, NULL, NULL, NULL, NULL, 1 }
  628. /**
  629. * MQTTAsync_connectOptions defines several settings that control the way the
  630. * client connects to an MQTT server. Default values are set in
  631. * MQTTAsync_connectOptions_initializer.
  632. */
  633. typedef struct
  634. {
  635. /** The eyecatcher for this structure. must be MQTC. */
  636. char struct_id[4];
  637. /** The version number of this structure. Must be 0, 1, 2, 3 4 or 5.
  638. * 0 signifies no SSL options and no serverURIs
  639. * 1 signifies no serverURIs
  640. * 2 signifies no MQTTVersion
  641. * 3 signifies no automatic reconnect options
  642. * 4 signifies no binary password option (just string)
  643. */
  644. int struct_version;
  645. /** The "keep alive" interval, measured in seconds, defines the maximum time
  646. * that should pass without communication between the client and the server
  647. * The client will ensure that at least one message travels across the
  648. * network within each keep alive period. In the absence of a data-related
  649. * message during the time period, the client sends a very small MQTT
  650. * "ping" message, which the server will acknowledge. The keep alive
  651. * interval enables the client to detect when the server is no longer
  652. * available without having to wait for the long TCP/IP timeout.
  653. * Set to 0 if you do not want any keep alive processing.
  654. */
  655. int keepAliveInterval;
  656. /**
  657. * This is a boolean value. The cleansession setting controls the behaviour
  658. * of both the client and the server at connection and disconnection time.
  659. * The client and server both maintain session state information. This
  660. * information is used to ensure "at least once" and "exactly once"
  661. * delivery, and "exactly once" receipt of messages. Session state also
  662. * includes subscriptions created by an MQTT client. You can choose to
  663. * maintain or discard state information between sessions.
  664. *
  665. * When cleansession is true, the state information is discarded at
  666. * connect and disconnect. Setting cleansession to false keeps the state
  667. * information. When you connect an MQTT client application with
  668. * MQTTAsync_connect(), the client identifies the connection using the
  669. * client identifier and the address of the server. The server checks
  670. * whether session information for this client
  671. * has been saved from a previous connection to the server. If a previous
  672. * session still exists, and cleansession=true, then the previous session
  673. * information at the client and server is cleared. If cleansession=false,
  674. * the previous session is resumed. If no previous session exists, a new
  675. * session is started.
  676. */
  677. int cleansession;
  678. /**
  679. * This controls how many messages can be in-flight simultaneously.
  680. */
  681. int maxInflight;
  682. /**
  683. * This is a pointer to an MQTTAsync_willOptions structure. If your
  684. * application does not make use of the Last Will and Testament feature,
  685. * set this pointer to NULL.
  686. */
  687. MQTTAsync_willOptions* will;
  688. /**
  689. * MQTT servers that support the MQTT v3.1 protocol provide authentication
  690. * and authorisation by user name and password. This is the user name
  691. * parameter.
  692. */
  693. const char* username;
  694. /**
  695. * MQTT servers that support the MQTT v3.1 protocol provide authentication
  696. * and authorisation by user name and password. This is the password
  697. * parameter.
  698. */
  699. const char* password;
  700. /**
  701. * The time interval in seconds to allow a connect to complete.
  702. */
  703. int connectTimeout;
  704. /**
  705. * The time interval in seconds
  706. */
  707. int retryInterval;
  708. /**
  709. * This is a pointer to an MQTTAsync_SSLOptions structure. If your
  710. * application does not make use of SSL, set this pointer to NULL.
  711. */
  712. MQTTAsync_SSLOptions* ssl;
  713. /**
  714. * A pointer to a callback function to be called if the connect successfully
  715. * completes. Can be set to NULL, in which case no indication of successful
  716. * completion will be received.
  717. */
  718. MQTTAsync_onSuccess* onSuccess;
  719. /**
  720. * A pointer to a callback function to be called if the connect fails.
  721. * Can be set to NULL, in which case no indication of unsuccessful
  722. * completion will be received.
  723. */
  724. MQTTAsync_onFailure* onFailure;
  725. /**
  726. * A pointer to any application-specific context. The
  727. * the <i>context</i> pointer is passed to success or failure callback functions to
  728. * provide access to the context information in the callback.
  729. */
  730. void* context;
  731. /**
  732. * The number of entries in the serverURIs array.
  733. */
  734. int serverURIcount;
  735. /**
  736. * An array of null-terminated strings specifying the servers to
  737. * which the client will connect. Each string takes the form <i>protocol://host:port</i>.
  738. * <i>protocol</i> must be <i>tcp</i> or <i>ssl</i>. For <i>host</i>, you can
  739. * specify either an IP address or a domain name. For instance, to connect to
  740. * a server running on the local machines with the default MQTT port, specify
  741. * <i>tcp://localhost:1883</i>.
  742. */
  743. char* const* serverURIs;
  744. /**
  745. * Sets the version of MQTT to be used on the connect.
  746. * MQTTVERSION_DEFAULT (0) = default: start with 3.1.1, and if that fails, fall back to 3.1
  747. * MQTTVERSION_3_1 (3) = only try version 3.1
  748. * MQTTVERSION_3_1_1 (4) = only try version 3.1.1
  749. */
  750. int MQTTVersion;
  751. /**
  752. * Reconnect automatically in the case of a connection being lost?
  753. */
  754. int automaticReconnect;
  755. /**
  756. * Minimum retry interval in seconds. Doubled on each failed retry.
  757. */
  758. int minRetryInterval;
  759. /**
  760. * Maximum retry interval in seconds. The doubling stops here on failed retries.
  761. */
  762. int maxRetryInterval;
  763. /**
  764. * Optional binary password. Only checked and used if the password option is NULL
  765. */
  766. struct {
  767. int len; /**< binary password length */
  768. const void* data; /**< binary password data */
  769. } binarypwd;
  770. } MQTTAsync_connectOptions;
  771. #define MQTTAsync_connectOptions_initializer { {'M', 'Q', 'T', 'C'}, 5, 60, 1, 10, NULL, NULL, NULL, 30, 0,\
  772. NULL, NULL, NULL, NULL, 0, NULL, 0, 0, 1, 60, {0, NULL}}
  773. /**
  774. * This function attempts to connect a previously-created client (see
  775. * MQTTAsync_create()) to an MQTT server using the specified options. If you
  776. * want to enable asynchronous message and status notifications, you must call
  777. * MQTTAsync_setCallbacks() prior to MQTTAsync_connect().
  778. * @param handle A valid client handle from a successful call to
  779. * MQTTAsync_create().
  780. * @param options A pointer to a valid MQTTAsync_connectOptions
  781. * structure.
  782. * @return ::MQTTASYNC_SUCCESS if the client connect request was accepted.
  783. * If the client was unable to connect to the server, an error code is
  784. * returned via the onFailure callback, if set.
  785. * Error codes greater than 0 are returned by the MQTT protocol:<br><br>
  786. * <b>1</b>: Connection refused: Unacceptable protocol version<br>
  787. * <b>2</b>: Connection refused: Identifier rejected<br>
  788. * <b>3</b>: Connection refused: Server unavailable<br>
  789. * <b>4</b>: Connection refused: Bad user name or password<br>
  790. * <b>5</b>: Connection refused: Not authorized<br>
  791. * <b>6-255</b>: Reserved for future use<br>
  792. */
  793. DLLExport int MQTTAsync_connect(MQTTAsync handle, const MQTTAsync_connectOptions* options);
  794. typedef struct
  795. {
  796. /** The eyecatcher for this structure. Must be MQTD. */
  797. char struct_id[4];
  798. /** The version number of this structure. Must be 0 or 1. 0 signifies no SSL options */
  799. int struct_version;
  800. /**
  801. * The client delays disconnection for up to this time (in
  802. * milliseconds) in order to allow in-flight message transfers to complete.
  803. */
  804. int timeout;
  805. /**
  806. * A pointer to a callback function to be called if the disconnect successfully
  807. * completes. Can be set to NULL, in which case no indication of successful
  808. * completion will be received.
  809. */
  810. MQTTAsync_onSuccess* onSuccess;
  811. /**
  812. * A pointer to a callback function to be called if the disconnect fails.
  813. * Can be set to NULL, in which case no indication of unsuccessful
  814. * completion will be received.
  815. */
  816. MQTTAsync_onFailure* onFailure;
  817. /**
  818. * A pointer to any application-specific context. The
  819. * the <i>context</i> pointer is passed to success or failure callback functions to
  820. * provide access to the context information in the callback.
  821. */
  822. void* context;
  823. } MQTTAsync_disconnectOptions;
  824. #define MQTTAsync_disconnectOptions_initializer { {'M', 'Q', 'T', 'D'}, 0, 0, NULL, NULL, NULL }
  825. /**
  826. * This function attempts to disconnect the client from the MQTT
  827. * server. In order to allow the client time to complete handling of messages
  828. * that are in-flight when this function is called, a timeout period is
  829. * specified. When the timeout period has expired, the client disconnects even
  830. * if there are still outstanding message acknowledgements.
  831. * The next time the client connects to the same server, any QoS 1 or 2
  832. * messages which have not completed will be retried depending on the
  833. * cleansession settings for both the previous and the new connection (see
  834. * MQTTAsync_connectOptions.cleansession and MQTTAsync_connect()).
  835. * @param handle A valid client handle from a successful call to
  836. * MQTTAsync_create().
  837. * @param options The client delays disconnection for up to this time (in
  838. * milliseconds) in order to allow in-flight message transfers to complete.
  839. * @return ::MQTTASYNC_SUCCESS if the client successfully disconnects from
  840. * the server. An error code is returned if the client was unable to disconnect
  841. * from the server
  842. */
  843. DLLExport int MQTTAsync_disconnect(MQTTAsync handle, const MQTTAsync_disconnectOptions* options);
  844. /**
  845. * This function allows the client application to test whether or not a
  846. * client is currently connected to the MQTT server.
  847. * @param handle A valid client handle from a successful call to
  848. * MQTTAsync_create().
  849. * @return Boolean true if the client is connected, otherwise false.
  850. */
  851. DLLExport int MQTTAsync_isConnected(MQTTAsync handle);
  852. /**
  853. * This function attempts to subscribe a client to a single topic, which may
  854. * contain wildcards (see @ref wildcard). This call also specifies the
  855. * @ref qos requested for the subscription
  856. * (see also MQTTAsync_subscribeMany()).
  857. * @param handle A valid client handle from a successful call to
  858. * MQTTAsync_create().
  859. * @param topic The subscription topic, which may include wildcards.
  860. * @param qos The requested quality of service for the subscription.
  861. * @param response A pointer to a response options structure. Used to set callback functions.
  862. * @return ::MQTTASYNC_SUCCESS if the subscription request is successful.
  863. * An error code is returned if there was a problem registering the
  864. * subscription.
  865. */
  866. DLLExport int MQTTAsync_subscribe(MQTTAsync handle, const char* topic, int qos, MQTTAsync_responseOptions* response);
  867. /**
  868. * This function attempts to subscribe a client to a list of topics, which may
  869. * contain wildcards (see @ref wildcard). This call also specifies the
  870. * @ref qos requested for each topic (see also MQTTAsync_subscribe()).
  871. * @param handle A valid client handle from a successful call to
  872. * MQTTAsync_create().
  873. * @param count The number of topics for which the client is requesting
  874. * subscriptions.
  875. * @param topic An array (of length <i>count</i>) of pointers to
  876. * topics, each of which may include wildcards.
  877. * @param qos An array (of length <i>count</i>) of @ref qos
  878. * values. qos[n] is the requested QoS for topic[n].
  879. * @param response A pointer to a response options structure. Used to set callback functions.
  880. * @return ::MQTTASYNC_SUCCESS if the subscription request is successful.
  881. * An error code is returned if there was a problem registering the
  882. * subscriptions.
  883. */
  884. DLLExport int MQTTAsync_subscribeMany(MQTTAsync handle, int count, char* const* topic, int* qos, MQTTAsync_responseOptions* response);
  885. /**
  886. * This function attempts to remove an existing subscription made by the
  887. * specified client.
  888. * @param handle A valid client handle from a successful call to
  889. * MQTTAsync_create().
  890. * @param topic The topic for the subscription to be removed, which may
  891. * include wildcards (see @ref wildcard).
  892. * @param response A pointer to a response options structure. Used to set callback functions.
  893. * @return ::MQTTASYNC_SUCCESS if the subscription is removed.
  894. * An error code is returned if there was a problem removing the
  895. * subscription.
  896. */
  897. DLLExport int MQTTAsync_unsubscribe(MQTTAsync handle, const char* topic, MQTTAsync_responseOptions* response);
  898. /**
  899. * This function attempts to remove existing subscriptions to a list of topics
  900. * made by the specified client.
  901. * @param handle A valid client handle from a successful call to
  902. * MQTTAsync_create().
  903. * @param count The number subscriptions to be removed.
  904. * @param topic An array (of length <i>count</i>) of pointers to the topics of
  905. * the subscriptions to be removed, each of which may include wildcards.
  906. * @param response A pointer to a response options structure. Used to set callback functions.
  907. * @return ::MQTTASYNC_SUCCESS if the subscriptions are removed.
  908. * An error code is returned if there was a problem removing the subscriptions.
  909. */
  910. DLLExport int MQTTAsync_unsubscribeMany(MQTTAsync handle, int count, char* const* topic, MQTTAsync_responseOptions* response);
  911. /**
  912. * This function attempts to publish a message to a given topic (see also
  913. * ::MQTTAsync_sendMessage()). An ::MQTTAsync_token is issued when
  914. * this function returns successfully. If the client application needs to
  915. * test for successful delivery of messages, a callback should be set
  916. * (see ::MQTTAsync_onSuccess() and ::MQTTAsync_deliveryComplete()).
  917. * @param handle A valid client handle from a successful call to
  918. * MQTTAsync_create().
  919. * @param destinationName The topic associated with this message.
  920. * @param payloadlen The length of the payload in bytes.
  921. * @param payload A pointer to the byte array payload of the message.
  922. * @param qos The @ref qos of the message.
  923. * @param retained The retained flag for the message.
  924. * @param response A pointer to an ::MQTTAsync_responseOptions structure. Used to set callback functions.
  925. * This is optional and can be set to NULL.
  926. * @return ::MQTTASYNC_SUCCESS if the message is accepted for publication.
  927. * An error code is returned if there was a problem accepting the message.
  928. */
  929. DLLExport int MQTTAsync_send(MQTTAsync handle, const char* destinationName, int payloadlen, void* payload, int qos, int retained,
  930. MQTTAsync_responseOptions* response);
  931. /**
  932. * This function attempts to publish a message to a given topic (see also
  933. * MQTTAsync_publish()). An ::MQTTAsync_token is issued when
  934. * this function returns successfully. If the client application needs to
  935. * test for successful delivery of messages, a callback should be set
  936. * (see ::MQTTAsync_onSuccess() and ::MQTTAsync_deliveryComplete()).
  937. * @param handle A valid client handle from a successful call to
  938. * MQTTAsync_create().
  939. * @param destinationName The topic associated with this message.
  940. * @param msg A pointer to a valid MQTTAsync_message structure containing
  941. * the payload and attributes of the message to be published.
  942. * @param response A pointer to an ::MQTTAsync_responseOptions structure. Used to set callback functions.
  943. * @return ::MQTTASYNC_SUCCESS if the message is accepted for publication.
  944. * An error code is returned if there was a problem accepting the message.
  945. */
  946. DLLExport int MQTTAsync_sendMessage(MQTTAsync handle, const char* destinationName, const MQTTAsync_message* msg, MQTTAsync_responseOptions* response);
  947. /**
  948. * This function sets a pointer to an array of tokens for
  949. * messages that are currently in-flight (pending completion).
  950. *
  951. * <b>Important note:</b> The memory used to hold the array of tokens is
  952. * malloc()'d in this function. The client application is responsible for
  953. * freeing this memory when it is no longer required.
  954. * @param handle A valid client handle from a successful call to
  955. * MQTTAsync_create().
  956. * @param tokens The address of a pointer to an ::MQTTAsync_token.
  957. * When the function returns successfully, the pointer is set to point to an
  958. * array of tokens representing messages pending completion. The last member of
  959. * the array is set to -1 to indicate there are no more tokens. If no tokens
  960. * are pending, the pointer is set to NULL.
  961. * @return ::MQTTASYNC_SUCCESS if the function returns successfully.
  962. * An error code is returned if there was a problem obtaining the list of
  963. * pending tokens.
  964. */
  965. DLLExport int MQTTAsync_getPendingTokens(MQTTAsync handle, MQTTAsync_token **tokens);
  966. /**
  967. * Tests whether a request corresponding to a token is complete.
  968. *
  969. * @param handle A valid client handle from a successful call to
  970. * MQTTAsync_create().
  971. * @param token An ::MQTTAsync_token associated with a request.
  972. * @return 1 if the request has been completed, 0 if not.
  973. */
  974. #define MQTTASYNC_TRUE 1
  975. DLLExport int MQTTAsync_isComplete(MQTTAsync handle, MQTTAsync_token token);
  976. /**
  977. * Waits for a request corresponding to a token to complete.
  978. *
  979. * @param handle A valid client handle from a successful call to
  980. * MQTTAsync_create().
  981. * @param token An ::MQTTAsync_token associated with a request.
  982. * @param timeout the maximum time to wait for completion, in milliseconds
  983. * @return ::MQTTASYNC_SUCCESS if the request has been completed in the time allocated,
  984. * ::MQTTASYNC_FAILURE if not.
  985. */
  986. DLLExport int MQTTAsync_waitForCompletion(MQTTAsync handle, MQTTAsync_token token, unsigned long timeout);
  987. /**
  988. * This function frees memory allocated to an MQTT message, including the
  989. * additional memory allocated to the message payload. The client application
  990. * calls this function when the message has been fully processed. <b>Important
  991. * note:</b> This function does not free the memory allocated to a message
  992. * topic string. It is the responsibility of the client application to free
  993. * this memory using the MQTTAsync_free() library function.
  994. * @param msg The address of a pointer to the ::MQTTAsync_message structure
  995. * to be freed.
  996. */
  997. DLLExport void MQTTAsync_freeMessage(MQTTAsync_message** msg);
  998. /**
  999. * This function frees memory allocated by the MQTT C client library, especially the
  1000. * topic name. This is needed on Windows when the client libary and application
  1001. * program have been compiled with different versions of the C compiler. It is
  1002. * thus good policy to always use this function when freeing any MQTT C client-
  1003. * allocated memory.
  1004. * @param ptr The pointer to the client library storage to be freed.
  1005. */
  1006. DLLExport void MQTTAsync_free(void* ptr);
  1007. /**
  1008. * This function frees the memory allocated to an MQTT client (see
  1009. * MQTTAsync_create()). It should be called when the client is no longer
  1010. * required.
  1011. * @param handle A pointer to the handle referring to the ::MQTTAsync
  1012. * structure to be freed.
  1013. */
  1014. DLLExport void MQTTAsync_destroy(MQTTAsync* handle);
  1015. enum MQTTASYNC_TRACE_LEVELS
  1016. {
  1017. MQTTASYNC_TRACE_MAXIMUM = 1,
  1018. MQTTASYNC_TRACE_MEDIUM,
  1019. MQTTASYNC_TRACE_MINIMUM,
  1020. MQTTASYNC_TRACE_PROTOCOL,
  1021. MQTTASYNC_TRACE_ERROR,
  1022. MQTTASYNC_TRACE_SEVERE,
  1023. MQTTASYNC_TRACE_FATAL,
  1024. };
  1025. /**
  1026. * This function sets the level of trace information which will be
  1027. * returned in the trace callback.
  1028. * @param level the trace level required
  1029. */
  1030. DLLExport void MQTTAsync_setTraceLevel(enum MQTTASYNC_TRACE_LEVELS level);
  1031. /**
  1032. * This is a callback function prototype which must be implemented if you want
  1033. * to receive trace information.
  1034. * @param level the trace level of the message returned
  1035. * @param meesage the trace message. This is a pointer to a static buffer which
  1036. * will be overwritten on each call. You must copy the data if you want to keep
  1037. * it for later.
  1038. */
  1039. typedef void MQTTAsync_traceCallback(enum MQTTASYNC_TRACE_LEVELS level, char* message);
  1040. /**
  1041. * This function sets the trace callback if needed. If set to NULL,
  1042. * no trace information will be returned. The default trace level is
  1043. * MQTTASYNC_TRACE_MINIMUM.
  1044. * @param callback a pointer to the function which will handle the trace information
  1045. */
  1046. DLLExport void MQTTAsync_setTraceCallback(MQTTAsync_traceCallback* callback);
  1047. typedef struct
  1048. {
  1049. const char* name;
  1050. const char* value;
  1051. } MQTTAsync_nameValue;
  1052. /**
  1053. * This function returns version information about the library.
  1054. * no trace information will be returned. The default trace level is
  1055. * MQTTASYNC_TRACE_MINIMUM
  1056. * @return an array of strings describing the library. The last entry is a NULL pointer.
  1057. */
  1058. DLLExport MQTTAsync_nameValue* MQTTAsync_getVersionInfo(void);
  1059. /**
  1060. * @cond MQTTAsync_main
  1061. * @page async Threading
  1062. * The client application runs on several threads.
  1063. * Processing of handshaking and maintaining
  1064. * the network connection is performed in the background.
  1065. * This API is thread safe: functions may be called by multiple application
  1066. * threads.
  1067. * Notifications of status and message reception are provided to the client
  1068. * application using callbacks registered with the library by the call to
  1069. * MQTTAsync_setCallbacks() (see MQTTAsync_messageArrived(),
  1070. * MQTTAsync_connectionLost() and MQTTAsync_deliveryComplete()).
  1071. * In addition, some functions allow success and failure callbacks to be set
  1072. * for individual requests, in the ::MQTTAsync_responseOptions structure. Applications
  1073. * can be written as a chain of callback functions. Note that it is a theoretically
  1074. * possible but unlikely event, that a success or failure callback could be called
  1075. * before function requesting the callback has returned. In this case the token
  1076. * delivered in the callback would not yet be known to the application program (see
  1077. * Race condition for MQTTAsync_token in MQTTAsync.c
  1078. * https://bugs.eclipse.org/bugs/show_bug.cgi?id=444093)
  1079. *
  1080. * @page auto_reconnect Automatic Reconnect
  1081. * The ability for the client library to reconnect automatically in the event
  1082. * of a connection failure was added in 1.1. The connection lost callback
  1083. * allows a flexible response to the loss of a connection, so almost any
  1084. * behaviour can be implemented in that way. Automatic reconnect does have the
  1085. * advantage of being a little simpler to use.
  1086. *
  1087. * To switch on automatic reconnect, the connect options field
  1088. * automaticReconnect should be set to non-zero. The minimum and maximum times
  1089. * before the next connection attempt can also be set, the defaults being 1 and
  1090. * 60 seconds. At each failure to reconnect, the retry interval is doubled until
  1091. * the maximum value is reached, and there it stays until the connection is
  1092. * successfully re-established whereupon it is reset.
  1093. *
  1094. * When a reconnection attempt is successful, the ::MQTTAsync_connected callback
  1095. * function is invoked, if set by calling ::MQTTAsync_setConnected. This allows
  1096. * the application to take any actions needed, such as amending subscriptions.
  1097. *
  1098. * @page offline_publish Publish While Disconnected
  1099. * This feature was not originally available because with persistence enabled,
  1100. * messages could be stored locally without ever knowing if they could be sent.
  1101. * The client application could have created the client with an erroneous broker
  1102. * address or port for instance.
  1103. *
  1104. * To enable messages to be published when the application is disconnected
  1105. * ::MQTTAsync_createWithOptions must be used instead of ::MQTTAsync_create to
  1106. * create the client object. The ::createOptions field sendWhileDisconnected
  1107. * must be set to non-zero, and the maxBufferedMessages field set as required -
  1108. * the default being 100.
  1109. *
  1110. * ::MQTTAsync_getPendingTokens can be called to return the ids of the messages
  1111. * waiting to be sent, or for which the sending process has not completed.
  1112. *
  1113. * @page wildcard Subscription wildcards
  1114. * Every MQTT message includes a topic that classifies it. MQTT servers use
  1115. * topics to determine which subscribers should receive messages published to
  1116. * the server.
  1117. *
  1118. * Consider the server receiving messages from several environmental sensors.
  1119. * Each sensor publishes its measurement data as a message with an associated
  1120. * topic. Subscribing applications need to know which sensor originally
  1121. * published each received message. A unique topic is thus used to identify
  1122. * each sensor and measurement type. Topics such as SENSOR1TEMP,
  1123. * SENSOR1HUMIDITY, SENSOR2TEMP and so on achieve this but are not very
  1124. * flexible. If additional sensors are added to the system at a later date,
  1125. * subscribing applications must be modified to receive them.
  1126. *
  1127. * To provide more flexibility, MQTT supports a hierarchical topic namespace.
  1128. * This allows application designers to organize topics to simplify their
  1129. * management. Levels in the hierarchy are delimited by the '/' character,
  1130. * such as SENSOR/1/HUMIDITY. Publishers and subscribers use these
  1131. * hierarchical topics as already described.
  1132. *
  1133. * For subscriptions, two wildcard characters are supported:
  1134. * <ul>
  1135. * <li>A '#' character represents a complete sub-tree of the hierarchy and
  1136. * thus must be the last character in a subscription topic string, such as
  1137. * SENSOR/#. This will match any topic starting with SENSOR/, such as
  1138. * SENSOR/1/TEMP and SENSOR/2/HUMIDITY.</li>
  1139. * <li> A '+' character represents a single level of the hierarchy and is
  1140. * used between delimiters. For example, SENSOR/+/TEMP will match
  1141. * SENSOR/1/TEMP and SENSOR/2/TEMP.</li>
  1142. * </ul>
  1143. * Publishers are not allowed to use the wildcard characters in their topic
  1144. * names.
  1145. *
  1146. * Deciding on your topic hierarchy is an important step in your system design.
  1147. *
  1148. * @page qos Quality of service
  1149. * The MQTT protocol provides three qualities of service for delivering
  1150. * messages between clients and servers: "at most once", "at least once" and
  1151. * "exactly once".
  1152. *
  1153. * Quality of service (QoS) is an attribute of an individual message being
  1154. * published. An application sets the QoS for a specific message by setting the
  1155. * MQTTAsync_message.qos field to the required value.
  1156. *
  1157. * A subscribing client can set the maximum quality of service a server uses
  1158. * to send messages that match the client subscriptions. The
  1159. * MQTTAsync_subscribe() and MQTTAsync_subscribeMany() functions set this
  1160. * maximum. The QoS of a message forwarded to a subscriber thus might be
  1161. * different to the QoS given to the message by the original publisher.
  1162. * The lower of the two values is used to forward a message.
  1163. *
  1164. * The three levels are:
  1165. *
  1166. * <b>QoS0, At most once:</b> The message is delivered at most once, or it
  1167. * may not be delivered at all. Its delivery across the network is not
  1168. * acknowledged. The message is not stored. The message could be lost if the
  1169. * client is disconnected, or if the server fails. QoS0 is the fastest mode of
  1170. * transfer. It is sometimes called "fire and forget".
  1171. *
  1172. * The MQTT protocol does not require servers to forward publications at QoS0
  1173. * to a client. If the client is disconnected at the time the server receives
  1174. * the publication, the publication might be discarded, depending on the
  1175. * server implementation.
  1176. *
  1177. * <b>QoS1, At least once:</b> The message is always delivered at least once.
  1178. * It might be delivered multiple times if there is a failure before an
  1179. * acknowledgment is received by the sender. The message must be stored
  1180. * locally at the sender, until the sender receives confirmation that the
  1181. * message has been published by the receiver. The message is stored in case
  1182. * the message must be sent again.
  1183. *
  1184. * <b>QoS2, Exactly once:</b> The message is always delivered exactly once.
  1185. * The message must be stored locally at the sender, until the sender receives
  1186. * confirmation that the message has been published by the receiver. The
  1187. * message is stored in case the message must be sent again. QoS2 is the
  1188. * safest, but slowest mode of transfer. A more sophisticated handshaking
  1189. * and acknowledgement sequence is used than for QoS1 to ensure no duplication
  1190. * of messages occurs.
  1191. * @page publish Publication example
  1192. @code
  1193. #include <stdio.h>
  1194. #include <stdlib.h>
  1195. #include <string.h>
  1196. #include "MQTTAsync.h"
  1197. #define ADDRESS "tcp://localhost:1883"
  1198. #define CLIENTID "ExampleClientPub"
  1199. #define TOPIC "MQTT Examples"
  1200. #define PAYLOAD "Hello World!"
  1201. #define QOS 1
  1202. #define TIMEOUT 10000L
  1203. volatile MQTTAsync_token deliveredtoken;
  1204. int finished = 0;
  1205. void connlost(void *context, char *cause)
  1206. {
  1207. MQTTAsync client = (MQTTAsync)context;
  1208. MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
  1209. int rc;
  1210. printf("\nConnection lost\n");
  1211. printf(" cause: %s\n", cause);
  1212. printf("Reconnecting\n");
  1213. conn_opts.keepAliveInterval = 20;
  1214. conn_opts.cleansession = 1;
  1215. if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
  1216. {
  1217. printf("Failed to start connect, return code %d\n", rc);
  1218. finished = 1;
  1219. }
  1220. }
  1221. void onDisconnect(void* context, MQTTAsync_successData* response)
  1222. {
  1223. printf("Successful disconnection\n");
  1224. finished = 1;
  1225. }
  1226. void onSend(void* context, MQTTAsync_successData* response)
  1227. {
  1228. MQTTAsync client = (MQTTAsync)context;
  1229. MQTTAsync_disconnectOptions opts = MQTTAsync_disconnectOptions_initializer;
  1230. int rc;
  1231. printf("Message with token value %d delivery confirmed\n", response->token);
  1232. opts.onSuccess = onDisconnect;
  1233. opts.context = client;
  1234. if ((rc = MQTTAsync_disconnect(client, &opts)) != MQTTASYNC_SUCCESS)
  1235. {
  1236. printf("Failed to start sendMessage, return code %d\n", rc);
  1237. exit(EXIT_FAILURE);
  1238. }
  1239. }
  1240. void onConnectFailure(void* context, MQTTAsync_failureData* response)
  1241. {
  1242. printf("Connect failed, rc %d\n", response ? response->code : 0);
  1243. finished = 1;
  1244. }
  1245. void onConnect(void* context, MQTTAsync_successData* response)
  1246. {
  1247. MQTTAsync client = (MQTTAsync)context;
  1248. MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
  1249. MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
  1250. int rc;
  1251. printf("Successful connection\n");
  1252. opts.onSuccess = onSend;
  1253. opts.context = client;
  1254. pubmsg.payload = PAYLOAD;
  1255. pubmsg.payloadlen = strlen(PAYLOAD);
  1256. pubmsg.qos = QOS;
  1257. pubmsg.retained = 0;
  1258. deliveredtoken = 0;
  1259. if ((rc = MQTTAsync_sendMessage(client, TOPIC, &pubmsg, &opts)) != MQTTASYNC_SUCCESS)
  1260. {
  1261. printf("Failed to start sendMessage, return code %d\n", rc);
  1262. exit(EXIT_FAILURE);
  1263. }
  1264. }
  1265. int main(int argc, char* argv[])
  1266. {
  1267. MQTTAsync client;
  1268. MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
  1269. MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
  1270. MQTTAsync_token token;
  1271. int rc;
  1272. MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
  1273. MQTTAsync_setCallbacks(client, NULL, connlost, NULL, NULL);
  1274. conn_opts.keepAliveInterval = 20;
  1275. conn_opts.cleansession = 1;
  1276. conn_opts.onSuccess = onConnect;
  1277. conn_opts.onFailure = onConnectFailure;
  1278. conn_opts.context = client;
  1279. if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
  1280. {
  1281. printf("Failed to start connect, return code %d\n", rc);
  1282. exit(EXIT_FAILURE);
  1283. }
  1284. printf("Waiting for publication of %s\n"
  1285. "on topic %s for client with ClientID: %s\n",
  1286. PAYLOAD, TOPIC, CLIENTID);
  1287. while (!finished)
  1288. #if defined(WIN32) || defined(WIN64)
  1289. Sleep(100);
  1290. #else
  1291. usleep(10000L);
  1292. #endif
  1293. MQTTAsync_destroy(&client);
  1294. return rc;
  1295. }
  1296. * @endcode
  1297. * @page subscribe Subscription example
  1298. @code
  1299. #include <stdio.h>
  1300. #include <stdlib.h>
  1301. #include <string.h>
  1302. #include "MQTTAsync.h"
  1303. #define ADDRESS "tcp://localhost:1883"
  1304. #define CLIENTID "ExampleClientSub"
  1305. #define TOPIC "MQTT Examples"
  1306. #define PAYLOAD "Hello World!"
  1307. #define QOS 1
  1308. #define TIMEOUT 10000L
  1309. volatile MQTTAsync_token deliveredtoken;
  1310. int disc_finished = 0;
  1311. int subscribed = 0;
  1312. int finished = 0;
  1313. void connlost(void *context, char *cause)
  1314. {
  1315. MQTTAsync client = (MQTTAsync)context;
  1316. MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
  1317. int rc;
  1318. printf("\nConnection lost\n");
  1319. printf(" cause: %s\n", cause);
  1320. printf("Reconnecting\n");
  1321. conn_opts.keepAliveInterval = 20;
  1322. conn_opts.cleansession = 1;
  1323. if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
  1324. {
  1325. printf("Failed to start connect, return code %d\n", rc);
  1326. finished = 1;
  1327. }
  1328. }
  1329. int msgarrvd(void *context, char *topicName, int topicLen, MQTTAsync_message *message)
  1330. {
  1331. int i;
  1332. char* payloadptr;
  1333. printf("Message arrived\n");
  1334. printf(" topic: %s\n", topicName);
  1335. printf(" message: ");
  1336. payloadptr = message->payload;
  1337. for(i=0; i<message->payloadlen; i++)
  1338. {
  1339. putchar(*payloadptr++);
  1340. }
  1341. putchar('\n');
  1342. MQTTAsync_freeMessage(&message);
  1343. MQTTAsync_free(topicName);
  1344. return 1;
  1345. }
  1346. void onDisconnect(void* context, MQTTAsync_successData* response)
  1347. {
  1348. printf("Successful disconnection\n");
  1349. disc_finished = 1;
  1350. }
  1351. void onSubscribe(void* context, MQTTAsync_successData* response)
  1352. {
  1353. printf("Subscribe succeeded\n");
  1354. subscribed = 1;
  1355. }
  1356. void onSubscribeFailure(void* context, MQTTAsync_failureData* response)
  1357. {
  1358. printf("Subscribe failed, rc %d\n", response ? response->code : 0);
  1359. finished = 1;
  1360. }
  1361. void onConnectFailure(void* context, MQTTAsync_failureData* response)
  1362. {
  1363. printf("Connect failed, rc %d\n", response ? response->code : 0);
  1364. finished = 1;
  1365. }
  1366. void onConnect(void* context, MQTTAsync_successData* response)
  1367. {
  1368. MQTTAsync client = (MQTTAsync)context;
  1369. MQTTAsync_responseOptions opts = MQTTAsync_responseOptions_initializer;
  1370. MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
  1371. int rc;
  1372. printf("Successful connection\n");
  1373. printf("Subscribing to topic %s\nfor client %s using QoS%d\n\n"
  1374. "Press Q<Enter> to quit\n\n", TOPIC, CLIENTID, QOS);
  1375. opts.onSuccess = onSubscribe;
  1376. opts.onFailure = onSubscribeFailure;
  1377. opts.context = client;
  1378. deliveredtoken = 0;
  1379. if ((rc = MQTTAsync_subscribe(client, TOPIC, QOS, &opts)) != MQTTASYNC_SUCCESS)
  1380. {
  1381. printf("Failed to start subscribe, return code %d\n", rc);
  1382. exit(EXIT_FAILURE);
  1383. }
  1384. }
  1385. int main(int argc, char* argv[])
  1386. {
  1387. MQTTAsync client;
  1388. MQTTAsync_connectOptions conn_opts = MQTTAsync_connectOptions_initializer;
  1389. MQTTAsync_disconnectOptions disc_opts = MQTTAsync_disconnectOptions_initializer;
  1390. MQTTAsync_message pubmsg = MQTTAsync_message_initializer;
  1391. MQTTAsync_token token;
  1392. int rc;
  1393. int ch;
  1394. MQTTAsync_create(&client, ADDRESS, CLIENTID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
  1395. MQTTAsync_setCallbacks(client, NULL, connlost, msgarrvd, NULL);
  1396. conn_opts.keepAliveInterval = 20;
  1397. conn_opts.cleansession = 1;
  1398. conn_opts.onSuccess = onConnect;
  1399. conn_opts.onFailure = onConnectFailure;
  1400. conn_opts.context = client;
  1401. if ((rc = MQTTAsync_connect(client, &conn_opts)) != MQTTASYNC_SUCCESS)
  1402. {
  1403. printf("Failed to start connect, return code %d\n", rc);
  1404. exit(EXIT_FAILURE);
  1405. }
  1406. while (!subscribed)
  1407. #if defined(WIN32) || defined(WIN64)
  1408. Sleep(100);
  1409. #else
  1410. usleep(10000L);
  1411. #endif
  1412. if (finished)
  1413. goto exit;
  1414. do
  1415. {
  1416. ch = getchar();
  1417. } while (ch!='Q' && ch != 'q');
  1418. disc_opts.onSuccess = onDisconnect;
  1419. if ((rc = MQTTAsync_disconnect(client, &disc_opts)) != MQTTASYNC_SUCCESS)
  1420. {
  1421. printf("Failed to start disconnect, return code %d\n", rc);
  1422. exit(EXIT_FAILURE);
  1423. }
  1424. while (!disc_finished)
  1425. #if defined(WIN32) || defined(WIN64)
  1426. Sleep(100);
  1427. #else
  1428. usleep(10000L);
  1429. #endif
  1430. exit:
  1431. MQTTAsync_destroy(&client);
  1432. return rc;
  1433. }
  1434. * @endcode
  1435. * @page tracing Tracing
  1436. *
  1437. * Runtime tracing can be controlled by environment variables or API calls.
  1438. *
  1439. * #### Environment variables
  1440. *
  1441. * Tracing is switched on by setting the MQTT_C_CLIENT_TRACE environment variable.
  1442. * A value of ON, or stdout, prints to stdout, any other value is interpreted as a file name to use.
  1443. *
  1444. * The amount of trace detail is controlled with the MQTT_C_CLIENT_TRACE_LEVEL environment
  1445. * variable - valid values are ERROR, PROTOCOL, MINIMUM, MEDIUM and MAXIMUM
  1446. * (from least to most verbose).
  1447. *
  1448. * The variable MQTT_C_CLIENT_TRACE_MAX_LINES limits the number of lines of trace that are output
  1449. * to a file. Two files are used at most, when they are full, the last one is overwritten with the
  1450. * new trace entries. The default size is 1000 lines.
  1451. *
  1452. * #### Trace API calls
  1453. *
  1454. * MQTTAsync_traceCallback() is used to set a callback function which is called whenever trace
  1455. * information is available. This will be the same information as that printed if the
  1456. * environment variables were used to control the trace.
  1457. *
  1458. * The MQTTAsync_setTraceLevel() calls is used to set the maximum level of trace entries that will be
  1459. * passed to the callback function. The levels are:
  1460. * 1. ::MQTTASYNC_TRACE_MAXIMUM
  1461. * 2. ::MQTTASYNC_TRACE_MEDIUM
  1462. * 3. ::MQTTASYNC_TRACE_MINIMUM
  1463. * 4. ::MQTTASYNC_TRACE_PROTOCOL
  1464. * 5. ::MQTTASYNC_TRACE_ERROR
  1465. * 6. ::MQTTASYNC_TRACE_SEVERE
  1466. * 7. ::MQTTASYNC_TRACE_FATAL
  1467. *
  1468. * Selecting ::MQTTASYNC_TRACE_MAXIMUM will cause all trace entries at all levels to be returned.
  1469. * Choosing ::MQTTASYNC_TRACE_ERROR will cause ERROR, SEVERE and FATAL trace entries to be returned
  1470. * to the callback function.
  1471. *
  1472. * ### MQTT Packet Tracing
  1473. *
  1474. * A feature that can be very useful is printing the MQTT packets that are sent and received. To
  1475. * achieve this, use the following environment variable settings:
  1476. * @code
  1477. MQTT_C_CLIENT_TRACE=ON
  1478. MQTT_C_CLIENT_TRACE_LEVEL=PROTOCOL
  1479. * @endcode
  1480. * The output you should see looks like this:
  1481. * @code
  1482. 20130528 155936.813 3 stdout-subscriber -> CONNECT cleansession: 1 (0)
  1483. 20130528 155936.813 3 stdout-subscriber <- CONNACK rc: 0
  1484. 20130528 155936.813 3 stdout-subscriber -> SUBSCRIBE msgid: 1 (0)
  1485. 20130528 155936.813 3 stdout-subscriber <- SUBACK msgid: 1
  1486. 20130528 155941.818 3 stdout-subscriber -> DISCONNECT (0)
  1487. * @endcode
  1488. * where the fields are:
  1489. * 1. date
  1490. * 2. time
  1491. * 3. socket number
  1492. * 4. client id
  1493. * 5. direction (-> from client to server, <- from server to client)
  1494. * 6. packet details
  1495. *
  1496. * ### Default Level Tracing
  1497. *
  1498. * This is an extract of a default level trace of a call to connect:
  1499. * @code
  1500. 19700101 010000.000 (1152206656) (0)> MQTTClient_connect:893
  1501. 19700101 010000.000 (1152206656) (1)> MQTTClient_connectURI:716
  1502. 20130528 160447.479 Connecting to serverURI localhost:1883
  1503. 20130528 160447.479 (1152206656) (2)> MQTTProtocol_connect:98
  1504. 20130528 160447.479 (1152206656) (3)> MQTTProtocol_addressPort:48
  1505. 20130528 160447.479 (1152206656) (3)< MQTTProtocol_addressPort:73
  1506. 20130528 160447.479 (1152206656) (3)> Socket_new:599
  1507. 20130528 160447.479 New socket 4 for localhost, port 1883
  1508. 20130528 160447.479 (1152206656) (4)> Socket_addSocket:163
  1509. 20130528 160447.479 (1152206656) (5)> Socket_setnonblocking:73
  1510. 20130528 160447.479 (1152206656) (5)< Socket_setnonblocking:78 (0)
  1511. 20130528 160447.479 (1152206656) (4)< Socket_addSocket:176 (0)
  1512. 20130528 160447.479 (1152206656) (4)> Socket_error:95
  1513. 20130528 160447.479 (1152206656) (4)< Socket_error:104 (115)
  1514. 20130528 160447.479 Connect pending
  1515. 20130528 160447.479 (1152206656) (3)< Socket_new:683 (115)
  1516. 20130528 160447.479 (1152206656) (2)< MQTTProtocol_connect:131 (115)
  1517. * @endcode
  1518. * where the fields are:
  1519. * 1. date
  1520. * 2. time
  1521. * 3. thread id
  1522. * 4. function nesting level
  1523. * 5. function entry (>) or exit (<)
  1524. * 6. function name : line of source code file
  1525. * 7. return value (if there is one)
  1526. *
  1527. * ### Memory Allocation Tracing
  1528. *
  1529. * Setting the trace level to maximum causes memory allocations and frees to be traced along with
  1530. * the default trace entries, with messages like the following:
  1531. * @code
  1532. 20130528 161819.657 Allocating 16 bytes in heap at file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c line 177 ptr 0x179f930
  1533. 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
  1534. * @endcode
  1535. * When the last MQTT client object is destroyed, if the trace is being recorded
  1536. * and all memory allocated by the client library has not been freed, an error message will be
  1537. * written to the trace. This can help with fixing memory leaks. The message will look like this:
  1538. * @code
  1539. 20130528 163909.208 Some memory not freed at shutdown, possible memory leak
  1540. 20130528 163909.208 Heap scan start, total 880 bytes
  1541. 20130528 163909.208 Heap element size 32, line 354, file /home/icraggs/workspaces/mqrtc/mqttv3c/src/MQTTPacket.c, ptr 0x260cb00
  1542. 20130528 163909.208 Content
  1543. 20130528 163909.209 Heap scan end
  1544. * @endcode
  1545. * @endcond
  1546. */
  1547. #endif
  1548. #ifdef __cplusplus
  1549. }
  1550. #endif