]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt.h
Rename \FreeRTOS-Plus\Source\FreeRTOS-Plus-IoT-SDK to \FreeRTOS-Plus\Source\FreeRTOS...
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-IoT-Libraries / c_sdk / standard / mqtt / include / iot_mqtt.h
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt.h b/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/include/iot_mqtt.h
new file mode 100644 (file)
index 0000000..327784a
--- /dev/null
@@ -0,0 +1,823 @@
+/*\r
+ * Amazon FreeRTOS MQTT V2.0.0\r
+ * Copyright (C) 2018 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
+ *\r
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
+ * this software and associated documentation files (the "Software"), to deal in\r
+ * the Software without restriction, including without limitation the rights to\r
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
+ * the Software, and to permit persons to whom the Software is furnished to do so,\r
+ * subject to the following conditions:\r
+ *\r
+ * The above copyright notice and this permission notice shall be included in all\r
+ * copies or substantial portions of the Software.\r
+ *\r
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+ *\r
+ * http://aws.amazon.com/freertos\r
+ * http://www.FreeRTOS.org\r
+ */\r
+\r
+/**\r
+ * @file iot_mqtt.h\r
+ * @brief User-facing functions of the MQTT 3.1.1 library.\r
+ */\r
+\r
+#ifndef IOT_MQTT_H_\r
+#define IOT_MQTT_H_\r
+\r
+/* The config header is always included first. */\r
+#include "iot_config.h"\r
+\r
+/* MQTT types include. */\r
+#include "types/iot_mqtt_types.h"\r
+\r
+/*------------------------- MQTT library functions --------------------------*/\r
+\r
+/**\r
+ * @functionspage{mqtt,MQTT library}\r
+ * - @functionname{mqtt_function_init}\r
+ * - @functionname{mqtt_function_cleanup}\r
+ * - @functionname{mqtt_function_receivecallback}\r
+ * - @functionname{mqtt_function_connect}\r
+ * - @functionname{mqtt_function_disconnect}\r
+ * - @functionname{mqtt_function_subscribe}\r
+ * - @functionname{mqtt_function_timedsubscribe}\r
+ * - @functionname{mqtt_function_unsubscribe}\r
+ * - @functionname{mqtt_function_timedunsubscribe}\r
+ * - @functionname{mqtt_function_publish}\r
+ * - @functionname{mqtt_function_timedpublish}\r
+ * - @functionname{mqtt_function_wait}\r
+ * - @functionname{mqtt_function_strerror}\r
+ * - @functionname{mqtt_function_operationtype}\r
+ * - @functionname{mqtt_function_issubscribed}\r
+ */\r
+\r
+/**\r
+ * @functionpage{IotMqtt_Init,mqtt,init}\r
+ * @functionpage{IotMqtt_Cleanup,mqtt,cleanup}\r
+ * @functionpage{IotMqtt_ReceiveCallback,mqtt,receivecallback}\r
+ * @functionpage{IotMqtt_Connect,mqtt,connect}\r
+ * @functionpage{IotMqtt_Disconnect,mqtt,disconnect}\r
+ * @functionpage{IotMqtt_Subscribe,mqtt,subscribe}\r
+ * @functionpage{IotMqtt_TimedSubscribe,mqtt,timedsubscribe}\r
+ * @functionpage{IotMqtt_Unsubscribe,mqtt,unsubscribe}\r
+ * @functionpage{IotMqtt_TimedUnsubscribe,mqtt,timedunsubscribe}\r
+ * @functionpage{IotMqtt_Publish,mqtt,publish}\r
+ * @functionpage{IotMqtt_TimedPublish,mqtt,timedpublish}\r
+ * @functionpage{IotMqtt_Wait,mqtt,wait}\r
+ * @functionpage{IotMqtt_strerror,mqtt,strerror}\r
+ * @functionpage{IotMqtt_OperationType,mqtt,operationtype}\r
+ * @functionpage{IotMqtt_IsSubscribed,mqtt,issubscribed}\r
+ */\r
+\r
+/**\r
+ * @brief One-time initialization function for the MQTT library.\r
+ *\r
+ * This function performs setup of the MQTT library. <b>It must be called\r
+ * once (and only once) before calling any other MQTT function.</b> Calling this\r
+ * function more than once without first calling @ref mqtt_function_cleanup\r
+ * may result in a crash.\r
+ *\r
+ * @return One of the following:\r
+ * - #IOT_MQTT_SUCCESS\r
+ * - #IOT_MQTT_INIT_FAILED\r
+ *\r
+ * @warning No thread-safety guarantees are provided for this function.\r
+ *\r
+ * @see @ref mqtt_function_cleanup\r
+ */\r
+/* @[declare_mqtt_init] */\r
+IotMqttError_t IotMqtt_Init( void );\r
+/* @[declare_mqtt_init] */\r
+\r
+/**\r
+ * @brief One-time deinitialization function for the MQTT library.\r
+ *\r
+ * This function frees resources taken in @ref mqtt_function_init. It should be\r
+ * called after [closing all MQTT connections](@ref mqtt_function_disconnect) to\r
+ * clean up the MQTT library. After this function returns, @ref mqtt_function_init\r
+ * must be called again before calling any other MQTT function.\r
+ *\r
+ * @warning No thread-safety guarantees are provided for this function. Do not\r
+ * call this function if any MQTT connections are open!\r
+ *\r
+ * @see @ref mqtt_function_init\r
+ */\r
+/* @[declare_mqtt_cleanup] */\r
+void IotMqtt_Cleanup( void );\r
+/* @[declare_mqtt_cleanup] */\r
+\r
+/**\r
+ * @brief Network receive callback for the MQTT library.\r
+ *\r
+ * This function should be called by the system whenever data is available for\r
+ * the MQTT library.\r
+ *\r
+ * @param[in] pNetworkConnection The network connection associated with the MQTT\r
+ * connection, passed by the network stack.\r
+ * @param[in] pReceiveContext A pointer to the MQTT connection handle for which\r
+ * the packet was received.\r
+ */\r
+/* @[declare_mqtt_receivecallback] */\r
+void IotMqtt_ReceiveCallback( void * pNetworkConnection,\r
+                              void * pReceiveContext );\r
+/* @[declare_mqtt_receivecallback] */\r
+\r
+/**\r
+ * @brief Establish a new MQTT connection.\r
+ *\r
+ * This function opens a connection between a new MQTT client and an MQTT server\r
+ * (also called a <i>broker</i>). MQTT connections are established on top of transport\r
+ * layer protocols (such as TCP/IP), and optionally, application layer security\r
+ * protocols (such as TLS). The MQTT packet that establishes a connection is called\r
+ * the MQTT CONNECT packet. After @ref mqtt_function_init, this function must be\r
+ * called before any other MQTT library function.\r
+ *\r
+ * If [pConnectInfo->cleanSession](@ref IotMqttConnectInfo_t.cleanSession) is `true`,\r
+ * this function establishes a clean MQTT session. Subscriptions and unacknowledged\r
+ * PUBLISH messages will be discarded when the connection is closed.\r
+ *\r
+ * If [pConnectInfo->cleanSession](@ref IotMqttConnectInfo_t.cleanSession) is `false`,\r
+ * this function establishes (or re-establishes) a persistent MQTT session. The parameters\r
+ * [pConnectInfo->pPreviousSubscriptions](@ref IotMqttConnectInfo_t.pPreviousSubscriptions)\r
+ * and [pConnectInfo->previousSubscriptionCount](@ref IotMqttConnectInfo_t.previousSubscriptionCount)\r
+ * may be used to restore subscriptions present in a re-established persistent session.\r
+ * Any restored subscriptions <b>MUST</b> have been present in the persistent session;\r
+ * <b>this function does not send an MQTT SUBSCRIBE packet!</b>\r
+ *\r
+ * This MQTT library is network agnostic, meaning it has no knowledge of the\r
+ * underlying network protocol carrying the MQTT packets. It interacts with the\r
+ * network through a network abstraction layer, allowing it to be used with many\r
+ * different network stacks. The network abstraction layer is established\r
+ * per-connection, allowing every #IotMqttConnection_t to use a different network\r
+ * stack. The parameter `pNetworkInterface` sets up the network abstraction layer\r
+ * for an MQTT connection; see the documentation on #IotMqttNetworkInfo_t for details\r
+ * on its members.\r
+ *\r
+ * The `pConnectInfo` parameter provides the contents of the MQTT CONNECT packet.\r
+ * Most members [are defined by the MQTT spec.](@ref IotMqttConnectInfo_t). The\r
+ * [pConnectInfo->pWillInfo](@ref IotMqttConnectInfo_t.pWillInfo) member provides\r
+ * information on a Last Will and Testament (LWT) message to be published if the\r
+ * MQTT connection is closed without [sending a DISCONNECT packet]\r
+ * (@ref mqtt_function_disconnect). Unlike other PUBLISH\r
+ * messages, a LWT message payload is limited to 65535 bytes in length. Additionally,\r
+ * the retry [interval](@ref IotMqttPublishInfo_t.retryMs) and [limit]\r
+ * (@ref IotMqttPublishInfo_t.retryLimit) members of #IotMqttPublishInfo_t\r
+ * are ignored for LWT messages. The LWT message is optional; `pWillInfo` may be NULL.\r
+ *\r
+ * Unlike @ref mqtt_function_publish, @ref mqtt_function_subscribe, and\r
+ * @ref mqtt_function_unsubscribe, this function is always blocking. Additionally,\r
+ * because the MQTT connection acknowledgement packet (CONNACK packet) does not\r
+ * contain any information on <i>which</i> CONNECT packet it acknowledges, only one\r
+ * CONNECT operation may be in progress at any time. This means that parallel\r
+ * threads making calls to @ref mqtt_function_connect will be serialized to send\r
+ * their CONNECT packets one-by-one.\r
+ *\r
+ * @param[in] pNetworkInfo Information on the transport-layer network connection\r
+ * to use with the MQTT connection.\r
+ * @param[in] pConnectInfo MQTT connection setup parameters.\r
+ * @param[in] timeoutMs If the MQTT server does not accept the connection within\r
+ * this timeout, this function returns #IOT_MQTT_TIMEOUT.\r
+ * @param[out] pMqttConnection Set to a newly-initialized MQTT connection handle\r
+ * if this function succeeds.\r
+ *\r
+ * @return One of the following:\r
+ * - #IOT_MQTT_SUCCESS\r
+ * - #IOT_MQTT_BAD_PARAMETER\r
+ * - #IOT_MQTT_NO_MEMORY\r
+ * - #IOT_MQTT_NETWORK_ERROR\r
+ * - #IOT_MQTT_SCHEDULING_ERROR\r
+ * - #IOT_MQTT_BAD_RESPONSE\r
+ * - #IOT_MQTT_TIMEOUT\r
+ * - #IOT_MQTT_SERVER_REFUSED\r
+ *\r
+ * <b>Example</b>\r
+ * @code{c}\r
+ * // An initialized and connected network connection.\r
+ * IotNetworkConnection_t pNetworkConnection;\r
+ *\r
+ * // Parameters to MQTT connect.\r
+ * IotMqttConnection_t mqttConnection = IOT_MQTT_CONNECTION_INITIALIZER;\r
+ * IotMqttNetworkInfo_t networkInfo = IOT_MQTT_NETWORK_INFO_INITIALIZER;\r
+ * IotMqttConnectInfo_t connectInfo = IOT_MQTT_CONNECT_INFO_INITIALIZER;\r
+ * IotMqttPublishInfo_t willInfo = IOT_MQTT_PUBLISH_INFO_INITIALIZER;\r
+ *\r
+ * // Example network abstraction types.\r
+ * IotNetworkServerInfo_t serverInfo = { ... };\r
+ * IotNetworkCredentialInfo_t credentialInfo = { ... };\r
+ * IotNetworkInterface_t networkInterface = { ... };\r
+ *\r
+ * // Example using a generic network implementation.\r
+ * networkInfo.createNetworkConnection = true;\r
+ * networkInfo.pNetworkServerInfo = &serverInfo;\r
+ * networkInfo.pNetworkCredentialInfo = &credentialInfo;\r
+ * networkInfo.pNetworkInterface = &networkInterface;\r
+ *\r
+ * // Set the members of the connection info (password and username not used).\r
+ * connectInfo.cleanSession = true;\r
+ * connectInfo.keepAliveSeconds = 30;\r
+ * connectInfo.pClientIdentifier = "uniqueclientidentifier";\r
+ * connectInfo.clientIdentifierLength = 22;\r
+ *\r
+ * // Set the members of the will info (retain and retry not used).\r
+ * willInfo.qos = IOT_MQTT_QOS_1;\r
+ * willInfo.pTopicName = "will/topic/name";\r
+ * willInfo.topicNameLength = 15;\r
+ * willInfo.pPayload = "MQTT client unexpectedly disconnected.";\r
+ * willInfo.payloadLength = 38;\r
+ *\r
+ * // Set the pointer to the will info.\r
+ * connectInfo.pWillInfo = &willInfo;\r
+ *\r
+ * // Call CONNECT with a 5 second block time. Should return\r
+ * // IOT_MQTT_SUCCESS when successful.\r
+ * IotMqttError_t result = IotMqtt_Connect( &networkInfo,\r
+ *                                          &connectInfo,\r
+ *                                          5000,\r
+ *                                          &mqttConnection );\r
+ *\r
+ * if( result == IOT_MQTT_SUCCESS )\r
+ * {\r
+ *     // Do something with the MQTT connection...\r
+ *\r
+ *     // Clean up and close the MQTT connection once it's no longer needed.\r
+ *     IotMqtt_Disconnect( mqttConnection, 0 );\r
+ * }\r
+ * @endcode\r
+ */\r
+/* @[declare_mqtt_connect] */\r
+IotMqttError_t IotMqtt_Connect( const IotMqttNetworkInfo_t * pNetworkInfo,\r
+                                const IotMqttConnectInfo_t * pConnectInfo,\r
+                                uint32_t timeoutMs,\r
+                                IotMqttConnection_t * const pMqttConnection );\r
+/* @[declare_mqtt_connect] */\r
+\r
+/**\r
+ * @brief Closes an MQTT connection and frees resources.\r
+ *\r
+ * This function closes an MQTT connection and should only be called once\r
+ * the MQTT connection is no longer needed. Its exact behavior depends on the\r
+ * `flags` parameter.\r
+ *\r
+ * Normally, `flags` should be `0`. This gracefully shuts down an MQTT\r
+ * connection by sending an MQTT DISCONNECT packet. Any [network close function]\r
+ * (@ref IotNetworkInterface_t::close) provided [when the connection was established]\r
+ * (@ref mqtt_function_connect) will also be called. Note that because the MQTT server\r
+ * will not acknowledge a DISCONNECT packet, the client has no way of knowing if\r
+ * the server received the DISCONNECT packet. In the case where the DISCONNECT\r
+ * packet is lost in transport, any Last Will and Testament (LWT) message established\r
+ * with the connection may be published. However, if the DISCONNECT reaches the\r
+ * MQTT server, the LWT message will be discarded and not published.\r
+ *\r
+ * Should the underlying network connection become unusable, this function should\r
+ * be called with `flags` set to #IOT_MQTT_FLAG_CLEANUP_ONLY. In this case, no\r
+ * DISCONNECT packet will be sent, though the [network close function](@ref IotNetworkInterface_t::close)\r
+ * will still be called. This function will only free the resources used by the MQTT\r
+ * connection; it still must be called even if the network is offline to avoid leaking\r
+ * resources.\r
+ *\r
+ * Once this function is called, its parameter `mqttConnection` should no longer\r
+ * be used.\r
+ *\r
+ * @param[in] mqttConnection The MQTT connection to close and clean up.\r
+ * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
+ */\r
+/* @[declare_mqtt_disconnect] */\r
+void IotMqtt_Disconnect( IotMqttConnection_t mqttConnection,\r
+                         uint32_t flags );\r
+/* @[declare_mqtt_disconnect] */\r
+\r
+/**\r
+ * @brief Subscribes to the given array of topic filters and receive an asynchronous\r
+ * notification when the subscribe completes.\r
+ *\r
+ * This function transmits an MQTT SUBSCRIBE packet to the server. A SUBSCRIBE\r
+ * packet notifies the server to send any matching PUBLISH messages to this client.\r
+ * A single SUBSCRIBE packet may carry more than one topic filter, hence the\r
+ * parameters to this function include an array of [subscriptions]\r
+ * (@ref IotMqttSubscription_t).\r
+ *\r
+ * An MQTT subscription has two pieces:\r
+ * 1. The subscription topic filter registered with the MQTT server. The MQTT\r
+ * SUBSCRIBE packet sent from this client to server notifies the server to send\r
+ * messages matching the given topic filters to this client.\r
+ * 2. The [callback function](@ref IotMqttCallbackInfo_t.function) that this\r
+ * client will invoke when an incoming message is received. The callback function\r
+ * notifies applications of an incoming PUBLISH message.\r
+ *\r
+ * The helper function @ref mqtt_function_issubscribed can be used to check if a\r
+ * [callback function](@ref IotMqttCallbackInfo_t.function) is registered for\r
+ * a particular topic filter.\r
+ *\r
+ * To modify an already-registered subscription callback, call this function with\r
+ * a new `pSubscriptionList`. Any topic filters in `pSubscriptionList` that already\r
+ * have a registered callback will be replaced with the new values in `pSubscriptionList`.\r
+ *\r
+ * @attention QoS 2 subscriptions are currently unsupported. Only 0 or 1 are valid\r
+ * for subscription QoS.\r
+ *\r
+ * @param[in] mqttConnection The MQTT connection to use for the subscription.\r
+ * @param[in] pSubscriptionList Pointer to the first element in the array of\r
+ * subscriptions.\r
+ * @param[in] subscriptionCount The number of elements in pSubscriptionList.\r
+ * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
+ * @param[in] pCallbackInfo Asynchronous notification of this function's completion.\r
+ * @param[out] pSubscribeOperation Set to a handle by which this operation may be\r
+ * referenced after this function returns. This reference is invalidated once\r
+ * the subscription operation completes.\r
+ *\r
+ * @return This function will return #IOT_MQTT_STATUS_PENDING upon success.\r
+ * @return Upon completion of the subscription (either through an\r
+ * #IotMqttCallbackInfo_t or @ref mqtt_function_wait), the status will be one of:\r
+ * - #IOT_MQTT_SUCCESS\r
+ * - #IOT_MQTT_NETWORK_ERROR\r
+ * - #IOT_MQTT_SCHEDULING_ERROR\r
+ * - #IOT_MQTT_BAD_RESPONSE\r
+ * - #IOT_MQTT_SERVER_REFUSED\r
+ * @return If this function fails before queuing a subscribe operation, it will return\r
+ * one of:\r
+ * - #IOT_MQTT_BAD_PARAMETER\r
+ * - #IOT_MQTT_NO_MEMORY\r
+ *\r
+ * @see @ref mqtt_function_timedsubscribe for a blocking variant of this function.\r
+ * @see @ref mqtt_function_unsubscribe for the function that removes subscriptions.\r
+ *\r
+ * <b>Example</b>\r
+ * @code{c}\r
+ * #define NUMBER_OF_SUBSCRIPTIONS ...\r
+ *\r
+ * // Subscription callback function.\r
+ * void subscriptionCallback( void * pArgument, IotMqttCallbackParam_t * pPublish );\r
+ *\r
+ * // An initialized and connected MQTT connection.\r
+ * IotMqttConnection_t mqttConnection;\r
+ *\r
+ * // Subscription information.\r
+ * pSubscriptions[ NUMBER_OF_SUBSCRIPTIONS ] = { IOT_MQTT_SUBSCRIPTION_INITIALIZER };\r
+ * IotMqttOperation_t lastOperation = IOT_MQTT_OPERATION_INITIALIZER;\r
+ *\r
+ * // Set the subscription information.\r
+ * for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )\r
+ * {\r
+ *     pSubscriptions[ i ].qos = IOT_MQTT_QOS_1;\r
+ *     pSubscriptions[ i ].pTopicFilter = "some/topic/filter";\r
+ *     pSubscriptions[ i ].topicLength = ( uint16_t ) strlen( pSubscriptions[ i ].pTopicFilter );\r
+ *     pSubscriptions[ i ].callback.function = subscriptionCallback;\r
+ * }\r
+ *\r
+ * IotMqttError_t result = IotMqtt_Subscribe( mqttConnection,\r
+ *                                            pSubscriptions,\r
+ *                                            NUMBER_OF_SUBSCRIPTIONS,\r
+ *                                            IOT_MQTT_FLAG_WAITABLE,\r
+ *                                            NULL,\r
+ *                                            &lastOperation );\r
+ *\r
+ * // Subscribe returns IOT_MQTT_STATUS_PENDING when successful. Wait up to\r
+ * // 5 seconds for the operation to complete.\r
+ * if( result == IOT_MQTT_STATUS_PENDING )\r
+ * {\r
+ *     result = IotMqtt_Wait( subscriptionRef, 5000 );\r
+ * }\r
+ *\r
+ * // Check that the subscriptions were successful.\r
+ * if( result == IOT_MQTT_SUCCESS )\r
+ * {\r
+ *     // Wait for messages on the subscription topic filters...\r
+ *\r
+ *     // Unsubscribe once the subscriptions are no longer needed.\r
+ *     result = IotMqtt_Unsubscribe( mqttConnection,\r
+ *                                   pSubscriptions,\r
+ *                                   NUMBER_OF_SUBSCRIPTIONS,\r
+ *                                   IOT_MQTT_FLAG_WAITABLE,\r
+ *                                   NULL,\r
+ *                                   &lastOperation );\r
+ *\r
+ *     // UNSUBSCRIBE returns IOT_MQTT_STATUS_PENDING when successful.\r
+ *     // Wait up to 5 seconds for the operation to complete.\r
+ *     if( result == IOT_MQTT_STATUS_PENDING )\r
+ *     {\r
+ *         result = IotMqtt_Wait( lastOperation, 5000 );\r
+ *     }\r
+ * }\r
+ * // Check which subscriptions were rejected by the server.\r
+ * else if( result == IOT_MQTT_SERVER_REFUSED )\r
+ * {\r
+ *     for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )\r
+ *     {\r
+ *         if( IotMqtt_IsSubscribed( mqttConnection,\r
+ *                                   pSubscriptions[ i ].pTopicFilter,\r
+ *                                   pSubscriptions[ i ].topicFilterLength,\r
+ *                                   NULL ) == false )\r
+ *         {\r
+ *             // This subscription was rejected.\r
+ *         }\r
+ *     }\r
+ * }\r
+ * @endcode\r
+ */\r
+/* @[declare_mqtt_subscribe] */\r
+IotMqttError_t IotMqtt_Subscribe( IotMqttConnection_t mqttConnection,\r
+                                  const IotMqttSubscription_t * pSubscriptionList,\r
+                                  size_t subscriptionCount,\r
+                                  uint32_t flags,\r
+                                  const IotMqttCallbackInfo_t * pCallbackInfo,\r
+                                  IotMqttOperation_t * pSubscribeOperation );\r
+/* @[declare_mqtt_subscribe] */\r
+\r
+/**\r
+ * @brief Subscribes to the given array of topic filters with a timeout.\r
+ *\r
+ * This function transmits an MQTT SUBSCRIBE packet to the server, then waits for\r
+ * a server response to the packet. Internally, this function is a call to @ref\r
+ * mqtt_function_subscribe followed by @ref mqtt_function_wait. See @ref\r
+ * mqtt_function_subscribe for more information about the MQTT SUBSCRIBE operation.\r
+ *\r
+ * @attention QoS 2 subscriptions are currently unsupported. Only 0 or 1 are valid\r
+ * for subscription QoS.\r
+ *\r
+ * @param[in] mqttConnection The MQTT connection to use for the subscription.\r
+ * @param[in] pSubscriptionList Pointer to the first element in the array of\r
+ * subscriptions.\r
+ * @param[in] subscriptionCount The number of elements in pSubscriptionList.\r
+ * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
+ * Currently, flags are ignored by this function; this parameter is for\r
+ * future-compatibility.\r
+ * @param[in] timeoutMs If the MQTT server does not acknowledge the subscriptions within\r
+ * this timeout, this function returns #IOT_MQTT_TIMEOUT.\r
+ *\r
+ * @return One of the following:\r
+ * - #IOT_MQTT_SUCCESS\r
+ * - #IOT_MQTT_BAD_PARAMETER\r
+ * - #IOT_MQTT_NO_MEMORY\r
+ * - #IOT_MQTT_NETWORK_ERROR\r
+ * - #IOT_MQTT_SCHEDULING_ERROR\r
+ * - #IOT_MQTT_BAD_RESPONSE\r
+ * - #IOT_MQTT_TIMEOUT\r
+ * - #IOT_MQTT_SERVER_REFUSED\r
+ */\r
+/* @[declare_mqtt_timedsubscribe] */\r
+IotMqttError_t IotMqtt_TimedSubscribe( IotMqttConnection_t mqttConnection,\r
+                                       const IotMqttSubscription_t * pSubscriptionList,\r
+                                       size_t subscriptionCount,\r
+                                       uint32_t flags,\r
+                                       uint32_t timeoutMs );\r
+/* @[declare_mqtt_timedsubscribe] */\r
+\r
+/**\r
+ * @brief Unsubscribes from the given array of topic filters and receive an asynchronous\r
+ * notification when the unsubscribe completes.\r
+ *\r
+ * This function transmits an MQTT UNSUBSCRIBE packet to the server. An UNSUBSCRIBE\r
+ * packet removes registered topic filters from the server. After unsubscribing,\r
+ * the server will no longer send messages on these topic filters to the client.\r
+ *\r
+ * Corresponding [subscription callback functions](@ref IotMqttCallbackInfo_t.function)\r
+ * are also removed from the MQTT connection. These subscription callback functions\r
+ * will be removed even if the MQTT UNSUBSCRIBE packet fails to send.\r
+ *\r
+ * @param[in] mqttConnection The MQTT connection used for the subscription.\r
+ * @param[in] pSubscriptionList Pointer to the first element in the array of\r
+ * subscriptions.\r
+ * @param[in] subscriptionCount The number of elements in pSubscriptionList.\r
+ * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
+ * @param[in] pCallbackInfo Asynchronous notification of this function's completion.\r
+ * @param[out] pUnsubscribeOperation Set to a handle by which this operation may be\r
+ * referenced after this function returns. This reference is invalidated once\r
+ * the unsubscribe operation completes.\r
+ *\r
+ * @return This function will return #IOT_MQTT_STATUS_PENDING upon success.\r
+ * @return Upon completion of the unsubscribe (either through an\r
+ * #IotMqttCallbackInfo_t or @ref mqtt_function_wait), the status will be one of:\r
+ * - #IOT_MQTT_SUCCESS\r
+ * - #IOT_MQTT_NETWORK_ERROR\r
+ * - #IOT_MQTT_SCHEDULING_ERROR\r
+ * - #IOT_MQTT_BAD_RESPONSE\r
+ * @return If this function fails before queuing an unsubscribe operation, it will return\r
+ * one of:\r
+ * - #IOT_MQTT_BAD_PARAMETER\r
+ * - #IOT_MQTT_NO_MEMORY\r
+ *\r
+ * @see @ref mqtt_function_timedsubscribe for a blocking variant of this function.\r
+ * @see @ref mqtt_function_subscribe for the function that adds subscriptions.\r
+ */\r
+/* @[declare_mqtt_unsubscribe] */\r
+IotMqttError_t IotMqtt_Unsubscribe( IotMqttConnection_t mqttConnection,\r
+                                    const IotMqttSubscription_t * pSubscriptionList,\r
+                                    size_t subscriptionCount,\r
+                                    uint32_t flags,\r
+                                    const IotMqttCallbackInfo_t * pCallbackInfo,\r
+                                    IotMqttOperation_t * pUnsubscribeOperation );\r
+/* @[declare_mqtt_unsubscribe] */\r
+\r
+/**\r
+ * @brief Unsubscribes from a given array of topic filters with a timeout.\r
+ *\r
+ * This function transmits an MQTT UNSUBSCRIBE packet to the server, then waits\r
+ * for a server response to the packet. Internally, this function is a call to\r
+ * @ref mqtt_function_unsubscribe followed by @ref mqtt_function_wait. See @ref\r
+ * mqtt_function_unsubscribe for more information about the MQTT UNSUBSCRIBE\r
+ * operation.\r
+ *\r
+ * @param[in] mqttConnection The MQTT connection used for the subscription.\r
+ * @param[in] pSubscriptionList Pointer to the first element in the array of\r
+ * subscriptions.\r
+ * @param[in] subscriptionCount The number of elements in pSubscriptionList.\r
+ * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
+ * Currently, flags are ignored by this function; this parameter is for\r
+ * future-compatibility.\r
+ * @param[in] timeoutMs If the MQTT server does not acknowledge the UNSUBSCRIBE within\r
+ * this timeout, this function returns #IOT_MQTT_TIMEOUT.\r
+ *\r
+ * @return One of the following:\r
+ * - #IOT_MQTT_SUCCESS\r
+ * - #IOT_MQTT_BAD_PARAMETER\r
+ * - #IOT_MQTT_NO_MEMORY\r
+ * - #IOT_MQTT_NETWORK_ERROR\r
+ * - #IOT_MQTT_SCHEDULING_ERROR\r
+ * - #IOT_MQTT_BAD_RESPONSE\r
+ */\r
+/* @[declare_mqtt_timedunsubscribe] */\r
+IotMqttError_t IotMqtt_TimedUnsubscribe( IotMqttConnection_t mqttConnection,\r
+                                         const IotMqttSubscription_t * pSubscriptionList,\r
+                                         size_t subscriptionCount,\r
+                                         uint32_t flags,\r
+                                         uint32_t timeoutMs );\r
+/* @[declare_mqtt_timedunsubscribe] */\r
+\r
+/**\r
+ * @brief Publishes a message to the given topic name and receive an asynchronous\r
+ * notification when the publish completes.\r
+ *\r
+ * This function transmits an MQTT PUBLISH packet to the server. A PUBLISH packet\r
+ * contains a payload and a topic name. Any clients with a subscription on a\r
+ * topic filter matching the PUBLISH topic name will receive a copy of the\r
+ * PUBLISH packet from the server.\r
+ *\r
+ * If a PUBLISH packet fails to reach the server and it is not a QoS 0 message,\r
+ * it will be retransmitted. See #IotMqttPublishInfo_t for a description\r
+ * of the retransmission strategy.\r
+ *\r
+ * @attention QoS 2 messages are currently unsupported. Only 0 or 1 are valid\r
+ * for message QoS.\r
+ *\r
+ * @param[in] mqttConnection The MQTT connection to use for the publish.\r
+ * @param[in] pPublishInfo MQTT publish parameters.\r
+ * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
+ * @param[in] pCallbackInfo Asynchronous notification of this function's completion.\r
+ * @param[out] pPublishOperation Set to a handle by which this operation may be\r
+ * referenced after this function returns. This reference is invalidated once\r
+ * the publish operation completes.\r
+ *\r
+ * @return This function will return #IOT_MQTT_STATUS_PENDING upon success for\r
+ * QoS 1 publishes. For a QoS 0 publish it returns #IOT_MQTT_SUCCESS upon\r
+ * success.\r
+ * @return Upon completion of a QoS 1 publish (either through an\r
+ * #IotMqttCallbackInfo_t or @ref mqtt_function_wait), the status will be one of:\r
+ * - #IOT_MQTT_SUCCESS\r
+ * - #IOT_MQTT_NETWORK_ERROR\r
+ * - #IOT_MQTT_SCHEDULING_ERROR\r
+ * - #IOT_MQTT_BAD_RESPONSE\r
+ * - #IOT_MQTT_RETRY_NO_RESPONSE (if [pPublishInfo->retryMs](@ref IotMqttPublishInfo_t.retryMs)\r
+ * and [pPublishInfo->retryLimit](@ref IotMqttPublishInfo_t.retryLimit) were set).\r
+ * @return If this function fails before queuing an publish operation (regardless\r
+ * of QoS), it will return one of:\r
+ * - #IOT_MQTT_BAD_PARAMETER\r
+ * - #IOT_MQTT_NO_MEMORY\r
+ *\r
+ * @note The parameters `pCallbackInfo` and `pPublishOperation` should only be used for QoS\r
+ * 1 publishes. For QoS 0, they should both be `NULL`.\r
+ *\r
+ * @see @ref mqtt_function_timedpublish for a blocking variant of this function.\r
+ *\r
+ * <b>Example</b>\r
+ * @code{c}\r
+ * // An initialized and connected MQTT connection.\r
+ * IotMqttConnection_t mqttConnection;\r
+ *\r
+ * // Publish information.\r
+ * IotMqttPublishInfo_t publishInfo = IOT_MQTT_PUBLISH_INFO_INITIALIZER;\r
+ *\r
+ * // Set the publish information. QoS 0 example (retain not used):\r
+ * publishInfo.qos = IOT_MQTT_QOS_0;\r
+ * publishInfo.pTopicName = "some/topic/name";\r
+ * publishInfo.topicNameLength = 15;\r
+ * publishInfo.pPayload = "payload";\r
+ * publishInfo.payloadLength = 8;\r
+ *\r
+ * // QoS 0 publish should return IOT_MQTT_SUCCESS upon success.\r
+ * IotMqttError_t qos0Result = IotMqtt_Publish( mqttConnection,\r
+ *                                              &publishInfo,\r
+ *                                              0,\r
+ *                                              NULL,\r
+ *                                              NULL );\r
+ *\r
+ * // QoS 1 with retry example (using same topic name and payload as QoS 0 example):\r
+ * IotMqttOperation_t qos1Operation = IOT_MQTT_OPERATION_INITIALIZER;\r
+ * publishInfo.qos = IOT_MQTT_QOS_1;\r
+ * publishInfo.retryMs = 1000; // Retry if no response is received in 1 second.\r
+ * publishInfo.retryLimit = 5; // Retry up to 5 times.\r
+ *\r
+ * // QoS 1 publish should return IOT_MQTT_STATUS_PENDING upon success.\r
+ * IotMqttError_t qos1Result = IotMqtt_Publish( mqttConnection,\r
+ *                                              &publishInfo,\r
+ *                                              IOT_MQTT_FLAG_WAITABLE,\r
+ *                                              NULL,\r
+ *                                              &qos1Operation );\r
+ *\r
+ * // Wait up to 5 seconds for the publish to complete.\r
+ * if( qos1Result == IOT_MQTT_STATUS_PENDING )\r
+ * {\r
+ *     qos1Result = IotMqtt_Wait( qos1Operation, 5000 );\r
+ * }\r
+ * @endcode\r
+ */\r
+/* @[declare_mqtt_publish] */\r
+IotMqttError_t IotMqtt_Publish( IotMqttConnection_t mqttConnection,\r
+                                const IotMqttPublishInfo_t * pPublishInfo,\r
+                                uint32_t flags,\r
+                                const IotMqttCallbackInfo_t * pCallbackInfo,\r
+                                IotMqttOperation_t * pPublishOperation );\r
+/* @[declare_mqtt_publish] */\r
+\r
+/**\r
+ * @brief Publish a message to the given topic name with a timeout.\r
+ *\r
+ * This function transmits an MQTT PUBLISH packet to the server, then waits for\r
+ * a server response to the packet. Internally, this function is a call to @ref\r
+ * mqtt_function_publish followed by @ref mqtt_function_wait. See @ref\r
+ * mqtt_function_publish for more information about the MQTT PUBLISH operation.\r
+ *\r
+ * @attention QoS 2 messages are currently unsupported. Only 0 or 1 are valid\r
+ * for message QoS.\r
+ *\r
+ * @param[in] mqttConnection The MQTT connection to use for the publish.\r
+ * @param[in] pPublishInfo MQTT publish parameters.\r
+ * @param[in] flags Flags which modify the behavior of this function. See @ref mqtt_constants_flags.\r
+ * Currently, flags are ignored by this function; this parameter is for\r
+ * future-compatibility.\r
+ * @param[in] timeoutMs If the MQTT server does not acknowledge a QoS 1 PUBLISH\r
+ * within this timeout, this function returns #IOT_MQTT_TIMEOUT. This parameter\r
+ * is ignored for QoS 0 PUBLISH messages.\r
+ *\r
+ * @return One of the following:\r
+ * - #IOT_MQTT_SUCCESS\r
+ * - #IOT_MQTT_BAD_PARAMETER\r
+ * - #IOT_MQTT_NO_MEMORY\r
+ * - #IOT_MQTT_NETWORK_ERROR\r
+ * - #IOT_MQTT_SCHEDULING_ERROR\r
+ * - #IOT_MQTT_BAD_RESPONSE\r
+ * - #IOT_MQTT_RETRY_NO_RESPONSE (if [pPublishInfo->retryMs](@ref IotMqttPublishInfo_t.retryMs)\r
+ * and [pPublishInfo->retryLimit](@ref IotMqttPublishInfo_t.retryLimit) were set).\r
+ */\r
+/* @[declare_mqtt_timedpublish] */\r
+IotMqttError_t IotMqtt_TimedPublish( IotMqttConnection_t mqttConnection,\r
+                                     const IotMqttPublishInfo_t * pPublishInfo,\r
+                                     uint32_t flags,\r
+                                     uint32_t timeoutMs );\r
+/* @[declare_mqtt_timedpublish] */\r
+\r
+/**\r
+ * @brief Waits for an operation to complete.\r
+ *\r
+ * This function blocks to wait for a [subscribe](@ref mqtt_function_subscribe),\r
+ * [unsubscribe](@ref mqtt_function_unsubscribe), or [publish]\r
+ * (@ref mqtt_function_publish) to complete. These operations are by default\r
+ * asynchronous; the function calls queue an operation for processing, and a\r
+ * callback is invoked once the operation is complete.\r
+ *\r
+ * To use this function, the flag #IOT_MQTT_FLAG_WAITABLE must have been\r
+ * set in the operation's function call. Additionally, this function must always\r
+ * be called with any waitable operation to clean up resources.\r
+ *\r
+ * Regardless of its return value, this function always clean up resources used\r
+ * by the waitable operation. This means `reference` is invalidated as soon as\r
+ * this function returns, even if it returns #IOT_MQTT_TIMEOUT or another error.\r
+ *\r
+ * @param[in] operation Reference to the operation to wait for. The flag\r
+ * #IOT_MQTT_FLAG_WAITABLE must have been set for this operation.\r
+ * @param[in] timeoutMs How long to wait before returning #IOT_MQTT_TIMEOUT.\r
+ *\r
+ * @return The return value of this function depends on the MQTT operation associated\r
+ * with `reference`. See #IotMqttError_t for possible return values.\r
+ *\r
+ * <b>Example</b>\r
+ * @code{c}\r
+ * // Operation reference and timeout.\r
+ * IotMqttOperation_t publishOperation = IOT_MQTT_OPERATION_INITIALIZER;\r
+ * uint32_t timeoutMs = 5000; // 5 seconds\r
+ *\r
+ * // MQTT operation to wait for.\r
+ * IotMqttError_t result = IotMqtt_Publish( mqttConnection,\r
+ *                                          &publishInfo,\r
+ *                                          IOT_MQTT_FLAG_WAITABLE,\r
+ *                                          NULL,\r
+ *                                          &publishOperation );\r
+ *\r
+ * // Publish should have returned IOT_MQTT_STATUS_PENDING. The call to wait\r
+ * // returns once the result of the publish is available or the timeout expires.\r
+ * if( result == IOT_MQTT_STATUS_PENDING )\r
+ * {\r
+ *     result = IotMqtt_Wait( publishOperation, timeoutMs );\r
+ *\r
+ *     // After the call to wait, the result of the publish is known\r
+ *     // (not IOT_MQTT_STATUS_PENDING).\r
+ *     assert( result != IOT_MQTT_STATUS_PENDING );\r
+ * }\r
+ * @endcode\r
+ */\r
+/* @[declare_mqtt_wait] */\r
+IotMqttError_t IotMqtt_Wait( IotMqttOperation_t operation,\r
+                             uint32_t timeoutMs );\r
+/* @[declare_mqtt_wait] */\r
+\r
+/*-------------------------- MQTT helper functions --------------------------*/\r
+\r
+/**\r
+ * @brief Returns a string that describes an #IotMqttError_t.\r
+ *\r
+ * Like the POSIX's `strerror`, this function returns a string describing a\r
+ * return code. In this case, the return code is an MQTT library error code,\r
+ * `status`.\r
+ *\r
+ * The string returned by this function <b>MUST</b> be treated as read-only: any\r
+ * attempt to modify its contents may result in a crash. Therefore, this function\r
+ * is limited to usage in logging.\r
+ *\r
+ * @param[in] status The status to describe.\r
+ *\r
+ * @return A read-only string that describes `status`.\r
+ *\r
+ * @warning The string returned by this function must never be modified.\r
+ */\r
+/* @[declare_mqtt_strerror] */\r
+const char * IotMqtt_strerror( IotMqttError_t status );\r
+/* @[declare_mqtt_strerror] */\r
+\r
+/**\r
+ * @brief Returns a string that describes an #IotMqttOperationType_t.\r
+ *\r
+ * This function returns a string describing an MQTT operation type, `operation`.\r
+ *\r
+ * The string returned by this function <b>MUST</b> be treated as read-only: any\r
+ * attempt to modify its contents may result in a crash. Therefore, this function\r
+ * is limited to usage in logging.\r
+ *\r
+ * @param[in] operation The operation to describe.\r
+ *\r
+ * @return A read-only string that describes `operation`.\r
+ *\r
+ * @warning The string returned by this function must never be modified.\r
+ */\r
+/* @[declare_mqtt_operationtype] */\r
+const char * IotMqtt_OperationType( IotMqttOperationType_t operation );\r
+/* @[declare_mqtt_operationtype] */\r
+\r
+/**\r
+ * @brief Check if an MQTT connection has a subscription for a topic filter.\r
+ *\r
+ * This function checks whether an MQTT connection `mqttConnection` has a\r
+ * subscription callback registered for a topic filter `pTopicFilter`. If a\r
+ * subscription callback is found, its details are copied into the output parameter\r
+ * `pCurrentSubscription`. This subscription callback will be invoked for incoming\r
+ * PUBLISH messages on `pTopicFilter`.\r
+ *\r
+ * <b>The check for a matching subscription is only performed client-side</b>;\r
+ * therefore, this function should not be relied upon for perfect accuracy. For\r
+ * example, this function may return an incorrect result if the MQTT server\r
+ * crashes and drops subscriptions without informing the client.\r
+ *\r
+ * Note that an MQTT connection's subscriptions might change between the time this\r
+ * function checks the subscription list and its caller tests the return value.\r
+ * This function certainly should not be used concurrently with any pending SUBSCRIBE\r
+ * or UNSUBSCRIBE operations.\r
+ *\r
+ * One suitable use of this function is to check <i>which</i> subscriptions were rejected\r
+ * if @ref mqtt_function_subscribe returns #IOT_MQTT_SERVER_REFUSED; that return\r
+ * code only means that <i>at least one</i> subscription was rejected.\r
+ *\r
+ * @param[in] mqttConnection The MQTT connection to check.\r
+ * @param[in] pTopicFilter The topic filter to check.\r
+ * @param[in] topicFilterLength Length of `pTopicFilter`.\r
+ * @param[out] pCurrentSubscription If a subscription is found, its details are\r
+ * copied here. This output parameter is only valid if this function returns `true`.\r
+ * Pass `NULL` to ignore.\r
+ *\r
+ * @return `true` if a subscription was found; `false` otherwise.\r
+ *\r
+ * @note The subscription QoS is not stored by the MQTT library; therefore,\r
+ * `pCurrentSubscription->qos` will always be set to #IOT_MQTT_QOS_0.\r
+ */\r
+/* @[declare_mqtt_issubscribed] */\r
+bool IotMqtt_IsSubscribed( IotMqttConnection_t mqttConnection,\r
+                           const char * pTopicFilter,\r
+                           uint16_t topicFilterLength,\r
+                           IotMqttSubscription_t * pCurrentSubscription );\r
+/* @[declare_mqtt_issubscribed] */\r
+\r
+#endif /* ifndef IOT_MQTT_H_ */\r