]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/DemoTasks/SimpleMQTTExamples.c
Remove dependency on secure sockets
[freertos] / FreeRTOS-Plus / Demo / FreeRTOS_IoT_Libraries / mqtt / DemoTasks / SimpleMQTTExamples.c
1 /*\r
2  * FreeRTOS Kernel V10.2.1\r
3  * Copyright (C) 2017 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://www.FreeRTOS.org\r
23  * http://aws.amazon.com/freertos\r
24  *\r
25  * 1 tab == 4 spaces!\r
26  */\r
27 \r
28 /* Standard inclues. */\r
29 #include <string.h>\r
30 #include <stdio.h>\r
31 \r
32 /* Kernel includes. */\r
33 #include "FreeRTOS.h"\r
34 #include "task.h"\r
35 \r
36 /* IoT SDK includes. */\r
37 #include "iot_mqtt.h"\r
38 #include "iot_taskpool.h"\r
39 #include "platform/iot_network_freertos.h"\r
40 \r
41 /**\r
42  * @brief The keep-alive interval used for this example.\r
43  *\r
44  * An MQTT ping request will be sent periodically at this interval.\r
45  */\r
46 #define mqttexampleKEEP_ALIVE_SECONDS           ( 60 )\r
47 \r
48 /**\r
49  * @brief The timeout for MQTT operations in this example.\r
50  */\r
51 #define mqttexampleMQTT_TIMEOUT_MS                      ( 5000 )\r
52 \r
53 /**\r
54  * @brief The MQTT client identifier used in this example.\r
55  */\r
56 #define mqttexampleCLIENT_IDENTIFIER            "mqttexampleclient"\r
57 \r
58 /**\r
59  * @brief Details of the MQTT broker to connect to.\r
60  *\r
61  * @note This example does not use TLS and therefore won't work with AWS IoT.\r
62  *\r
63  */\r
64 #define mqttexampleMQTT_BROKER_ENDPOINT         "test.mosquitto.org"\r
65 #define mqttexampleMQTT_BROKER_PORT                     1883\r
66 \r
67 /**\r
68  * @brief The topic to subscribe and publish to in the example.\r
69  */\r
70 #define mqttexampleTOPIC                                        "example/topic"\r
71 \r
72 /**\r
73  * @brief The MQTT message published in this example.\r
74  */\r
75 #define mqttexampleMESSAGE                                      "Hello World!"\r
76 \r
77 /**\r
78  * @brief Paramters to control the retry behaviour in case a QoS1 publish\r
79  * message gets lost.\r
80  *\r
81  * Retry every minutes up to a maximum of 5 retries.\r
82  */\r
83 #define mqttexamplePUBLISH_RETRY_MS                     ( 1000 )\r
84 #define mqttexamplePUBLISH_RETRY_LIMIT          ( 5 )\r
85 \r
86 /**\r
87  * @brief The bit which is set in the demo task's notification value from the\r
88  * disconnect callback to inform the demo task about the MQTT disconnect.\r
89  */\r
90 #define mqttexampleDISCONNECTED_BIT                     ( 1UL << 0UL )\r
91 \r
92 /**\r
93  * @brief The bit which is set in the demo task's notification value from the\r
94  * publish callback to inform the demo task about the message received from the\r
95  * MQTT broker.\r
96  */\r
97 #define mqttexampleMESSAGE_RECEIVED_BIT         ( 1UL << 1UL )\r
98 /*-----------------------------------------------------------*/\r
99 \r
100 /**\r
101  * @brief The MQTT connection handle used in this example.\r
102  */\r
103 static IotMqttConnection_t xMQTTConnection = IOT_MQTT_CONNECTION_INITIALIZER;\r
104 \r
105 /**\r
106  * @brief Parameters used to create the system task pool.\r
107  */\r
108 static const IotTaskPoolInfo_t xTaskPoolParameters = {\r
109                                                                                                                 /* Minimum number of threads in a task pool.\r
110                                                                                                                  * Note the slimmed down version of the task\r
111                                                                                                                  * pool used by this library does not autoscale\r
112                                                                                                                  * the number of tasks in the pool so in this\r
113                                                                                                                  * case this sets the number of tasks in the\r
114                                                                                                                  * pool. */\r
115                                                                                                                 2,\r
116                                                                                                                 /* Maximum number of threads in a task pool.\r
117                                                                                                                  * Note the slimmed down version of the task\r
118                                                                                                                  * pool used by this library does not autoscale\r
119                                                                                                                  * the number of tasks in the pool so in this\r
120                                                                                                                  * case this parameter is just ignored. */\r
121                                                                                                                 2,\r
122                                                                                                                 /* Stack size for every task pool thread - in\r
123                                                                                                                  * bytes, hence multiplying by the number of bytes\r
124                                                                                                                  * in a word as configMINIMAL_STACK_SIZE is\r
125                                                                                                                  * specified in words. */\r
126                                                                                                                 configMINIMAL_STACK_SIZE * sizeof( portSTACK_TYPE ),\r
127                                                                                                                 /* Priority for every task pool thread. */\r
128                                                                                                                 tskIDLE_PRIORITY,\r
129                                                                                                          };\r
130 /*-----------------------------------------------------------*/\r
131 \r
132 /**\r
133  * @brief The task used to demonstrate the MQTT API.\r
134  *\r
135  * @param[in] pvParameters Parmaters as passed at the time of task creation. Not\r
136  * used in this example.\r
137  */\r
138 static void prvMQTTDemoTask( void *pvParameters );\r
139 \r
140 /**\r
141  * @brief The callback invoked by the MQTT library when the MQTT connection gets\r
142  * disconnected.\r
143  * \r
144  * @param[in] pvCallbackContext Callback context as provided at the time of\r
145  * connect.\r
146  * @param[in] pxCallbackParams Contains the reason why the MQTT connection was\r
147  * disconnected.\r
148  */\r
149 static void prvExample_DisconnectCallback( void * pvCallbackContext,\r
150                                                                                    IotMqttCallbackParam_t * pxCallbackParams );\r
151 \r
152 /**\r
153  * @brief The callback invoked by the MQTT library when a message is received on\r
154  * a subscribed topic from the MQTT broker.\r
155  * \r
156  * @param[in] pvCallbackContext Callback context as provided at the time of\r
157  * subscribe.\r
158  * @param[in] pxCallbackParams Contain the details about the received message - \r
159  * topic on which the message was received, the received message.\r
160  */\r
161 static void prvExample_PublishCallback( void * pvCallbackContext,\r
162                                                                                 IotMqttCallbackParam_t * pxCallbackParams );\r
163 \r
164 /**\r
165  * @brief Connects to the MQTT broker as specified in mqttexampleMQTT_BROKER_ENDPOINT\r
166  * and mqttexampleMQTT_BROKER_PORT.\r
167  * \r
168  * @note This example does not use TLS and therefore will not work with MQTT.\r
169  */\r
170 static void prvMQTTConnect( void );\r
171 \r
172 /**\r
173  * @brief Subscribes to the topic as specified in mqttexampleTOPIC.\r
174  */\r
175 static void prvMQTTSubscribe( void );\r
176 \r
177 /**\r
178  * @brief Publishes a messages mqttexampleMESSAGE on mqttexampleTOPIC topic.\r
179  */\r
180 static void prvMQTTPublish( void );\r
181 \r
182 /**\r
183  * @brief Unsubscribes from the mqttexampleTOPIC topic.\r
184  */\r
185 static void prvMQTTUnsubscribe( void );\r
186 \r
187 /**\r
188  * @brief Disconnects from the MQTT broker gracefully by sending an MQTT\r
189  * DISCONNECT message.\r
190  */\r
191 static void prvMQTTDisconnect( void );\r
192 /*-----------------------------------------------------------*/\r
193 \r
194 static void prvExample_DisconnectCallback( void * pvCallbackContext,\r
195                                                                                    IotMqttCallbackParam_t * pxCallbackParams )\r
196 {\r
197 TaskHandle_t xDemoTaskHandle = ( TaskHandle_t ) pvCallbackContext;\r
198 \r
199         /* Ensure that we initiated the disconnect. */\r
200         configASSERT( pxCallbackParams->u.disconnectReason == IOT_MQTT_DISCONNECT_CALLED );\r
201 \r
202         /* Inform the demo task about the disconnect. */\r
203         xTaskNotify( xDemoTaskHandle,\r
204                                 mqttexampleDISCONNECTED_BIT,\r
205                                 eSetBits /* Set the mqttexampleDISCONNECTED_BIT in the demo task's notification value. */\r
206                                 );\r
207 }\r
208 /*-----------------------------------------------------------*/\r
209 \r
210 static void prvExample_PublishCallback( void * pvCallbackContext,\r
211                                                                                 IotMqttCallbackParam_t * pxCallbackParams )\r
212 {\r
213 TaskHandle_t xDemoTaskHandle = ( TaskHandle_t ) pvCallbackContext;\r
214 \r
215         /* Ensure that the message is received on the expected topic. */\r
216         configASSERT( pxCallbackParams->u.message.info.topicNameLength == strlen( mqttexampleTOPIC ) );\r
217         configASSERT( strncmp( pxCallbackParams->u.message.info.pTopicName,\r
218                                                    mqttexampleTOPIC,\r
219                                                    strlen( mqttexampleTOPIC ) ) == 0 );\r
220 \r
221         /* Ensure that the expected message is received. */\r
222         configASSERT( pxCallbackParams->u.message.info.payloadLength == strlen( mqttexampleMESSAGE ) );\r
223         configASSERT( strncmp( pxCallbackParams->u.message.info.pPayload,\r
224                                                    mqttexampleMESSAGE,\r
225                                                    strlen( mqttexampleMESSAGE ) ) == 0 );\r
226 \r
227         /* Ensure that the message QoS is as expected. */\r
228         configASSERT( pxCallbackParams->u.message.info.qos == IOT_MQTT_QOS_1 );\r
229 \r
230         /* Inform the demo task about the message received from the MQTT broker. */\r
231         xTaskNotify( xDemoTaskHandle,\r
232                                  mqttexampleMESSAGE_RECEIVED_BIT,\r
233                                  eSetBits /* Set the mqttexampleMESSAGE_RECEIVED_BIT in the demo task's notification value. */\r
234                                 );\r
235 }\r
236 /*-----------------------------------------------------------*/\r
237 \r
238 void vStartSimpleMQTTDemo( void )\r
239 {\r
240         /* This example uses a single application task, which in turn is used to\r
241          * connect, subscribe, publish, unsubscribe and disconnect from the MQTT\r
242          * broker. */\r
243         xTaskCreate( prvMQTTDemoTask,                   /* Function that implements the task. */\r
244                                  "MQTTDemo",                            /* Text name for the task - only used for debugging. */\r
245                                  configMINIMAL_STACK_SIZE,      /* Size of stack (in words, not bytes) to allocate for the task. */\r
246                                  NULL,                                          /* Task parameter - not used in this case. */\r
247                                  tskIDLE_PRIORITY,                      /* Task priority, must be between 0 and configMAX_PRIORITIES - 1. */\r
248                                  NULL );                                        /* Used to pass out a handle to the created task - not used in this case. */\r
249 }\r
250 /*-----------------------------------------------------------*/\r
251 \r
252 static void prvMQTTDemoTask( void *pvParameters )\r
253 {\r
254 IotMqttError_t xResult;\r
255 uint32_t ulNotificationValue = 0;\r
256 const TickType_t xNoDelay = ( TickType_t ) 0;\r
257 \r
258         /* Remove compiler warnings about unused parameters. */\r
259         ( void ) pvParameters;\r
260 \r
261         /* The MQTT library needs a task pool, so create the system task pool. */\r
262         xResult = IotTaskPool_CreateSystemTaskPool( &( xTaskPoolParameters ) );\r
263         configASSERT( xResult == IOT_TASKPOOL_SUCCESS );\r
264 \r
265         /* MQTT library must be initialized before it can be used. This is just one\r
266          * time initialization. */\r
267         xResult = IotMqtt_Init();\r
268         configASSERT( xResult == IOT_MQTT_SUCCESS );\r
269 \r
270         for( ; ; )\r
271         {\r
272                 /* Don't expect any notifications to be pending yet. */\r
273                 configASSERT( ulTaskNotifyTake( pdTRUE, xNoDelay ) == 0 );\r
274 \r
275                 /* Establish a connection to the MQTT broker. This example connects to\r
276                  * the MQTT broker as specified in mqttexampleMQTT_BROKER_ENDPOINT and\r
277                  * mqttexampleMQTT_BROKER_PORT at the top of this file. Please change\r
278                  * it to the MQTT broker you want to connect to. Note that this example\r
279                  * does not use TLS and therefore will not work with AWS IoT. */\r
280                 prvMQTTConnect();\r
281 \r
282                 /* Subscribe to the topic as specified in mqttexampleTOPIC at the top\r
283                  * of this file. */\r
284                 prvMQTTSubscribe();\r
285 \r
286                 /* Publish a message on the mqttexampleTOPIC topic as specified at the\r
287                  * top of this file. */\r
288                 prvMQTTPublish();\r
289 \r
290                 /* Since we are subscribed on the same topic, we will get the same\r
291                  * message back from the MQTT broker. Wait for the message to be\r
292                  * received which is informed to us by the publish callback\r
293                  * (prvExample_PublishCallback) by setting the mqttexampleMESSAGE_RECEIVED_BIT\r
294                  * in this task's notification value. */\r
295                 xTaskNotifyWait( 0UL, /* Don't clear any bits on entry. */\r
296                                                  0UL, /* Don't clear any bits on exit. */\r
297                                                  &( ulNotificationValue ), /* Obtain the notification value. */\r
298                                                  pdMS_TO_TICKS( mqttexampleMQTT_TIMEOUT_MS ) );\r
299                 configASSERT( ( ulNotificationValue & mqttexampleMESSAGE_RECEIVED_BIT ) == mqttexampleMESSAGE_RECEIVED_BIT );\r
300 \r
301                 /* Unsubscribe from the topic mqttexampleTOPIC. */\r
302                 prvMQTTUnsubscribe();\r
303 \r
304                 /* Gracefully disconnect from the MQTT broker by sending an MQTT\r
305                  * DISCONNECT message. */\r
306                 prvMQTTDisconnect();\r
307 \r
308                 /* Wait for the disconnect operation to complete which is informed to us\r
309                  * by the disconnect callback (prvExample_DisconnectCallback)by setting\r
310                  * the mqttexampleDISCONNECTED_BIT in this task's notification value.\r
311                  * Note that all bits are cleared in the task's notification value to\r
312                  * ensure that it is ready for the next run. */\r
313                 xTaskNotifyWait( 0UL, /* Don't clear any bits on entry. */\r
314                                                  portMAX_DELAY, /* Clear all bits on exit - portMAX_DELAY is used as it is a portable way of having all bits set. */\r
315                                                  &( ulNotificationValue ), /* Obtain the notification value. */\r
316                                                  pdMS_TO_TICKS( mqttexampleMQTT_TIMEOUT_MS ) );\r
317                 configASSERT( ( ulNotificationValue & mqttexampleDISCONNECTED_BIT ) == mqttexampleDISCONNECTED_BIT );\r
318 \r
319                 printf( "prvMQTTDemoTask() completed an iteration without hitting an assert.\r\n" );\r
320                 fflush( stdout );\r
321 \r
322                 /* Wait for some time between two iterations to ensure that we do not\r
323                  * bombard the public test mosquitto broker. */\r
324                 vTaskDelay( pdMS_TO_TICKS( 5000 ) );\r
325         }\r
326 }\r
327 /*-----------------------------------------------------------*/\r
328 \r
329 static void prvMQTTConnect( void )\r
330 {\r
331 IotMqttError_t xResult;\r
332 IotNetworkServerInfo_t xMQTTBrokerInfo;\r
333 IotMqttNetworkInfo_t xNetworkInfo = IOT_MQTT_NETWORK_INFO_INITIALIZER;\r
334 IotMqttConnectInfo_t xConnectInfo = IOT_MQTT_CONNECT_INFO_INITIALIZER;\r
335 \r
336         /******************* Broker information setup. **********************/\r
337         xMQTTBrokerInfo.pHostName = mqttexampleMQTT_BROKER_ENDPOINT;\r
338         xMQTTBrokerInfo.port = mqttexampleMQTT_BROKER_PORT;\r
339 \r
340         /******************* Network information setup. **********************/\r
341         /* No connection to the MQTT broker has been established yet and we want to\r
342          * establish a new connection. */\r
343         xNetworkInfo.createNetworkConnection = true;\r
344         xNetworkInfo.u.setup.pNetworkServerInfo = &( xMQTTBrokerInfo );\r
345 \r
346         /* This example does not use TLS and therefore pNetworkCredentialInfo must\r
347          * be set to NULL. */\r
348         xNetworkInfo.u.setup.pNetworkCredentialInfo = NULL;\r
349 \r
350         /* Use FreeRTOS+TCP network. */\r
351         xNetworkInfo.pNetworkInterface = IOT_NETWORK_INTERFACE_FREERTOS;\r
352 \r
353         /* Setup the callback which is called when the MQTT connection is disconnected. */\r
354         xNetworkInfo.disconnectCallback.pCallbackContext = ( void * ) xTaskGetCurrentTaskHandle();\r
355         xNetworkInfo.disconnectCallback.function = prvExample_DisconnectCallback;\r
356 \r
357         /****************** MQTT Connection information setup. ********************/\r
358         /* This example does not use TLS and therefore won't work with AWS IoT. */\r
359         xConnectInfo.awsIotMqttMode = false;\r
360 \r
361         /* Start with a clean session i.e. direct the MQTT broker to discard any\r
362          * previous session data. Also, establishing a connection with clean session\r
363          * will ensure that the broker does not store any data when this client\r
364          * gets disconnected. */\r
365         xConnectInfo.cleanSession = true;\r
366 \r
367         /* Since we are starting with a clean session, there are no previous\r
368          * subscriptions to be restored. */\r
369         xConnectInfo.pPreviousSubscriptions = NULL;\r
370         xConnectInfo.previousSubscriptionCount = 0;\r
371 \r
372         /* We do not want to publish Last Will and Testament (LWT) message if the\r
373          * client gets disconnected. */\r
374         xConnectInfo.pWillInfo = NULL;\r
375 \r
376         /* Send an MQTT PING request every minute. */\r
377         xConnectInfo.keepAliveSeconds = mqttexampleKEEP_ALIVE_SECONDS;\r
378 \r
379         /* The client identifier is used to uniquely identify this MQTT client to\r
380          * the MQTT broker. */\r
381         xConnectInfo.pClientIdentifier = mqttexampleCLIENT_IDENTIFIER;\r
382         xConnectInfo.clientIdentifierLength = ( uint16_t ) strlen( mqttexampleCLIENT_IDENTIFIER );\r
383 \r
384         /* This example does not use any authentication and therefore username and\r
385          * password fields are not used. */\r
386         xConnectInfo.pUserName = NULL;\r
387         xConnectInfo.userNameLength = 0;\r
388         xConnectInfo.pPassword = NULL;\r
389         xConnectInfo.passwordLength = 0;\r
390 \r
391         /* Establish the connection to the MQTT broker - It is a blocking call and\r
392         will return only when connection is complete. */\r
393         xResult = IotMqtt_Connect( &( xNetworkInfo ),\r
394                                                            &( xConnectInfo ),\r
395                                                            mqttexampleMQTT_TIMEOUT_MS,\r
396                                                            &( xMQTTConnection ) );\r
397         configASSERT( xResult == IOT_MQTT_SUCCESS );\r
398 }\r
399 /*-----------------------------------------------------------*/\r
400 \r
401 static void prvMQTTSubscribe( void )\r
402 {\r
403 IotMqttError_t xResult;\r
404 IotMqttSubscription_t xMQTTSubscription;\r
405 \r
406         /* Subscribe to the mqttexampleTOPIC topic filter. */\r
407         xMQTTSubscription.qos = IOT_MQTT_QOS_1;\r
408         xMQTTSubscription.pTopicFilter = mqttexampleTOPIC;\r
409         xMQTTSubscription.topicFilterLength = ( uint16_t ) strlen( mqttexampleTOPIC );\r
410         xMQTTSubscription.callback.pCallbackContext = ( void * ) xTaskGetCurrentTaskHandle();\r
411         xMQTTSubscription.callback.function = prvExample_PublishCallback;\r
412 \r
413         /* Use the synchronous API to subscribe - It is a blocking call and only\r
414          * returns when the subscribe operation is complete. */\r
415         xResult = IotMqtt_TimedSubscribe( xMQTTConnection,\r
416                                                                           &( xMQTTSubscription ),\r
417                                                                           1, /* We are subscribing to one topic filter. */\r
418                                                                           0, /* flags - currently ignored. */\r
419                                                                           mqttexampleMQTT_TIMEOUT_MS );\r
420         configASSERT( xResult == IOT_MQTT_SUCCESS );\r
421 }\r
422 /*-----------------------------------------------------------*/\r
423 \r
424 static void prvMQTTPublish( void )\r
425 {\r
426 IotMqttError_t xResult;\r
427 IotMqttPublishInfo_t xMQTTPublishInfo;\r
428 \r
429         /* Publish a message with QoS1 on the mqttexampleTOPIC topic. Since we are\r
430          * subscribed to the same topic, the MQTT broker will send the same message\r
431          * back to us. It is verified in the publish callback. */\r
432         xMQTTPublishInfo.qos = IOT_MQTT_QOS_1;\r
433         xMQTTPublishInfo.retain = false;\r
434         xMQTTPublishInfo.pTopicName = mqttexampleTOPIC;\r
435         xMQTTPublishInfo.topicNameLength = ( uint16_t ) strlen( mqttexampleTOPIC );\r
436         xMQTTPublishInfo.pPayload = mqttexampleMESSAGE;\r
437         xMQTTPublishInfo.payloadLength = strlen( mqttexampleMESSAGE );\r
438         xMQTTPublishInfo.retryMs = mqttexamplePUBLISH_RETRY_MS;\r
439         xMQTTPublishInfo.retryLimit = mqttexamplePUBLISH_RETRY_LIMIT;\r
440 \r
441         /* Use the synchronous API to publish - It is a blocking call and only\r
442          * returns when the publish operation is complete. */\r
443         xResult = IotMqtt_TimedPublish( xMQTTConnection,\r
444                                                                         &( xMQTTPublishInfo ),\r
445                                                                         0, /* flags - currently ignored. */\r
446                                                                         mqttexampleMQTT_TIMEOUT_MS );\r
447         configASSERT( xResult == IOT_MQTT_SUCCESS );\r
448 }\r
449 /*-----------------------------------------------------------*/\r
450 \r
451 static void prvMQTTUnsubscribe( void )\r
452 {\r
453 IotMqttError_t xResult;\r
454 IotMqttSubscription_t xMQTTSubscription;\r
455 \r
456         /* Unsubscribe from the mqttexampleTOPIC topic filter. */\r
457         xMQTTSubscription.pTopicFilter = mqttexampleTOPIC;\r
458         xMQTTSubscription.topicFilterLength = ( uint16_t ) strlen( mqttexampleTOPIC );\r
459         /* The following members of the IotMqttSubscription_t are ignored by the\r
460          * unsubscribe operation. Just initialize them to avoid "use of uninitialized\r
461          * variable" warnings. */\r
462         xMQTTSubscription.qos = IOT_MQTT_QOS_1;\r
463         xMQTTSubscription.callback.pCallbackContext = NULL;\r
464         xMQTTSubscription.callback.function = NULL;\r
465 \r
466         /* Use the synchronous API to unsubscribe - It is a blocking call and only\r
467          * returns when the unsubscribe operation is complete. */\r
468         xResult = IotMqtt_TimedUnsubscribe( xMQTTConnection,\r
469                                                                                 &( xMQTTSubscription ),\r
470                                                                                 1, /* We are unsubscribing from one topic filter. */\r
471                                                                                 0, /* flags - currently ignored. */\r
472                                                                                 mqttexampleMQTT_TIMEOUT_MS );\r
473         configASSERT( xResult == IOT_MQTT_SUCCESS );\r
474 }\r
475 /*-----------------------------------------------------------*/\r
476 \r
477 static void prvMQTTDisconnect( void )\r
478 {\r
479         /* Send a MQTT DISCONNECT packet to the MQTT broker to do a graceful\r
480          * disconnect. */\r
481         IotMqtt_Disconnect( xMQTTConnection,\r
482                                                 0 /* flags - 0 means a graceful disconnect by sending MQTT DISCONNECT. */\r
483                                                 );\r
484 }\r
485 /*-----------------------------------------------------------*/\r