MQTTAsync.h 95 KB

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