]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt.h
Correct an err in queue.c introduced when previously updating behaviour when queue...
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-IoT-Libraries / c_sdk / standard / mqtt / include / iot_mqtt.h
1 /*\r
2  * Amazon FreeRTOS MQTT V2.0.0\r
3  * Copyright (C) 2018 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software.\r
14  *\r
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21  *\r
22  * http://aws.amazon.com/freertos\r
23  * http://www.FreeRTOS.org\r
24  */\r
25 \r
26 /**\r
27  * @file iot_mqtt.h\r
28  * @brief User-facing functions of the MQTT 3.1.1 library.\r
29  */\r
30 \r
31 #ifndef IOT_MQTT_H_\r
32 #define IOT_MQTT_H_\r
33 \r
34 /* The config header is always included first. */\r
35 #include "iot_config.h"\r
36 \r
37 /* MQTT types include. */\r
38 #include "types/iot_mqtt_types.h"\r
39 \r
40 /*------------------------- MQTT library functions --------------------------*/\r
41 \r
42 /**\r
43  * @functionspage{mqtt,MQTT library}\r
44  * - @functionname{mqtt_function_init}\r
45  * - @functionname{mqtt_function_cleanup}\r
46  * - @functionname{mqtt_function_receivecallback}\r
47  * - @functionname{mqtt_function_connect}\r
48  * - @functionname{mqtt_function_disconnect}\r
49  * - @functionname{mqtt_function_subscribe}\r
50  * - @functionname{mqtt_function_timedsubscribe}\r
51  * - @functionname{mqtt_function_unsubscribe}\r
52  * - @functionname{mqtt_function_timedunsubscribe}\r
53  * - @functionname{mqtt_function_publish}\r
54  * - @functionname{mqtt_function_timedpublish}\r
55  * - @functionname{mqtt_function_wait}\r
56  * - @functionname{mqtt_function_strerror}\r
57  * - @functionname{mqtt_function_operationtype}\r
58  * - @functionname{mqtt_function_issubscribed}\r
59  */\r
60 \r
61 /**\r
62  * @functionpage{IotMqtt_Init,mqtt,init}\r
63  * @functionpage{IotMqtt_Cleanup,mqtt,cleanup}\r
64  * @functionpage{IotMqtt_ReceiveCallback,mqtt,receivecallback}\r
65  * @functionpage{IotMqtt_Connect,mqtt,connect}\r
66  * @functionpage{IotMqtt_Disconnect,mqtt,disconnect}\r
67  * @functionpage{IotMqtt_Subscribe,mqtt,subscribe}\r
68  * @functionpage{IotMqtt_TimedSubscribe,mqtt,timedsubscribe}\r
69  * @functionpage{IotMqtt_Unsubscribe,mqtt,unsubscribe}\r
70  * @functionpage{IotMqtt_TimedUnsubscribe,mqtt,timedunsubscribe}\r
71  * @functionpage{IotMqtt_Publish,mqtt,publish}\r
72  * @functionpage{IotMqtt_TimedPublish,mqtt,timedpublish}\r
73  * @functionpage{IotMqtt_Wait,mqtt,wait}\r
74  * @functionpage{IotMqtt_strerror,mqtt,strerror}\r
75  * @functionpage{IotMqtt_OperationType,mqtt,operationtype}\r
76  * @functionpage{IotMqtt_IsSubscribed,mqtt,issubscribed}\r
77  */\r
78 \r
79 /**\r
80  * @brief One-time initialization function for the MQTT library.\r
81  *\r
82  * This function performs setup of the MQTT library. <b>It must be called\r
83  * once (and only once) before calling any other MQTT function.</b> Calling this\r
84  * function more than once without first calling @ref mqtt_function_cleanup\r
85  * may result in a crash.\r
86  *\r
87  * @return One of the following:\r
88  * - #IOT_MQTT_SUCCESS\r
89  * - #IOT_MQTT_INIT_FAILED\r
90  *\r
91  * @warning No thread-safety guarantees are provided for this function.\r
92  *\r
93  * @see @ref mqtt_function_cleanup\r
94  */\r
95 /* @[declare_mqtt_init] */\r
96 IotMqttError_t IotMqtt_Init( void );\r
97 /* @[declare_mqtt_init] */\r
98 \r
99 /**\r
100  * @brief One-time deinitialization function for the MQTT library.\r
101  *\r
102  * This function frees resources taken in @ref mqtt_function_init. It should be\r
103  * called after [closing all MQTT connections](@ref mqtt_function_disconnect) to\r
104  * clean up the MQTT library. After this function returns, @ref mqtt_function_init\r
105  * must be called again before calling any other MQTT function.\r
106  *\r
107  * @warning No thread-safety guarantees are provided for this function. Do not\r
108  * call this function if any MQTT connections are open!\r
109  *\r
110  * @see @ref mqtt_function_init\r
111  */\r
112 /* @[declare_mqtt_cleanup] */\r
113 void IotMqtt_Cleanup( void );\r
114 /* @[declare_mqtt_cleanup] */\r
115 \r
116 /**\r
117  * @brief Network receive callback for the MQTT library.\r
118  *\r
119  * This function should be called by the system whenever data is available for\r
120  * the MQTT library.\r
121  *\r
122  * @param[in] pNetworkConnection The network connection associated with the MQTT\r
123  * connection, passed by the network stack.\r
124  * @param[in] pReceiveContext A pointer to the MQTT connection handle for which\r
125  * the packet was received.\r
126  */\r
127 /* @[declare_mqtt_receivecallback] */\r
128 void IotMqtt_ReceiveCallback( void * pNetworkConnection,\r
129                               void * pReceiveContext );\r
130 /* @[declare_mqtt_receivecallback] */\r
131 \r
132 /**\r
133  * @brief Establish a new MQTT connection.\r
134  *\r
135  * This function opens a connection between a new MQTT client and an MQTT server\r
136  * (also called a <i>broker</i>). MQTT connections are established on top of transport\r
137  * layer protocols (such as TCP/IP), and optionally, application layer security\r
138  * protocols (such as TLS). The MQTT packet that establishes a connection is called\r
139  * the MQTT CONNECT packet. After @ref mqtt_function_init, this function must be\r
140  * called before any other MQTT library function.\r
141  *\r
142  * If [pConnectInfo->cleanSession](@ref IotMqttConnectInfo_t.cleanSession) is `true`,\r
143  * this function establishes a clean MQTT session. Subscriptions and unacknowledged\r
144  * PUBLISH messages will be discarded when the connection is closed.\r
145  *\r
146  * If [pConnectInfo->cleanSession](@ref IotMqttConnectInfo_t.cleanSession) is `false`,\r
147  * this function establishes (or re-establishes) a persistent MQTT session. The parameters\r
148  * [pConnectInfo->pPreviousSubscriptions](@ref IotMqttConnectInfo_t.pPreviousSubscriptions)\r
149  * and [pConnectInfo->previousSubscriptionCount](@ref IotMqttConnectInfo_t.previousSubscriptionCount)\r
150  * may be used to restore subscriptions present in a re-established persistent session.\r
151  * Any restored subscriptions <b>MUST</b> have been present in the persistent session;\r
152  * <b>this function does not send an MQTT SUBSCRIBE packet!</b>\r
153  *\r
154  * This MQTT library is network agnostic, meaning it has no knowledge of the\r
155  * underlying network protocol carrying the MQTT packets. It interacts with the\r
156  * network through a network abstraction layer, allowing it to be used with many\r
157  * different network stacks. The network abstraction layer is established\r
158  * per-connection, allowing every #IotMqttConnection_t to use a different network\r
159  * stack. The parameter `pNetworkInterface` sets up the network abstraction layer\r
160  * for an MQTT connection; see the documentation on #IotMqttNetworkInfo_t for details\r
161  * on its members.\r
162  *\r
163  * The `pConnectInfo` parameter provides the contents of the MQTT CONNECT packet.\r
164  * Most members [are defined by the MQTT spec.](@ref IotMqttConnectInfo_t). The\r
165  * [pConnectInfo->pWillInfo](@ref IotMqttConnectInfo_t.pWillInfo) member provides\r
166  * information on a Last Will and Testament (LWT) message to be published if the\r
167  * MQTT connection is closed without [sending a DISCONNECT packet]\r
168  * (@ref mqtt_function_disconnect). Unlike other PUBLISH\r
169  * messages, a LWT message payload is limited to 65535 bytes in length. Additionally,\r
170  * the retry [interval](@ref IotMqttPublishInfo_t.retryMs) and [limit]\r
171  * (@ref IotMqttPublishInfo_t.retryLimit) members of #IotMqttPublishInfo_t\r
172  * are ignored for LWT messages. The LWT message is optional; `pWillInfo` may be NULL.\r
173  *\r
174  * Unlike @ref mqtt_function_publish, @ref mqtt_function_subscribe, and\r
175  * @ref mqtt_function_unsubscribe, this function is always blocking. Additionally,\r
176  * because the MQTT connection acknowledgement packet (CONNACK packet) does not\r
177  * contain any information on <i>which</i> CONNECT packet it acknowledges, only one\r
178  * CONNECT operation may be in progress at any time. This means that parallel\r
179  * threads making calls to @ref mqtt_function_connect will be serialized to send\r
180  * their CONNECT packets one-by-one.\r
181  *\r
182  * @param[in] pNetworkInfo Information on the transport-layer network connection\r
183  * to use with the MQTT connection.\r
184  * @param[in] pConnectInfo MQTT connection setup parameters.\r
185  * @param[in] timeoutMs If the MQTT server does not accept the connection within\r
186  * this timeout, this function returns #IOT_MQTT_TIMEOUT.\r
187  * @param[out] pMqttConnection Set to a newly-initialized MQTT connection handle\r
188  * if this function succeeds.\r
189  *\r
190  * @return One of the following:\r
191  * - #IOT_MQTT_SUCCESS\r
192  * - #IOT_MQTT_BAD_PARAMETER\r
193  * - #IOT_MQTT_NO_MEMORY\r
194  * - #IOT_MQTT_NETWORK_ERROR\r
195  * - #IOT_MQTT_SCHEDULING_ERROR\r
196  * - #IOT_MQTT_BAD_RESPONSE\r
197  * - #IOT_MQTT_TIMEOUT\r
198  * - #IOT_MQTT_SERVER_REFUSED\r
199  *\r
200  * <b>Example</b>\r
201  * @code{c}\r
202  * // An initialized and connected network connection.\r
203  * IotNetworkConnection_t pNetworkConnection;\r
204  *\r
205  * // Parameters to MQTT connect.\r
206  * IotMqttConnection_t mqttConnection = IOT_MQTT_CONNECTION_INITIALIZER;\r
207  * IotMqttNetworkInfo_t networkInfo = IOT_MQTT_NETWORK_INFO_INITIALIZER;\r
208  * IotMqttConnectInfo_t connectInfo = IOT_MQTT_CONNECT_INFO_INITIALIZER;\r
209  * IotMqttPublishInfo_t willInfo = IOT_MQTT_PUBLISH_INFO_INITIALIZER;\r
210  *\r
211  * // Example network abstraction types.\r
212  * IotNetworkServerInfo_t serverInfo = { ... };\r
213  * IotNetworkCredentialInfo_t credentialInfo = { ... };\r
214  * IotNetworkInterface_t networkInterface = { ... };\r
215  *\r
216  * // Example using a generic network implementation.\r
217  * networkInfo.createNetworkConnection = true;\r
218  * networkInfo.pNetworkServerInfo = &serverInfo;\r
219  * networkInfo.pNetworkCredentialInfo = &credentialInfo;\r
220  * networkInfo.pNetworkInterface = &networkInterface;\r
221  *\r
222  * // Set the members of the connection info (password and username not used).\r
223  * connectInfo.cleanSession = true;\r
224  * connectInfo.keepAliveSeconds = 30;\r
225  * connectInfo.pClientIdentifier = "uniqueclientidentifier";\r
226  * connectInfo.clientIdentifierLength = 22;\r
227  *\r
228  * // Set the members of the will info (retain and retry not used).\r
229  * willInfo.qos = IOT_MQTT_QOS_1;\r
230  * willInfo.pTopicName = "will/topic/name";\r
231  * willInfo.topicNameLength = 15;\r
232  * willInfo.pPayload = "MQTT client unexpectedly disconnected.";\r
233  * willInfo.payloadLength = 38;\r
234  *\r
235  * // Set the pointer to the will info.\r
236  * connectInfo.pWillInfo = &willInfo;\r
237  *\r
238  * // Call CONNECT with a 5 second block time. Should return\r
239  * // IOT_MQTT_SUCCESS when successful.\r
240  * IotMqttError_t result = IotMqtt_Connect( &networkInfo,\r
241  *                                          &connectInfo,\r
242  *                                          5000,\r
243  *                                          &mqttConnection );\r
244  *\r
245  * if( result == IOT_MQTT_SUCCESS )\r
246  * {\r
247  *     // Do something with the MQTT connection...\r
248  *\r
249  *     // Clean up and close the MQTT connection once it's no longer needed.\r
250  *     IotMqtt_Disconnect( mqttConnection, 0 );\r
251  * }\r
252  * @endcode\r
253  */\r
254 /* @[declare_mqtt_connect] */\r
255 IotMqttError_t IotMqtt_Connect( const IotMqttNetworkInfo_t * pNetworkInfo,\r
256                                 const IotMqttConnectInfo_t * pConnectInfo,\r
257                                 uint32_t timeoutMs,\r
258                                 IotMqttConnection_t * const pMqttConnection );\r
259 /* @[declare_mqtt_connect] */\r
260 \r
261 /**\r
262  * @brief Closes an MQTT connection and frees resources.\r
263  *\r
264  * This function closes an MQTT connection and should only be called once\r
265  * the MQTT connection is no longer needed. Its exact behavior depends on the\r
266  * `flags` parameter.\r
267  *\r
268  * Normally, `flags` should be `0`. This gracefully shuts down an MQTT\r
269  * connection by sending an MQTT DISCONNECT packet. Any [network close function]\r
270  * (@ref IotNetworkInterface_t::close) provided [when the connection was established]\r
271  * (@ref mqtt_function_connect) will also be called. Note that because the MQTT server\r
272  * will not acknowledge a DISCONNECT packet, the client has no way of knowing if\r
273  * the server received the DISCONNECT packet. In the case where the DISCONNECT\r
274  * packet is lost in transport, any Last Will and Testament (LWT) message established\r
275  * with the connection may be published. However, if the DISCONNECT reaches the\r
276  * MQTT server, the LWT message will be discarded and not published.\r
277  *\r
278  * Should the underlying network connection become unusable, this function should\r
279  * be called with `flags` set to #IOT_MQTT_FLAG_CLEANUP_ONLY. In this case, no\r
280  * DISCONNECT packet will be sent, though the [network close function](@ref IotNetworkInterface_t::close)\r
281  * will still be called. This function will only free the resources used by the MQTT\r
282  * connection; it still must be called even if the network is offline to avoid leaking\r
283  * resources.\r
284  *\r
285  * Once this function is called, its parameter `mqttConnection` should no longer\r
286  * be used.\r
287  *\r
288  * @param[in] mqttConnection The MQTT connection to close and clean up.\r
289  * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
290  */\r
291 /* @[declare_mqtt_disconnect] */\r
292 void IotMqtt_Disconnect( IotMqttConnection_t mqttConnection,\r
293                          uint32_t flags );\r
294 /* @[declare_mqtt_disconnect] */\r
295 \r
296 /**\r
297  * @brief Subscribes to the given array of topic filters and receive an asynchronous\r
298  * notification when the subscribe completes.\r
299  *\r
300  * This function transmits an MQTT SUBSCRIBE packet to the server. A SUBSCRIBE\r
301  * packet notifies the server to send any matching PUBLISH messages to this client.\r
302  * A single SUBSCRIBE packet may carry more than one topic filter, hence the\r
303  * parameters to this function include an array of [subscriptions]\r
304  * (@ref IotMqttSubscription_t).\r
305  *\r
306  * An MQTT subscription has two pieces:\r
307  * 1. The subscription topic filter registered with the MQTT server. The MQTT\r
308  * SUBSCRIBE packet sent from this client to server notifies the server to send\r
309  * messages matching the given topic filters to this client.\r
310  * 2. The [callback function](@ref IotMqttCallbackInfo_t.function) that this\r
311  * client will invoke when an incoming message is received. The callback function\r
312  * notifies applications of an incoming PUBLISH message.\r
313  *\r
314  * The helper function @ref mqtt_function_issubscribed can be used to check if a\r
315  * [callback function](@ref IotMqttCallbackInfo_t.function) is registered for\r
316  * a particular topic filter.\r
317  *\r
318  * To modify an already-registered subscription callback, call this function with\r
319  * a new `pSubscriptionList`. Any topic filters in `pSubscriptionList` that already\r
320  * have a registered callback will be replaced with the new values in `pSubscriptionList`.\r
321  *\r
322  * @attention QoS 2 subscriptions are currently unsupported. Only 0 or 1 are valid\r
323  * for subscription QoS.\r
324  *\r
325  * @param[in] mqttConnection The MQTT connection to use for the subscription.\r
326  * @param[in] pSubscriptionList Pointer to the first element in the array of\r
327  * subscriptions.\r
328  * @param[in] subscriptionCount The number of elements in pSubscriptionList.\r
329  * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
330  * @param[in] pCallbackInfo Asynchronous notification of this function's completion.\r
331  * @param[out] pSubscribeOperation Set to a handle by which this operation may be\r
332  * referenced after this function returns. This reference is invalidated once\r
333  * the subscription operation completes.\r
334  *\r
335  * @return This function will return #IOT_MQTT_STATUS_PENDING upon success.\r
336  * @return Upon completion of the subscription (either through an\r
337  * #IotMqttCallbackInfo_t or @ref mqtt_function_wait), the status will be one of:\r
338  * - #IOT_MQTT_SUCCESS\r
339  * - #IOT_MQTT_NETWORK_ERROR\r
340  * - #IOT_MQTT_SCHEDULING_ERROR\r
341  * - #IOT_MQTT_BAD_RESPONSE\r
342  * - #IOT_MQTT_SERVER_REFUSED\r
343  * @return If this function fails before queuing a subscribe operation, it will return\r
344  * one of:\r
345  * - #IOT_MQTT_BAD_PARAMETER\r
346  * - #IOT_MQTT_NO_MEMORY\r
347  *\r
348  * @see @ref mqtt_function_timedsubscribe for a blocking variant of this function.\r
349  * @see @ref mqtt_function_unsubscribe for the function that removes subscriptions.\r
350  *\r
351  * <b>Example</b>\r
352  * @code{c}\r
353  * #define NUMBER_OF_SUBSCRIPTIONS ...\r
354  *\r
355  * // Subscription callback function.\r
356  * void subscriptionCallback( void * pArgument, IotMqttCallbackParam_t * pPublish );\r
357  *\r
358  * // An initialized and connected MQTT connection.\r
359  * IotMqttConnection_t mqttConnection;\r
360  *\r
361  * // Subscription information.\r
362  * pSubscriptions[ NUMBER_OF_SUBSCRIPTIONS ] = { IOT_MQTT_SUBSCRIPTION_INITIALIZER };\r
363  * IotMqttOperation_t lastOperation = IOT_MQTT_OPERATION_INITIALIZER;\r
364  *\r
365  * // Set the subscription information.\r
366  * for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )\r
367  * {\r
368  *     pSubscriptions[ i ].qos = IOT_MQTT_QOS_1;\r
369  *     pSubscriptions[ i ].pTopicFilter = "some/topic/filter";\r
370  *     pSubscriptions[ i ].topicLength = ( uint16_t ) strlen( pSubscriptions[ i ].pTopicFilter );\r
371  *     pSubscriptions[ i ].callback.function = subscriptionCallback;\r
372  * }\r
373  *\r
374  * IotMqttError_t result = IotMqtt_Subscribe( mqttConnection,\r
375  *                                            pSubscriptions,\r
376  *                                            NUMBER_OF_SUBSCRIPTIONS,\r
377  *                                            IOT_MQTT_FLAG_WAITABLE,\r
378  *                                            NULL,\r
379  *                                            &lastOperation );\r
380  *\r
381  * // Subscribe returns IOT_MQTT_STATUS_PENDING when successful. Wait up to\r
382  * // 5 seconds for the operation to complete.\r
383  * if( result == IOT_MQTT_STATUS_PENDING )\r
384  * {\r
385  *     result = IotMqtt_Wait( subscriptionRef, 5000 );\r
386  * }\r
387  *\r
388  * // Check that the subscriptions were successful.\r
389  * if( result == IOT_MQTT_SUCCESS )\r
390  * {\r
391  *     // Wait for messages on the subscription topic filters...\r
392  *\r
393  *     // Unsubscribe once the subscriptions are no longer needed.\r
394  *     result = IotMqtt_Unsubscribe( mqttConnection,\r
395  *                                   pSubscriptions,\r
396  *                                   NUMBER_OF_SUBSCRIPTIONS,\r
397  *                                   IOT_MQTT_FLAG_WAITABLE,\r
398  *                                   NULL,\r
399  *                                   &lastOperation );\r
400  *\r
401  *     // UNSUBSCRIBE returns IOT_MQTT_STATUS_PENDING when successful.\r
402  *     // Wait up to 5 seconds for the operation to complete.\r
403  *     if( result == IOT_MQTT_STATUS_PENDING )\r
404  *     {\r
405  *         result = IotMqtt_Wait( lastOperation, 5000 );\r
406  *     }\r
407  * }\r
408  * // Check which subscriptions were rejected by the server.\r
409  * else if( result == IOT_MQTT_SERVER_REFUSED )\r
410  * {\r
411  *     for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )\r
412  *     {\r
413  *         if( IotMqtt_IsSubscribed( mqttConnection,\r
414  *                                   pSubscriptions[ i ].pTopicFilter,\r
415  *                                   pSubscriptions[ i ].topicFilterLength,\r
416  *                                   NULL ) == false )\r
417  *         {\r
418  *             // This subscription was rejected.\r
419  *         }\r
420  *     }\r
421  * }\r
422  * @endcode\r
423  */\r
424 /* @[declare_mqtt_subscribe] */\r
425 IotMqttError_t IotMqtt_Subscribe( IotMqttConnection_t mqttConnection,\r
426                                   const IotMqttSubscription_t * pSubscriptionList,\r
427                                   size_t subscriptionCount,\r
428                                   uint32_t flags,\r
429                                   const IotMqttCallbackInfo_t * pCallbackInfo,\r
430                                   IotMqttOperation_t * const pSubscribeOperation );\r
431 /* @[declare_mqtt_subscribe] */\r
432 \r
433 /**\r
434  * @brief Subscribes to the given array of topic filters with a timeout.\r
435  *\r
436  * This function transmits an MQTT SUBSCRIBE packet to the server, then waits for\r
437  * a server response to the packet. Internally, this function is a call to @ref\r
438  * mqtt_function_subscribe followed by @ref mqtt_function_wait. See @ref\r
439  * mqtt_function_subscribe for more information about the MQTT SUBSCRIBE operation.\r
440  *\r
441  * @attention QoS 2 subscriptions are currently unsupported. Only 0 or 1 are valid\r
442  * for subscription QoS.\r
443  *\r
444  * @param[in] mqttConnection The MQTT connection to use for the subscription.\r
445  * @param[in] pSubscriptionList Pointer to the first element in the array of\r
446  * subscriptions.\r
447  * @param[in] subscriptionCount The number of elements in pSubscriptionList.\r
448  * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
449  * Currently, flags are ignored by this function; this parameter is for\r
450  * future-compatibility.\r
451  * @param[in] timeoutMs If the MQTT server does not acknowledge the subscriptions within\r
452  * this timeout, this function returns #IOT_MQTT_TIMEOUT.\r
453  *\r
454  * @return One of the following:\r
455  * - #IOT_MQTT_SUCCESS\r
456  * - #IOT_MQTT_BAD_PARAMETER\r
457  * - #IOT_MQTT_NO_MEMORY\r
458  * - #IOT_MQTT_NETWORK_ERROR\r
459  * - #IOT_MQTT_SCHEDULING_ERROR\r
460  * - #IOT_MQTT_BAD_RESPONSE\r
461  * - #IOT_MQTT_TIMEOUT\r
462  * - #IOT_MQTT_SERVER_REFUSED\r
463  */\r
464 /* @[declare_mqtt_timedsubscribe] */\r
465 IotMqttError_t IotMqtt_TimedSubscribe( IotMqttConnection_t mqttConnection,\r
466                                        const IotMqttSubscription_t * pSubscriptionList,\r
467                                        size_t subscriptionCount,\r
468                                        uint32_t flags,\r
469                                        uint32_t timeoutMs );\r
470 /* @[declare_mqtt_timedsubscribe] */\r
471 \r
472 /**\r
473  * @brief Unsubscribes from the given array of topic filters and receive an asynchronous\r
474  * notification when the unsubscribe completes.\r
475  *\r
476  * This function transmits an MQTT UNSUBSCRIBE packet to the server. An UNSUBSCRIBE\r
477  * packet removes registered topic filters from the server. After unsubscribing,\r
478  * the server will no longer send messages on these topic filters to the client.\r
479  *\r
480  * Corresponding [subscription callback functions](@ref IotMqttCallbackInfo_t.function)\r
481  * are also removed from the MQTT connection. These subscription callback functions\r
482  * will be removed even if the MQTT UNSUBSCRIBE packet fails to send.\r
483  *\r
484  * @param[in] mqttConnection The MQTT connection used for the subscription.\r
485  * @param[in] pSubscriptionList Pointer to the first element in the array of\r
486  * subscriptions.\r
487  * @param[in] subscriptionCount The number of elements in pSubscriptionList.\r
488  * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
489  * @param[in] pCallbackInfo Asynchronous notification of this function's completion.\r
490  * @param[out] pUnsubscribeOperation Set to a handle by which this operation may be\r
491  * referenced after this function returns. This reference is invalidated once\r
492  * the unsubscribe operation completes.\r
493  *\r
494  * @return This function will return #IOT_MQTT_STATUS_PENDING upon success.\r
495  * @return Upon completion of the unsubscribe (either through an\r
496  * #IotMqttCallbackInfo_t or @ref mqtt_function_wait), the status will be one of:\r
497  * - #IOT_MQTT_SUCCESS\r
498  * - #IOT_MQTT_NETWORK_ERROR\r
499  * - #IOT_MQTT_SCHEDULING_ERROR\r
500  * - #IOT_MQTT_BAD_RESPONSE\r
501  * @return If this function fails before queuing an unsubscribe operation, it will return\r
502  * one of:\r
503  * - #IOT_MQTT_BAD_PARAMETER\r
504  * - #IOT_MQTT_NO_MEMORY\r
505  *\r
506  * @see @ref mqtt_function_timedsubscribe for a blocking variant of this function.\r
507  * @see @ref mqtt_function_subscribe for the function that adds subscriptions.\r
508  */\r
509 /* @[declare_mqtt_unsubscribe] */\r
510 IotMqttError_t IotMqtt_Unsubscribe( IotMqttConnection_t mqttConnection,\r
511                                     const IotMqttSubscription_t * pSubscriptionList,\r
512                                     size_t subscriptionCount,\r
513                                     uint32_t flags,\r
514                                     const IotMqttCallbackInfo_t * pCallbackInfo,\r
515                                     IotMqttOperation_t * const pUnsubscribeOperation );\r
516 /* @[declare_mqtt_unsubscribe] */\r
517 \r
518 /**\r
519  * @brief Unsubscribes from a given array of topic filters with a timeout.\r
520  *\r
521  * This function transmits an MQTT UNSUBSCRIBE packet to the server, then waits\r
522  * for a server response to the packet. Internally, this function is a call to\r
523  * @ref mqtt_function_unsubscribe followed by @ref mqtt_function_wait. See @ref\r
524  * mqtt_function_unsubscribe for more information about the MQTT UNSUBSCRIBE\r
525  * operation.\r
526  *\r
527  * @param[in] mqttConnection The MQTT connection used for the subscription.\r
528  * @param[in] pSubscriptionList Pointer to the first element in the array of\r
529  * subscriptions.\r
530  * @param[in] subscriptionCount The number of elements in pSubscriptionList.\r
531  * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
532  * Currently, flags are ignored by this function; this parameter is for\r
533  * future-compatibility.\r
534  * @param[in] timeoutMs If the MQTT server does not acknowledge the UNSUBSCRIBE within\r
535  * this timeout, this function returns #IOT_MQTT_TIMEOUT.\r
536  *\r
537  * @return One of the following:\r
538  * - #IOT_MQTT_SUCCESS\r
539  * - #IOT_MQTT_BAD_PARAMETER\r
540  * - #IOT_MQTT_NO_MEMORY\r
541  * - #IOT_MQTT_NETWORK_ERROR\r
542  * - #IOT_MQTT_SCHEDULING_ERROR\r
543  * - #IOT_MQTT_BAD_RESPONSE\r
544  */\r
545 /* @[declare_mqtt_timedunsubscribe] */\r
546 IotMqttError_t IotMqtt_TimedUnsubscribe( IotMqttConnection_t mqttConnection,\r
547                                          const IotMqttSubscription_t * pSubscriptionList,\r
548                                          size_t subscriptionCount,\r
549                                          uint32_t flags,\r
550                                          uint32_t timeoutMs );\r
551 /* @[declare_mqtt_timedunsubscribe] */\r
552 \r
553 /**\r
554  * @brief Publishes a message to the given topic name and receive an asynchronous\r
555  * notification when the publish completes.\r
556  *\r
557  * This function transmits an MQTT PUBLISH packet to the server. A PUBLISH packet\r
558  * contains a payload and a topic name. Any clients with a subscription on a\r
559  * topic filter matching the PUBLISH topic name will receive a copy of the\r
560  * PUBLISH packet from the server.\r
561  *\r
562  * If a PUBLISH packet fails to reach the server and it is not a QoS 0 message,\r
563  * it will be retransmitted. See #IotMqttPublishInfo_t for a description\r
564  * of the retransmission strategy.\r
565  *\r
566  * @attention QoS 2 messages are currently unsupported. Only 0 or 1 are valid\r
567  * for message QoS.\r
568  *\r
569  * @param[in] mqttConnection The MQTT connection to use for the publish.\r
570  * @param[in] pPublishInfo MQTT publish parameters.\r
571  * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
572  * @param[in] pCallbackInfo Asynchronous notification of this function's completion.\r
573  * @param[out] pPublishOperation Set to a handle by which this operation may be\r
574  * referenced after this function returns. This reference is invalidated once\r
575  * the publish operation completes.\r
576  *\r
577  * @return This function will return #IOT_MQTT_STATUS_PENDING upon success for\r
578  * QoS 1 publishes. For a QoS 0 publish it returns #IOT_MQTT_SUCCESS upon\r
579  * success.\r
580  * @return Upon completion of a QoS 1 publish (either through an\r
581  * #IotMqttCallbackInfo_t or @ref mqtt_function_wait), the status will be one of:\r
582  * - #IOT_MQTT_SUCCESS\r
583  * - #IOT_MQTT_NETWORK_ERROR\r
584  * - #IOT_MQTT_SCHEDULING_ERROR\r
585  * - #IOT_MQTT_BAD_RESPONSE\r
586  * - #IOT_MQTT_RETRY_NO_RESPONSE (if [pPublishInfo->retryMs](@ref IotMqttPublishInfo_t.retryMs)\r
587  * and [pPublishInfo->retryLimit](@ref IotMqttPublishInfo_t.retryLimit) were set).\r
588  * @return If this function fails before queuing an publish operation (regardless\r
589  * of QoS), it will return one of:\r
590  * - #IOT_MQTT_BAD_PARAMETER\r
591  * - #IOT_MQTT_NO_MEMORY\r
592  *\r
593  * @note The parameters `pCallbackInfo` and `pPublishOperation` should only be used for QoS\r
594  * 1 publishes. For QoS 0, they should both be `NULL`.\r
595  *\r
596  * @see @ref mqtt_function_timedpublish for a blocking variant of this function.\r
597  *\r
598  * <b>Example</b>\r
599  * @code{c}\r
600  * // An initialized and connected MQTT connection.\r
601  * IotMqttConnection_t mqttConnection;\r
602  *\r
603  * // Publish information.\r
604  * IotMqttPublishInfo_t publishInfo = IOT_MQTT_PUBLISH_INFO_INITIALIZER;\r
605  *\r
606  * // Set the publish information. QoS 0 example (retain not used):\r
607  * publishInfo.qos = IOT_MQTT_QOS_0;\r
608  * publishInfo.pTopicName = "some/topic/name";\r
609  * publishInfo.topicNameLength = 15;\r
610  * publishInfo.pPayload = "payload";\r
611  * publishInfo.payloadLength = 8;\r
612  *\r
613  * // QoS 0 publish should return IOT_MQTT_SUCCESS upon success.\r
614  * IotMqttError_t qos0Result = IotMqtt_Publish( mqttConnection,\r
615  *                                              &publishInfo,\r
616  *                                              0,\r
617  *                                              NULL,\r
618  *                                              NULL );\r
619  *\r
620  * // QoS 1 with retry example (using same topic name and payload as QoS 0 example):\r
621  * IotMqttOperation_t qos1Operation = IOT_MQTT_OPERATION_INITIALIZER;\r
622  * publishInfo.qos = IOT_MQTT_QOS_1;\r
623  * publishInfo.retryMs = 1000; // Retry if no response is received in 1 second.\r
624  * publishInfo.retryLimit = 5; // Retry up to 5 times.\r
625  *\r
626  * // QoS 1 publish should return IOT_MQTT_STATUS_PENDING upon success.\r
627  * IotMqttError_t qos1Result = IotMqtt_Publish( mqttConnection,\r
628  *                                              &publishInfo,\r
629  *                                              IOT_MQTT_FLAG_WAITABLE,\r
630  *                                              NULL,\r
631  *                                              &qos1Operation );\r
632  *\r
633  * // Wait up to 5 seconds for the publish to complete.\r
634  * if( qos1Result == IOT_MQTT_STATUS_PENDING )\r
635  * {\r
636  *     qos1Result = IotMqtt_Wait( qos1Operation, 5000 );\r
637  * }\r
638  * @endcode\r
639  */\r
640 /* @[declare_mqtt_publish] */\r
641 IotMqttError_t IotMqtt_Publish( IotMqttConnection_t mqttConnection,\r
642                                 const IotMqttPublishInfo_t * pPublishInfo,\r
643                                 uint32_t flags,\r
644                                 const IotMqttCallbackInfo_t * pCallbackInfo,\r
645                                 IotMqttOperation_t * const pPublishOperation );\r
646 /* @[declare_mqtt_publish] */\r
647 \r
648 /**\r
649  * @brief Publish a message to the given topic name with a timeout.\r
650  *\r
651  * This function transmits an MQTT PUBLISH packet to the server, then waits for\r
652  * a server response to the packet. Internally, this function is a call to @ref\r
653  * mqtt_function_publish followed by @ref mqtt_function_wait. See @ref\r
654  * mqtt_function_publish for more information about the MQTT PUBLISH operation.\r
655  *\r
656  * @attention QoS 2 messages are currently unsupported. Only 0 or 1 are valid\r
657  * for message QoS.\r
658  *\r
659  * @param[in] mqttConnection The MQTT connection to use for the publish.\r
660  * @param[in] pPublishInfo MQTT publish parameters.\r
661  * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
662  * Currently, flags are ignored by this function; this parameter is for\r
663  * future-compatibility.\r
664  * @param[in] timeoutMs If the MQTT server does not acknowledge a QoS 1 PUBLISH\r
665  * within this timeout, this function returns #IOT_MQTT_TIMEOUT. This parameter\r
666  * is ignored for QoS 0 PUBLISH messages.\r
667  *\r
668  * @return One of the following:\r
669  * - #IOT_MQTT_SUCCESS\r
670  * - #IOT_MQTT_BAD_PARAMETER\r
671  * - #IOT_MQTT_NO_MEMORY\r
672  * - #IOT_MQTT_NETWORK_ERROR\r
673  * - #IOT_MQTT_SCHEDULING_ERROR\r
674  * - #IOT_MQTT_BAD_RESPONSE\r
675  * - #IOT_MQTT_RETRY_NO_RESPONSE (if [pPublishInfo->retryMs](@ref IotMqttPublishInfo_t.retryMs)\r
676  * and [pPublishInfo->retryLimit](@ref IotMqttPublishInfo_t.retryLimit) were set).\r
677  */\r
678 /* @[declare_mqtt_timedpublish] */\r
679 IotMqttError_t IotMqtt_TimedPublish( IotMqttConnection_t mqttConnection,\r
680                                      const IotMqttPublishInfo_t * pPublishInfo,\r
681                                      uint32_t flags,\r
682                                      uint32_t timeoutMs );\r
683 /* @[declare_mqtt_timedpublish] */\r
684 \r
685 /**\r
686  * @brief Waits for an operation to complete.\r
687  *\r
688  * This function blocks to wait for a [subscribe](@ref mqtt_function_subscribe),\r
689  * [unsubscribe](@ref mqtt_function_unsubscribe), or [publish]\r
690  * (@ref mqtt_function_publish) to complete. These operations are by default\r
691  * asynchronous; the function calls queue an operation for processing, and a\r
692  * callback is invoked once the operation is complete.\r
693  *\r
694  * To use this function, the flag #IOT_MQTT_FLAG_WAITABLE must have been\r
695  * set in the operation's function call. Additionally, this function must always\r
696  * be called with any waitable operation to clean up resources.\r
697  *\r
698  * Regardless of its return value, this function always clean up resources used\r
699  * by the waitable operation. This means `reference` is invalidated as soon as\r
700  * this function returns, even if it returns #IOT_MQTT_TIMEOUT or another error.\r
701  *\r
702  * @param[in] operation Reference to the operation to wait for. The flag\r
703  * #IOT_MQTT_FLAG_WAITABLE must have been set for this operation.\r
704  * @param[in] timeoutMs How long to wait before returning #IOT_MQTT_TIMEOUT.\r
705  *\r
706  * @return The return value of this function depends on the MQTT operation associated\r
707  * with `reference`. See #IotMqttError_t for possible return values.\r
708  *\r
709  * <b>Example</b>\r
710  * @code{c}\r
711  * // Operation reference and timeout.\r
712  * IotMqttOperation_t publishOperation = IOT_MQTT_OPERATION_INITIALIZER;\r
713  * uint32_t timeoutMs = 5000; // 5 seconds\r
714  *\r
715  * // MQTT operation to wait for.\r
716  * IotMqttError_t result = IotMqtt_Publish( mqttConnection,\r
717  *                                          &publishInfo,\r
718  *                                          IOT_MQTT_FLAG_WAITABLE,\r
719  *                                          NULL,\r
720  *                                          &publishOperation );\r
721  *\r
722  * // Publish should have returned IOT_MQTT_STATUS_PENDING. The call to wait\r
723  * // returns once the result of the publish is available or the timeout expires.\r
724  * if( result == IOT_MQTT_STATUS_PENDING )\r
725  * {\r
726  *     result = IotMqtt_Wait( publishOperation, timeoutMs );\r
727  *\r
728  *     // After the call to wait, the result of the publish is known\r
729  *     // (not IOT_MQTT_STATUS_PENDING).\r
730  *     assert( result != IOT_MQTT_STATUS_PENDING );\r
731  * }\r
732  * @endcode\r
733  */\r
734 /* @[declare_mqtt_wait] */\r
735 IotMqttError_t IotMqtt_Wait( IotMqttOperation_t operation,\r
736                              uint32_t timeoutMs );\r
737 /* @[declare_mqtt_wait] */\r
738 \r
739 /*-------------------------- MQTT helper functions --------------------------*/\r
740 \r
741 /**\r
742  * @brief Returns a string that describes an #IotMqttError_t.\r
743  *\r
744  * Like the POSIX's `strerror`, this function returns a string describing a\r
745  * return code. In this case, the return code is an MQTT library error code,\r
746  * `status`.\r
747  *\r
748  * The string returned by this function <b>MUST</b> be treated as read-only: any\r
749  * attempt to modify its contents may result in a crash. Therefore, this function\r
750  * is limited to usage in logging.\r
751  *\r
752  * @param[in] status The status to describe.\r
753  *\r
754  * @return A read-only string that describes `status`.\r
755  *\r
756  * @warning The string returned by this function must never be modified.\r
757  */\r
758 /* @[declare_mqtt_strerror] */\r
759 const char * IotMqtt_strerror( IotMqttError_t status );\r
760 /* @[declare_mqtt_strerror] */\r
761 \r
762 /**\r
763  * @brief Returns a string that describes an #IotMqttOperationType_t.\r
764  *\r
765  * This function returns a string describing an MQTT operation type, `operation`.\r
766  *\r
767  * The string returned by this function <b>MUST</b> be treated as read-only: any\r
768  * attempt to modify its contents may result in a crash. Therefore, this function\r
769  * is limited to usage in logging.\r
770  *\r
771  * @param[in] operation The operation to describe.\r
772  *\r
773  * @return A read-only string that describes `operation`.\r
774  *\r
775  * @warning The string returned by this function must never be modified.\r
776  */\r
777 /* @[declare_mqtt_operationtype] */\r
778 const char * IotMqtt_OperationType( IotMqttOperationType_t operation );\r
779 /* @[declare_mqtt_operationtype] */\r
780 \r
781 /**\r
782  * @brief Check if an MQTT connection has a subscription for a topic filter.\r
783  *\r
784  * This function checks whether an MQTT connection `mqttConnection` has a\r
785  * subscription callback registered for a topic filter `pTopicFilter`. If a\r
786  * subscription callback is found, its details are copied into the output parameter\r
787  * `pCurrentSubscription`. This subscription callback will be invoked for incoming\r
788  * PUBLISH messages on `pTopicFilter`.\r
789  *\r
790  * <b>The check for a matching subscription is only performed client-side</b>;\r
791  * therefore, this function should not be relied upon for perfect accuracy. For\r
792  * example, this function may return an incorrect result if the MQTT server\r
793  * crashes and drops subscriptions without informing the client.\r
794  *\r
795  * Note that an MQTT connection's subscriptions might change between the time this\r
796  * function checks the subscription list and its caller tests the return value.\r
797  * This function certainly should not be used concurrently with any pending SUBSCRIBE\r
798  * or UNSUBSCRIBE operations.\r
799  *\r
800  * One suitable use of this function is to check <i>which</i> subscriptions were rejected\r
801  * if @ref mqtt_function_subscribe returns #IOT_MQTT_SERVER_REFUSED; that return\r
802  * code only means that <i>at least one</i> subscription was rejected.\r
803  *\r
804  * @param[in] mqttConnection The MQTT connection to check.\r
805  * @param[in] pTopicFilter The topic filter to check.\r
806  * @param[in] topicFilterLength Length of `pTopicFilter`.\r
807  * @param[out] pCurrentSubscription If a subscription is found, its details are\r
808  * copied here. This output parameter is only valid if this function returns `true`.\r
809  * Pass `NULL` to ignore.\r
810  *\r
811  * @return `true` if a subscription was found; `false` otherwise.\r
812  *\r
813  * @note The subscription QoS is not stored by the MQTT library; therefore,\r
814  * `pCurrentSubscription->qos` will always be set to #IOT_MQTT_QOS_0.\r
815  */\r
816 /* @[declare_mqtt_issubscribed] */\r
817 bool IotMqtt_IsSubscribed( IotMqttConnection_t mqttConnection,\r
818                            const char * pTopicFilter,\r
819                            uint16_t topicFilterLength,\r
820                            IotMqttSubscription_t * const pCurrentSubscription );\r
821 /* @[declare_mqtt_issubscribed] */\r
822 \r
823 #endif /* ifndef IOT_MQTT_H_ */\r