2 * FreeRTOS Kernel V10.3.0
\r
3 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
\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
12 * The above copyright notice and this permission notice shall be included in all
\r
13 * copies or substantial portions of the Software.
\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
22 * http://www.FreeRTOS.org
\r
23 * http://aws.amazon.com/freertos
\r
25 * 1 tab == 4 spaces!
\r
29 * This file contains the common functions for plain text, basic TLS, and mutual
\r
30 * authentication MQTT demos. Aside from the difference in security level during
\r
31 * connect, the three demos perform the same interaction with a MQTT broker. The
\r
32 * demos create a single application task that connects to a MQTT broker,
\r
33 * subscribes to a topic, publishes a topic with a message, and disconnect from a
\r
34 * MQTT broker. The task subscribes to the same topic it publishes to, receiving
\r
35 * the message it sends to the broker. Note that this demo does not terminate, the
\r
36 * connect-subscribe-publish-disconnect cycle is repeated for unlimited number of
\r
39 * The plain text MQTT demo does not authenticate the server nor the client. The
\r
40 * basic TLS MQTT demo builds on top of the plain text demo, adding broker
\r
41 * authentication and encryption. The mutual authentication MQTT demo builds on top
\r
42 * of the basic TLS demo, enabling both server and client authentication.
\r
44 * For more information regarding the MQTT library and the demo, please refer to:
\r
45 * https://freertos.org/mqtt/index.html
\r
48 /* Standard includes. */
\r
52 /* Kernel includes. */
\r
53 #include "FreeRTOS.h"
\r
56 /* FreeRTOS+TCP includes. */
\r
57 #include "FreeRTOS_IP.h"
\r
59 /* IoT SDK includes. */
\r
60 #include "iot_mqtt.h"
\r
61 #include "iot_taskpool_freertos.h"
\r
62 #include "platform/iot_network_freertos.h"
\r
64 /* MQTT Demo Select */
\r
65 #include "demo_config.h"
\r
67 /* Select MQTT profile based on the setting in demo_config.h */
\r
68 #if ( democonfigPROFILE_USE_AWS_IOT == 1 )
\r
69 #include "aws_iot_demo_profile.h"
\r
71 #include "mqtt_demo_profile.h"
\r
74 /* Preprocessor check for configuration */
\r
75 #include "aws_iot_setup_check.h"
\r
78 * Set connection profile based on the setting in demo_config.h. For more
\r
79 * information on each variable, please refer to the respective *_profile.h
\r
80 * file in FreeRTOS-Labs\Demo\FreeRTOS_IoT_Libraries\include.
\r
82 * Note that if you are running mqtt_tls_mutual_auth demo please make sure to
\r
83 * visit the following link for setup:
\r
84 * https://www.freertos.org/mqtt/preconfiguredexamplesMA.html
\r
86 #if ( democonfigPROFILE_USE_AWS_IOT == 1 )
\r
87 #define mqttexampleBROKER_ENDPOINT awsiotdemoprofileAWS_ENDPOINT
\r
88 #define mqttexampleBROKER_PORT awsiotdemoprofileAWS_MQTT_PORT
\r
89 #define mqttexampleBROKER_CERTIFICATE_PEM awsiotdemoprofileAWS_CERTIFICATE_PEM
\r
90 #define mqttexampleCLIENT_IDENTIFIER awsiotdemoprofileCLIENT_IDENTIFIER
\r
91 #define mqttexampleCLIENT_CERTIFICATE_PEM awsiotdemoprofileCLIENT_CERTIFICATE_PEM
\r
92 #define mqttexampleCLIENT_PRIVATE_KEY_PEM awsiotdemoprofileCLIENT_PRIVATE_KEY_PEM
\r
94 #define mqttexampleBROKER_ENDPOINT mqttdemoprofileBROKER_ENDPOINT
\r
95 #define mqttexampleBROKER_PORT mqttdemoprofileBROKER_PORT
\r
96 #define mqttexampleBROKER_CERTIFICATE_PEM mqttdemoprofileBROKER_CERTIFICATE_PEM
\r
97 #define mqttexampleCLIENT_IDENTIFIER mqttdemoprofileCLIENT_IDENTIFIER
\r
98 #endif /* if ( democonfigPROFILE_USE_AWS_IOT == pdTRUE ) */
\r
101 * @brief The keep-alive interval used for this example.
\r
103 * An MQTT ping request will be sent periodically at this interval.
\r
105 * @note: This value is set to zero to disable MQTT
\r
106 * keep alive for the Windows simulator project.
\r
107 * The FreeRTOS kernel does not accurately calculate time for the Windows
\r
108 * Simulator. Therefore, MQTT PING Request messages may be sent
\r
109 * at an incorrect time interval to the broker. If the broker does
\r
110 * not receive a ping request within 1.5x the time sent in a
\r
111 * connection request, the broker may close the connection.
\r
112 * To enable the keep alive feature, set this value
\r
113 * to the desired interval in seconds.
\r
115 #define mqttexampleKEEP_ALIVE_SECONDS ( 0 )
\r
118 * @brief The timeout for MQTT operations in this example.
\r
120 #define mqttexampleMQTT_TIMEOUT_MS ( 5000 )
\r
123 * @brief The topic to subscribe and publish to in the example.
\r
125 * The topic starts with the client identifier to ensure that each demo interacts
\r
126 * with a unique topic.
\r
128 #define mqttexampleTOPIC mqttexampleCLIENT_IDENTIFIER "/example/topic"
\r
131 * @brief The MQTT message published in this example.
\r
133 #define mqttexampleMESSAGE "Hello World!"
\r
136 * @brief Parameters to control the retry behavior in case a QoS1 publish
\r
137 * message gets lost.
\r
139 * Retry every minutes up to a maximum of 5 retries.
\r
141 #define mqttexamplePUBLISH_RETRY_MS ( 1000 )
\r
142 #define mqttexamplePUBLISH_RETRY_LIMIT ( 5 )
\r
145 * @brief The bit which is set in the demo task's notification value from the
\r
146 * disconnect callback to inform the demo task about the MQTT disconnect.
\r
148 #define mqttexampleDISCONNECTED_BIT ( 1UL << 0UL )
\r
151 * @brief The bit which is set in the demo task's notification value from the
\r
152 * publish callback to inform the demo task about the message received from the
\r
155 #define mqttexampleMESSAGE_RECEIVED_BIT ( 1UL << 1UL )
\r
157 /*-----------------------------------------------------------*/
\r
160 * @brief The task used to demonstrate the MQTT API.
\r
162 * @param[in] pvParameters Parameters as passed at the time of task creation. Not
\r
163 * used in this example.
\r
165 static void prvMQTTDemoTask( void * pvParameters );
\r
168 * @brief The callback invoked by the MQTT library when the MQTT connection gets
\r
171 * @param[in] pvCallbackContext Callback context as provided at the time of
\r
173 * @param[in] pxCallbackParams Contains the reason why the MQTT connection was
\r
176 static void prvExample_OnDisconnect( void * pvCallbackContext,
\r
177 IotMqttCallbackParam_t * pxCallbackParams );
\r
180 * @brief The callback invoked by the MQTT library when a message is received on
\r
181 * a subscribed topic from the MQTT broker.
\r
183 * @param[in] pvCallbackContext Callback context as provided at the time of
\r
185 * @param[in] pxCallbackParams Contain the details about the received message -
\r
186 * topic on which the message was received, the received message.
\r
188 static void prvExample_OnMessageReceived( void * pvCallbackContext,
\r
189 IotMqttCallbackParam_t * pxCallbackParams );
\r
192 * @brief Connects to the MQTT broker as specified in mqttexampleBROKER_ENDPOINT
\r
193 * and mqttexampleBROKER_PORT.
\r
195 static void prvMQTTConnect( void );
\r
198 * @brief Subscribes to the topic as specified in mqttexampleTOPIC.
\r
200 static void prvMQTTSubscribe( void );
\r
203 * @brief Publishes a messages mqttexampleMESSAGE on mqttexampleTOPIC topic.
\r
205 static void prvMQTTPublish( void );
\r
208 * @brief Unsubscribes from the mqttexampleTOPIC topic.
\r
210 static void prvMQTTUnsubscribe( void );
\r
213 * @brief Disconnects from the MQTT broker gracefully by sending an MQTT
\r
214 * DISCONNECT message.
\r
216 static void prvMQTTDisconnect( void );
\r
219 * @brief Initializes the IoT libraries used by this demo.
\r
221 static void prvInitialiseLibraries( void );
\r
224 * @brief The MQTT connection handle used in this example.
\r
226 static IotMqttConnection_t xMQTTConnection = IOT_MQTT_CONNECTION_INITIALIZER;
\r
228 /*-----------------------------------------------------------*/
\r
231 * @brief Parameters used to create the system task pool.
\r
233 static const IotTaskPoolInfo_t xTaskPoolParameters =
\r
235 /* Minimum number of threads in a task pool.
\r
236 * Note the slimmed down version of the task
\r
237 * pool used by this library does not auto-scale
\r
238 * the number of tasks in the pool so in this
\r
239 * case this sets the number of tasks in the
\r
243 /* Maximum number of threads in a task pool.
\r
244 * Note the slimmed down version of the task
\r
245 * pool used by this library does not auto-scale
\r
246 * the number of tasks in the pool so in this
\r
247 * case this parameter is just ignored. */
\r
250 /* Stack size for every task pool thread - in
\r
251 * bytes, hence multiplying by the number of bytes
\r
252 * in a word as configMINIMAL_STACK_SIZE is
\r
253 * specified in words. */
\r
254 configMINIMAL_STACK_SIZE * sizeof( portSTACK_TYPE ),
\r
255 /* Priority for every task pool thread. */
\r
259 /*-----------------------------------------------------------*/
\r
261 static const struct IotNetworkServerInfo xMQTTBrokerInfo =
\r
263 .pHostName = mqttexampleBROKER_ENDPOINT,
\r
264 .port = mqttexampleBROKER_PORT
\r
267 #if ( democonfigENABLE_TLS )
\r
268 static struct IotNetworkCredentials xNetworkSecurityCredentials =
\r
270 /* Optional TLS extensions. For this demo, they are disabled. */
\r
271 .pAlpnProtos = NULL,
\r
272 .maxFragmentLength = 0,
\r
274 /* SNI is enabled by default. */
\r
275 .disableSni = false,
\r
277 /* Provide the certificate for validating the server. Only required for
\r
278 * demos using TLS. */
\r
279 .pRootCa = mqttexampleBROKER_CERTIFICATE_PEM,
\r
280 .rootCaSize = sizeof( mqttexampleBROKER_CERTIFICATE_PEM ),
\r
282 /* Strong mutual authentication to authenticate both the broker and
\r
284 #if ( democonfigENABLE_MUTUAL_AUTH )
\r
285 .pClientCert = mqttexampleCLIENT_CERTIFICATE_PEM,
\r
286 .clientCertSize = sizeof( mqttexampleCLIENT_CERTIFICATE_PEM ),
\r
287 .pPrivateKey = mqttexampleCLIENT_PRIVATE_KEY_PEM,
\r
288 .privateKeySize = sizeof( mqttexampleCLIENT_PRIVATE_KEY_PEM )
\r
290 .pClientCert = NULL,
\r
291 .clientCertSize = 0,
\r
292 .pPrivateKey = NULL,
\r
293 .privateKeySize = 0
\r
294 #endif /* if ( democonfigENABLE_MUTUAL_AUTH ) */
\r
296 #endif /* if ( democonfigENABLE_TLS ) */
\r
298 static IotMqttNetworkInfo_t xNetworkInfo =
\r
300 /* No connection to the MQTT broker has been established yet and we want to
\r
301 * establish a new connection. */
\r
302 .createNetworkConnection = true,
\r
303 .u.setup.pNetworkServerInfo = &( xMQTTBrokerInfo ),
\r
305 /* Set the TLS credentials for the new MQTT connection. This member is NULL
\r
306 * for the plain text MQTT demo. */
\r
307 #if ( democonfigENABLE_TLS )
\r
308 .u.setup.pNetworkCredentialInfo = &xNetworkSecurityCredentials,
\r
310 .u.setup.pNetworkCredentialInfo = NULL, /* Not using TLS so no credentials. */
\r
313 /* Use FreeRTOS+TCP network interface. */
\r
314 .pNetworkInterface = IOT_NETWORK_INTERFACE_FREERTOS,
\r
316 /* Setup the callback which is called when the MQTT connection is
\r
317 * disconnected. The task handle is passed as the callback context which
\r
318 * is used by the callback to send a task notification to this task.*/
\r
319 .disconnectCallback.function = prvExample_OnDisconnect
\r
322 static const IotMqttConnectInfo_t xConnectInfo =
\r
324 /* Set this flag to true if connecting to the AWS IoT MQTT broker. */
\r
325 #if ( democonfigPROFILE_USE_AWS_IOT == 1 )
\r
326 .awsIotMqttMode = true,
\r
328 .awsIotMqttMode = false,
\r
331 /* Start with a clean session i.e. direct the MQTT broker to discard any
\r
332 * previous session data. Also, establishing a connection with clean session
\r
333 * will ensure that the broker does not store any data when this client
\r
334 * gets disconnected. */
\r
335 .cleanSession = true,
\r
337 /* Since we are starting with a clean session, there are no previous
\r
338 * subscriptions to be restored. */
\r
339 .pPreviousSubscriptions = NULL,
\r
340 .previousSubscriptionCount = 0,
\r
342 /* We do not want to publish Last Will and Testament (LWT) message if the
\r
343 * client gets disconnected. */
\r
346 /* Send an MQTT PING request every minute to keep the connection open if
\r
347 there is no other MQTT traffic. */
\r
348 .keepAliveSeconds = mqttexampleKEEP_ALIVE_SECONDS,
\r
350 /* The client identifier is used to uniquely identify this MQTT client to
\r
351 * the MQTT broker. In a production device the identifier can be something
\r
352 * unique, such as a device serial number. */
\r
353 .pClientIdentifier = mqttexampleCLIENT_IDENTIFIER,
\r
354 .clientIdentifierLength = ( uint16_t ) sizeof( mqttexampleCLIENT_IDENTIFIER ) - 1,
\r
356 /* This example does not authenticate the client and therefore username and
\r
357 * password fields are not used. */
\r
359 .userNameLength = 0,
\r
361 .passwordLength = 0
\r
363 /*-----------------------------------------------------------*/
\r
366 void vStartSimpleMQTTDemo( void )
\r
368 TickType_t xShortDelay = ( TickType_t ) pdMS_TO_TICKS( ( TickType_t ) 500 );
\r
370 /* Wait a short time to allow receipt of the ARP replies. */
\r
371 vTaskDelay( xShortDelay );
\r
373 /* This example uses a single application task, which in turn is used to
\r
374 * connect, subscribe, publish, unsubscribe and disconnect from the MQTT
\r
376 xTaskCreate( prvMQTTDemoTask, /* Function that implements the task. */
\r
377 "MQTTDemo", /* Text name for the task - only used for debugging. */
\r
378 democonfigDEMO_STACKSIZE, /* Size of stack (in words, not bytes) to allocate for the task. */
\r
379 NULL, /* Task parameter - not used in this case. */
\r
380 tskIDLE_PRIORITY, /* Task priority, must be between 0 and configMAX_PRIORITIES - 1. */
\r
381 NULL ); /* Used to pass out a handle to the created task - not used in this case. */
\r
383 /*-----------------------------------------------------------*/
\r
385 static void prvMQTTDemoTask( void * pvParameters )
\r
387 uint32_t ulNotificationValue = 0, ulPublishCount;
\r
388 const uint32_t ulMaxPublishCount = 5UL;
\r
389 const TickType_t xNoDelay = ( TickType_t ) 0;
\r
391 /* Remove compiler warnings about unused parameters. */
\r
392 ( void ) pvParameters;
\r
394 /* One time initialization of the libraries used by this demo. */
\r
395 prvInitialiseLibraries();
\r
399 /* Notifications are used to send events from the callback functions to this
\r
400 * task. Don't expect any notifications to be pending at the beginning of the
\r
402 configASSERT( ulTaskNotifyTake( pdTRUE, xNoDelay ) == 0 );
\r
405 /****************************** Connect. ******************************/
\r
407 /* Establish a connection to the MQTT broker. This example connects to
\r
408 * the MQTT broker as specified by the compile time constants
\r
409 * mqttexampleBROKER_ENDPOINT and mqttexampleBROKER_PORT.
\r
410 * Please change it to the MQTT broker you want to connect to. */
\r
411 configPRINTF( ( "Attempt to connect to %s:%d\r\n", mqttexampleBROKER_ENDPOINT, mqttexampleBROKER_PORT ) );
\r
413 configPRINTF( ( "Connected to %s:%d\r\n", mqttexampleBROKER_ENDPOINT, mqttexampleBROKER_PORT ) );
\r
416 /**************************** Subscribe. ******************************/
\r
418 /* The client is now connected to the broker. Subscribe to the topic
\r
419 * as specified by the mqttexampleTOPIC compile time constant. This
\r
420 * client will then publish to the same topic it subscribed to, so will
\r
421 * expect all the messages it sends to the broker to be sent back to it
\r
422 * from the broker. */
\r
423 configPRINTF( ( "Attempt to subscribed to the topic %s\r\n", mqttexampleTOPIC ) );
\r
424 prvMQTTSubscribe();
\r
425 configPRINTF( ( "Subscribed to the topic %s\r\n", mqttexampleTOPIC ) );
\r
428 /*********************** Publish ulMaxPublishCount messages. **********/
\r
430 /* Publish a few messages while connected. */
\r
431 for( ulPublishCount = 0; ulPublishCount < ulMaxPublishCount; ulPublishCount++ )
\r
433 /* Publish a message on the topic specified by the mqttexampleTOPIC
\r
434 * compile time constant. */
\r
435 configPRINTF( ( "Publish %s on the topic %s\r\n", mqttexampleMESSAGE, mqttexampleTOPIC ) );
\r
437 configPRINTF( ( "Published %s on the topic %s\r\n", mqttexampleMESSAGE, mqttexampleTOPIC ) );
\r
439 /* Since we are subscribed to the same topic as we published on, we
\r
440 * will get the same message back from the MQTT broker. Wait for the
\r
441 * message to be received which is signaled to us by the publish
\r
442 * callback (prvExample_OnMessageReceived) setting the
\r
443 * mqttexampleMESSAGE_RECEIVED_BIT bit in this task's notification
\r
444 * value. Note the bit is then cleared in the task's notification value
\r
445 * to ensure the bit being set can be detected on the next iteration. */
\r
446 xTaskNotifyWait( 0UL, /* Don't clear any bits on entry. */
\r
447 mqttexampleMESSAGE_RECEIVED_BIT, /* Clear bit on exit. */
\r
448 &( ulNotificationValue ), /* Obtain the notification value. */
\r
449 pdMS_TO_TICKS( mqttexampleMQTT_TIMEOUT_MS ) );
\r
450 configASSERT( ( ulNotificationValue & mqttexampleMESSAGE_RECEIVED_BIT ) == mqttexampleMESSAGE_RECEIVED_BIT );
\r
453 /******************* Unsubscribe and Disconnect. **********************/
\r
455 /* Unsubscribe from the topic mqttexampleTOPIC and disconnect
\r
457 prvMQTTUnsubscribe();
\r
458 prvMQTTDisconnect();
\r
459 configPRINTF( ( "Disconnected from %s:%d\r\n\r\n", mqttexampleBROKER_ENDPOINT, mqttexampleBROKER_PORT ) );
\r
461 /* Wait for the disconnect operation to complete which is signaled to us
\r
462 * by the disconnect callback (prvExample_OnDisconnect)by setting
\r
463 * the mqttexampleDISCONNECTED_BIT bit in this task's notification value.
\r
464 * Note the bit is cleared in the task's notification value again to ensure
\r
465 * it being set can be detected again on the next iteration. */
\r
466 xTaskNotifyWait( 0UL, /* Don't clear any bits on entry. */
\r
467 mqttexampleDISCONNECTED_BIT, /* Clear bit on exit. */
\r
468 &( ulNotificationValue ), /* Obtain the notification value. */
\r
469 pdMS_TO_TICKS( mqttexampleMQTT_TIMEOUT_MS ) );
\r
470 configASSERT( ( ulNotificationValue & mqttexampleDISCONNECTED_BIT ) == mqttexampleDISCONNECTED_BIT );
\r
472 /* Delay between iterations to avoid broker throttling. */
\r
473 configPRINTF( ( "prvMQTTDemoTask() completed an iteration successfully. Total free heap is %u\r\n", xPortGetFreeHeapSize() ) );
\r
474 configPRINTF( ( "Demo completed successfully.\r\n" ) );
\r
475 configPRINTF( ( "Short delay before starting the next iteration.... \r\n\r\n" ) );
\r
476 vTaskDelay( pdMS_TO_TICKS( mqttexampleMQTT_TIMEOUT_MS ) );
\r
479 /*-----------------------------------------------------------*/
\r
481 static void prvExample_OnDisconnect( void * pvCallbackContext,
\r
482 IotMqttCallbackParam_t * pxCallbackParams )
\r
484 TaskHandle_t xDemoTaskHandle = ( TaskHandle_t ) pvCallbackContext;
\r
486 /* Ensure that we initiated the disconnect. */
\r
487 configASSERT( pxCallbackParams->u.disconnectReason == IOT_MQTT_DISCONNECT_CALLED );
\r
489 /* Inform the demo task about the disconnect. */
\r
490 xTaskNotify( xDemoTaskHandle,
\r
491 mqttexampleDISCONNECTED_BIT,
\r
492 eSetBits /* Set the mqttexampleDISCONNECTED_BIT in the demo task's notification value. */
\r
495 /*-----------------------------------------------------------*/
\r
497 static void prvExample_OnMessageReceived( void * pvCallbackContext,
\r
498 IotMqttCallbackParam_t * pxCallbackParams )
\r
500 TaskHandle_t xDemoTaskHandle = ( TaskHandle_t ) pvCallbackContext;
\r
502 /* Ensure the message is received on the expected topic. */
\r
503 configASSERT( pxCallbackParams->u.message.info.topicNameLength == strlen( mqttexampleTOPIC ) );
\r
504 configASSERT( strncmp( pxCallbackParams->u.message.info.pTopicName,
\r
506 strlen( mqttexampleTOPIC ) ) == 0 );
\r
508 /* Ensure the message itself is as expected. */
\r
509 configASSERT( pxCallbackParams->u.message.info.payloadLength == strlen( mqttexampleMESSAGE ) );
\r
510 configASSERT( strncmp( pxCallbackParams->u.message.info.pPayload,
\r
511 mqttexampleMESSAGE,
\r
512 strlen( mqttexampleMESSAGE ) ) == 0 );
\r
514 /* Ensure the message Quality of Service (QoS) is as expected. */
\r
515 configASSERT( pxCallbackParams->u.message.info.qos == IOT_MQTT_QOS_1 );
\r
517 /* So as not to worry about string lengths the print message uses the
\r
518 * consts rather than the data from the message, but the asserts above have
\r
519 * already checked the two are equal. */
\r
520 configPRINTF( ( "Received %s on the topic %s\r\n", mqttexampleMESSAGE, mqttexampleTOPIC ) );
\r
522 /* Inform the demo task about the message received from the MQTT broker by
\r
523 * setting the mqttexampleMESSAGE_RECEIVED_BIT bit in the task's notification
\r
525 xTaskNotify( xDemoTaskHandle,
\r
526 mqttexampleMESSAGE_RECEIVED_BIT,
\r
527 eSetBits /* Set the mqttexampleMESSAGE_RECEIVED_BIT in the demo task's notification value. */
\r
530 /*-----------------------------------------------------------*/
\r
532 static void prvMQTTConnect( void )
\r
534 IotMqttError_t xResult;
\r
536 /* Set the context to pass into the disconnect callback function. */
\r
537 xNetworkInfo.disconnectCallback.pCallbackContext = ( void * ) xTaskGetCurrentTaskHandle();
\r
539 /* Establish the connection to the MQTT broker - It is a blocking call and
\r
540 * will return only when connection is complete or a timeout occurs. The
\r
541 * network and connection structures are declared and initialized at the top
\r
543 xResult = IotMqtt_Connect( &( xNetworkInfo ),
\r
545 mqttexampleMQTT_TIMEOUT_MS,
\r
546 &( xMQTTConnection ) );
\r
547 configASSERT( xResult == IOT_MQTT_SUCCESS );
\r
549 /*-----------------------------------------------------------*/
\r
551 static void prvMQTTDisconnect( void )
\r
553 /* Send a MQTT DISCONNECT packet to the MQTT broker to do a graceful
\r
555 IotMqtt_Disconnect( xMQTTConnection,
\r
556 0 /* flags - 0 means a graceful disconnect by sending MQTT DISCONNECT. */
\r
559 /*-----------------------------------------------------------*/
\r
561 static void prvMQTTSubscribe( void )
\r
563 IotMqttError_t xResult;
\r
564 IotMqttSubscription_t xMQTTSubscription;
\r
566 /* Subscribe to the mqttexampleTOPIC topic filter. The task handle is passed
\r
567 * as the callback context, which is then used by the callback to send a task
\r
568 * notification to this task.*/
\r
569 xMQTTSubscription.qos = IOT_MQTT_QOS_1;
\r
570 xMQTTSubscription.pTopicFilter = mqttexampleTOPIC;
\r
571 xMQTTSubscription.topicFilterLength = ( uint16_t ) strlen( mqttexampleTOPIC );
\r
572 xMQTTSubscription.callback.pCallbackContext = ( void * ) xTaskGetCurrentTaskHandle();
\r
573 xMQTTSubscription.callback.function = prvExample_OnMessageReceived;
\r
575 /* Use the synchronous API to subscribe - It is a blocking call and only
\r
576 * returns when the subscribe operation is complete or a timeout occurs. */
\r
577 xResult = IotMqtt_SubscribeSync( xMQTTConnection,
\r
578 &( xMQTTSubscription ),
\r
579 1, /* We are subscribing to one topic filter. */
\r
580 0, /* flags - currently ignored. */
\r
581 mqttexampleMQTT_TIMEOUT_MS );
\r
582 configASSERT( xResult == IOT_MQTT_SUCCESS );
\r
584 /*-----------------------------------------------------------*/
\r
586 static void prvMQTTPublish( void )
\r
588 IotMqttError_t xResult;
\r
589 IotMqttPublishInfo_t xMQTTPublishInfo;
\r
591 /* Publish a message with QoS1 on the mqttexampleTOPIC topic. Since we are
\r
592 * subscribed to the same topic, the MQTT broker will send the same message
\r
593 * back to us. It is verified in the publish callback. */
\r
594 xMQTTPublishInfo.qos = IOT_MQTT_QOS_1;
\r
595 xMQTTPublishInfo.retain = false;
\r
596 xMQTTPublishInfo.pTopicName = mqttexampleTOPIC;
\r
597 xMQTTPublishInfo.topicNameLength = ( uint16_t ) strlen( mqttexampleTOPIC );
\r
598 xMQTTPublishInfo.pPayload = mqttexampleMESSAGE;
\r
599 xMQTTPublishInfo.payloadLength = strlen( mqttexampleMESSAGE );
\r
600 xMQTTPublishInfo.retryMs = mqttexamplePUBLISH_RETRY_MS;
\r
601 xMQTTPublishInfo.retryLimit = mqttexamplePUBLISH_RETRY_LIMIT;
\r
603 /* Use the synchronous API to publish - It is a blocking call and only
\r
604 * returns when the publish operation is complete or a timeout occurs. */
\r
605 xResult = IotMqtt_PublishSync( xMQTTConnection,
\r
606 &( xMQTTPublishInfo ),
\r
607 0, /* flags - currently ignored. */
\r
608 mqttexampleMQTT_TIMEOUT_MS );
\r
609 configASSERT( xResult == IOT_MQTT_SUCCESS );
\r
611 /*-----------------------------------------------------------*/
\r
613 static void prvMQTTUnsubscribe( void )
\r
615 IotMqttError_t xResult;
\r
616 IotMqttSubscription_t xMQTTSubscription;
\r
618 /* Unsubscribe from the mqttexampleTOPIC topic filter. */
\r
619 xMQTTSubscription.pTopicFilter = mqttexampleTOPIC;
\r
620 xMQTTSubscription.topicFilterLength = ( uint16_t ) strlen( mqttexampleTOPIC );
\r
622 /* The following members of the IotMqttSubscription_t are ignored by the
\r
623 * unsubscribe operation. Just initialize them to avoid "use of uninitialized
\r
624 * variable" warnings. */
\r
625 xMQTTSubscription.qos = IOT_MQTT_QOS_1;
\r
626 xMQTTSubscription.callback.pCallbackContext = NULL;
\r
627 xMQTTSubscription.callback.function = NULL;
\r
629 /* Use the synchronous API to unsubscribe - It is a blocking call and only
\r
630 * returns when the unsubscribe operation is complete or a timeout occurs. */
\r
631 xResult = IotMqtt_UnsubscribeSync( xMQTTConnection,
\r
632 &( xMQTTSubscription ),
\r
633 1, /* We are unsubscribing from one topic filter. */
\r
634 0, /* flags - currently ignored. */
\r
635 mqttexampleMQTT_TIMEOUT_MS );
\r
636 configASSERT( xResult == IOT_MQTT_SUCCESS );
\r
638 /*-----------------------------------------------------------*/
\r
640 static void prvInitialiseLibraries( void )
\r
642 IotTaskPoolError_t xTaskPoolResult;
\r
643 IotMqttError_t xResult;
\r
644 IotNetworkError_t xNetworkResult;
\r
646 /* The MQTT library needs a task pool, so create the system task pool. */
\r
647 xTaskPoolResult = IotTaskPool_CreateSystemTaskPool( &( xTaskPoolParameters ) );
\r
648 configASSERT( xTaskPoolResult == IOT_TASKPOOL_SUCCESS );
\r
650 /* Initialize the network stack abstraction for FreeRTOS. */
\r
651 xNetworkResult = IotNetworkFreeRTOS_Init();
\r
652 configASSERT( xNetworkResult == IOT_NETWORK_SUCCESS );
\r
654 /* MQTT library must be initialized before it can be used. This is just one
\r
655 * time initialization. */
\r
656 xResult = IotMqtt_Init();
\r
657 configASSERT( xResult == IOT_MQTT_SUCCESS );
\r
659 /*-----------------------------------------------------------*/
\r