--- /dev/null
+/*\r
+ * FreeRTOS Kernel V10.2.1\r
+ * Copyright (C) 2017 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://www.FreeRTOS.org\r
+ * http://aws.amazon.com/freertos\r
+ *\r
+ * 1 tab == 4 spaces!\r
+ */\r
+\r
+/* Standard inclues. */\r
+#include <string.h>\r
+\r
+/* Kernel includes. */\r
+#include "FreeRTOS.h"\r
+#include "task.h"\r
+\r
+/* MQTT include. */\r
+#include "iot_mqtt.h"\r
+\r
+/* Platform FreeRTOS network include. */\r
+#include "platform/iot_network_freertos.h"\r
+\r
+/**\r
+ * @brief The keep-alive interval used for this example.\r
+ *\r
+ * An MQTT ping request will be sent periodically at this interval.\r
+ */\r
+#define mqttexampleKEEP_ALIVE_SECONDS ( 60 )\r
+\r
+/**\r
+ * @brief The timeout for MQTT operations in this example.\r
+ */\r
+#define mqttexampleMQTT_TIMEOUT_MS ( 5000 )\r
+\r
+/**\r
+ * @brief The MQTT client identifier used in this example.\r
+ */\r
+#define mqttexampleCLIENT_IDENTIFIER "mqttexampleclient"\r
+\r
+/**\r
+ * @brief Details of the MQTT broker to connect to.\r
+ *\r
+ * @note This example does not use TLS and therefore won't work with AWS IoT.\r
+ */\r
+#define mqttexampleMQTT_BROKER_ENDPOINT "10.60.214.105"\r
+#define mqttexampleMQTT_BROKER_PORT 1883\r
+\r
+/**\r
+ * @brief The topic to subscribe and publish to in the example.\r
+ */\r
+#define mqttexampleTOPIC "example/topic"\r
+\r
+/**\r
+ * @brief The MQTT message published in this example.\r
+ */\r
+#define mqttexampleMESSAGE "Hello World!"\r
+\r
+/**\r
+ * @brief Paramters to control the retry behaviour in case a QoS1 publish\r
+ * message gets lost.\r
+ *\r
+ * Retry every minutes up to a maximum of 5 retries.\r
+ */\r
+#define mqttexamplePUBLISH_RETRY_MS ( 1000 )\r
+#define mqttexamplePUBLISH_RETRY_LIMIT ( 5 )\r
+\r
+/**\r
+ * @brief The bit which is set in the demo task's notification value from the\r
+ * disconnect callback to inform the demo task about the MQTT disconnect.\r
+ */\r
+#define mqttexampleDISCONNECTED_BIT ( 1UL << 0UL )\r
+\r
+/**\r
+ * @brief The bit which is set in the demo task's notification value from the\r
+ * publish callback to inform the demo task about the message received from the\r
+ * MQTT broker.\r
+ */\r
+#define mqttexampleMESSAGE_RECEIVED_BIT ( 1UL << 1UL )\r
+/*-----------------------------------------------------------*/\r
+\r
+/**\r
+ * @brief The MQTT connection handle used in this example.\r
+ */\r
+static IotMqttConnection_t xMQTTConnection = IOT_MQTT_CONNECTION_INITIALIZER;\r
+/*-----------------------------------------------------------*/\r
+\r
+/**\r
+ * @brief The task used to demonstrate the MQTT API.\r
+ *\r
+ * @param[in] pvParameters Parmaters as passed at the time of task creation. Not\r
+ * used in this example.\r
+ */\r
+static void prvMQTTDemoTask( void *pvParameters );\r
+\r
+/**\r
+ * @brief The callback invoked by the MQTT library when the MQTT connection gets\r
+ * disconnected.\r
+ * \r
+ * @param[in] pvCallbackContext Callback context as provided at the time of\r
+ * connect.\r
+ * @param[in] pxCallbackParams Contains the reason why the MQTT connection was\r
+ * disconnected.\r
+ */\r
+static void prvExample_DisconnectCallback( void * pvCallbackContext,\r
+ IotMqttCallbackParam_t * pxCallbackParams );\r
+\r
+/**\r
+ * @brief The callback invoked by the MQTT library when a message is received on\r
+ * a subscribed topic from the MQTT broker.\r
+ * \r
+ * @param[in] pvCallbackContext Callback context as provided at the time of\r
+ * subscribe.\r
+ * @param[in] pxCallbackParams Contain the details about the received message - \r
+ * topic on which the message was received, the received message.\r
+ */\r
+static void prvExample_PublishCallback( void * pvCallbackContext,\r
+ IotMqttCallbackParam_t * pxCallbackParams );\r
+\r
+/**\r
+ * @brief Connects to the MQTT broker as specified in mqttexampleMQTT_BROKER_ENDPOINT\r
+ * and mqttexampleMQTT_BROKER_PORT.\r
+ * \r
+ * @note This example does not use TLS and therefore will not work with MQTT.\r
+ */\r
+static void prvMQTTConnect( void );\r
+\r
+/**\r
+ * @brief Subscribes to the topic as specified in mqttexampleTOPIC.\r
+ */\r
+static void prvMQTTSubscribe( void );\r
+\r
+/**\r
+ * @brief Publishes a messages mqttexampleMESSAGE on mqttexampleTOPIC topic.\r
+ */\r
+static void prvMQTTPublish( void );\r
+\r
+/**\r
+ * @brief Unsubscribes from the mqttexampleTOPIC topic.\r
+ */\r
+static void prvMQTTUnsubscribe( void );\r
+\r
+/**\r
+ * @brief Disconnects from the MQTT broker gracefully by sending an MQTT\r
+ * DISCONNECT message.\r
+ */\r
+static void prvMQTTDisconnect( void );\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvExample_DisconnectCallback( void * pvCallbackContext,\r
+ IotMqttCallbackParam_t * pxCallbackParams )\r
+{\r
+TaskHandle_t xDemoTaskHandle = ( TaskHandle_t ) pvCallbackContext;\r
+\r
+ /* Ensure that we initiated the disconnect. */\r
+ configASSERT( pxCallbackParams->u.disconnectReason == IOT_MQTT_DISCONNECT_CALLED );\r
+\r
+ /* Inform the demo task about the disconnect. */\r
+ xTaskNotify( xDemoTaskHandle,\r
+ mqttexampleDISCONNECTED_BIT,\r
+ eSetBits /* Set the mqttexampleDISCONNECTED_BIT in the demo task's notification value. */\r
+ );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvExample_PublishCallback( void * pvCallbackContext,\r
+ IotMqttCallbackParam_t * pxCallbackParams )\r
+{\r
+TaskHandle_t xDemoTaskHandle = ( TaskHandle_t ) pvCallbackContext;\r
+\r
+ /* Ensure that the message is received on the expected topic. */\r
+ configASSERT( pxCallbackParams->u.message.info.topicNameLength == strlen( mqttexampleTOPIC ) );\r
+ configASSERT( strncmp( pxCallbackParams->u.message.info.pTopicName,\r
+ mqttexampleTOPIC,\r
+ strlen( mqttexampleTOPIC ) ) == 0 );\r
+\r
+ /* Ensure that the expected message is received. */\r
+ configASSERT( pxCallbackParams->u.message.info.payloadLength == strlen( mqttexampleMESSAGE ) );\r
+ configASSERT( strncmp( pxCallbackParams->u.message.info.pPayload,\r
+ mqttexampleMESSAGE,\r
+ strlen( mqttexampleMESSAGE ) ) == 0 );\r
+\r
+ /* Ensure that the message QoS is as expected. */\r
+ configASSERT( pxCallbackParams->u.message.info.qos == IOT_MQTT_QOS_1 );\r
+\r
+ /* Inform the demo task about the message received from the MQTT broker. */\r
+ xTaskNotify( xDemoTaskHandle,\r
+ mqttexampleMESSAGE_RECEIVED_BIT,\r
+ eSetBits /* Set the mqttexampleMESSAGE_RECEIVED_BIT in the demo task's notification value. */\r
+ );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+void vStartSimpleMQTTDemo( void )\r
+{\r
+ /* This example uses a single application task, which in turn is used to\r
+ * connect, subscribe, publish, unsubscribe and disconnect from the MQTT\r
+ * broker. */\r
+ xTaskCreate( prvMQTTDemoTask, /* Function that implements the task. */\r
+ "MQTTDemo", /* Text name for the task - only used for debugging. */\r
+ configMINIMAL_STACK_SIZE, /* Size of stack (in words, not bytes) to allocate for the task. */\r
+ NULL, /* Task parameter - not used in this case. */\r
+ tskIDLE_PRIORITY, /* Task priority, must be between 0 and configMAX_PRIORITIES - 1. */\r
+ NULL ); /* Used to pass out a handle to the created task - not used in this case. */\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvMQTTDemoTask( void *pvParameters )\r
+{\r
+IotMqttError_t xResult;\r
+uint32_t ulNotificationValue = 0;\r
+const TickType_t xNoDelay = ( TickType_t ) 0;\r
+\r
+ /* Remove compiler warnings about unused parameters. */\r
+ ( void ) pvParameters;\r
+\r
+ /* MQTT library must be initialized before it can be used. This is just one\r
+ * time initialization. */\r
+ xResult = IotMqtt_Init();\r
+ configASSERT( xResult == IOT_MQTT_SUCCESS );\r
+\r
+ for( ; ; )\r
+ {\r
+ /* Don't expect any notifications to be pending yet. */\r
+ configASSERT( ulTaskNotifyTake( pdTRUE, xNoDelay ) == 0 );\r
+\r
+ /* Establish a connection to the MQTT broker. This example connects to\r
+ * the MQTT broker as specified in mqttexampleMQTT_BROKER_ENDPOINT and\r
+ * mqttexampleMQTT_BROKER_PORT at the top of this file. Please change\r
+ * it to the MQTT broker you want to connect to. Note that this example\r
+ * does not use TLS and therefore will not work with AWS IoT. */\r
+ prvMQTTConnect();\r
+\r
+ /* Subscribe to the topic as specified in mqttexampleTOPIC at the top\r
+ * of this file. */\r
+ prvMQTTSubscribe();\r
+\r
+ /* Publish a message on the mqttexampleTOPIC topic as specified at the\r
+ * top of this file. */\r
+ prvMQTTPublish();\r
+\r
+ /* Since we are subscribed on the same topic, we will get the same\r
+ * message back from the MQTT broker. Wait for the message to be\r
+ * received which is informed to us by the publish callback\r
+ * (prvExample_PublishCallback) by setting the mqttexampleMESSAGE_RECEIVED_BIT\r
+ * in this task's notification value. */\r
+ xTaskNotifyWait( 0UL, /* Don't clear any bits on entry. */\r
+ 0UL, /* Don't clear any bits on exit. */\r
+ &( ulNotificationValue ), /* Obtain the notification value. */\r
+ pdMS_TO_TICKS( mqttexampleMQTT_TIMEOUT_MS ) );\r
+ configASSERT( ( ulNotificationValue & mqttexampleMESSAGE_RECEIVED_BIT ) == mqttexampleMESSAGE_RECEIVED_BIT );\r
+\r
+ /* Unsubscribe from the topic mqttexampleTOPIC. */\r
+ prvMQTTUnsubscribe();\r
+\r
+ /* Gracefully disconnect from the MQTT broker by sending an MQTT\r
+ * DISCONNECT message. */\r
+ prvMQTTDisconnect();\r
+\r
+ /* Wait for the disconnect operation to complete which is informed to us\r
+ * by the disconnect callback (prvExample_DisconnectCallback)by setting\r
+ * the mqttexampleDISCONNECTED_BIT in this task's notification value.\r
+ * Note that all bits are cleared in the task's notification value to\r
+ * ensure that it is ready for the next run. */\r
+ xTaskNotifyWait( 0UL, /* Don't clear any bits on entry. */\r
+ portMAX_DELAY, /* Clear all bits on exit - portMAX_DELAY is used as it is a portable way of having all bits set. */\r
+ &( ulNotificationValue ), /* Obtain the notification value. */\r
+ pdMS_TO_TICKS( mqttexampleMQTT_TIMEOUT_MS ) );\r
+ configASSERT( ( ulNotificationValue & mqttexampleDISCONNECTED_BIT ) == mqttexampleDISCONNECTED_BIT );\r
+ }\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvMQTTConnect( void )\r
+{\r
+IotMqttError_t xResult;\r
+IotNetworkServerInfo_t xMQTTBrokerInfo;\r
+IotMqttNetworkInfo_t xNetworkInfo = IOT_MQTT_NETWORK_INFO_INITIALIZER;\r
+IotMqttConnectInfo_t xConnectInfo = IOT_MQTT_CONNECT_INFO_INITIALIZER;\r
+\r
+ /******************* Broker information setup. **********************/\r
+ xMQTTBrokerInfo.pHostName = mqttexampleMQTT_BROKER_ENDPOINT;\r
+ xMQTTBrokerInfo.port = mqttexampleMQTT_BROKER_PORT;\r
+\r
+ /******************* Network information setup. **********************/\r
+ /* No connection to the MQTT broker has been established yet and we want to\r
+ * establish a new connection. */\r
+ xNetworkInfo.createNetworkConnection = true;\r
+ xNetworkInfo.u.setup.pNetworkServerInfo = &( xMQTTBrokerInfo );\r
+\r
+ /* This example does not use TLS and therefore pNetworkCredentialInfo must\r
+ * be set to NULL. */\r
+ xNetworkInfo.u.setup.pNetworkCredentialInfo = NULL;\r
+\r
+ /* Use FreeRTOS+TCP network. */\r
+ xNetworkInfo.pNetworkInterface = IOT_NETWORK_INTERFACE_AFR;\r
+\r
+ /* Setup the callback which is called when the MQTT connection is disconnected. */\r
+ xNetworkInfo.disconnectCallback.pCallbackContext = ( void * ) xTaskGetCurrentTaskHandle();\r
+ xNetworkInfo.disconnectCallback.function = prvExample_DisconnectCallback;\r
+\r
+ /****************** MQTT Connection information setup. ********************/\r
+ /* This example does not use TLS and therefore won't work with AWS IoT. */\r
+ xConnectInfo.awsIotMqttMode = false;\r
+\r
+ /* Start with a clean session i.e. direct the MQTT broker to discard any\r
+ * previous session data. Also, establishing a connection with clean session\r
+ * will ensure that the broker does not store any data when this client\r
+ * gets disconnected. */\r
+ xConnectInfo.cleanSession = true;\r
+\r
+ /* Since we are starting with a clean session, there are no previous\r
+ * subscriptions to be restored. */\r
+ xConnectInfo.pPreviousSubscriptions = NULL;\r
+ xConnectInfo.previousSubscriptionCount = 0;\r
+\r
+ /* We do not want to publish Last Will and Testament (LWT) message if the\r
+ * client gets disconnected. */\r
+ xConnectInfo.pWillInfo = NULL;\r
+\r
+ /* Send an MQTT PING request every minute. */\r
+ xConnectInfo.keepAliveSeconds = mqttexampleKEEP_ALIVE_SECONDS;\r
+\r
+ /* The client identifier is used to uniquely identify this MQTT client to\r
+ * the MQTT broker. */\r
+ xConnectInfo.pClientIdentifier = mqttexampleCLIENT_IDENTIFIER;\r
+ xConnectInfo.clientIdentifierLength = ( uint16_t ) strlen( mqttexampleCLIENT_IDENTIFIER );\r
+\r
+ /* This example does not use any authentication and therefore username and\r
+ * password fields are not used. */\r
+ xConnectInfo.pUserName = NULL;\r
+ xConnectInfo.userNameLength = 0;\r
+ xConnectInfo.pPassword = NULL;\r
+ xConnectInfo.passwordLength = 0;\r
+\r
+ /* Establish the connection to the MQTT broker - It is a blocking call and\r
+ will return only when connection is complete. */\r
+ xResult = IotMqtt_Connect( &( xNetworkInfo ),\r
+ &( xConnectInfo ),\r
+ mqttexampleMQTT_TIMEOUT_MS,\r
+ &( xMQTTConnection ) );\r
+ configASSERT( xResult == IOT_MQTT_SUCCESS );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvMQTTSubscribe( void )\r
+{\r
+IotMqttError_t xResult;\r
+IotMqttSubscription_t xMQTTSubscription;\r
+\r
+ /* Subscribe to the mqttexampleTOPIC topic filter. */\r
+ xMQTTSubscription.qos = IOT_MQTT_QOS_1;\r
+ xMQTTSubscription.pTopicFilter = mqttexampleTOPIC;\r
+ xMQTTSubscription.topicFilterLength = ( uint16_t ) strlen( mqttexampleTOPIC );\r
+ xMQTTSubscription.callback.pCallbackContext = ( void * ) xTaskGetCurrentTaskHandle();\r
+ xMQTTSubscription.callback.function = prvExample_PublishCallback;\r
+\r
+ /* Use the synchronous API to subscribe - It is a blocking call and only\r
+ * returns when the subscribe operation is complete. */\r
+ xResult = IotMqtt_TimedSubscribe( xMQTTConnection,\r
+ &( xMQTTSubscription ),\r
+ 1, /* We are subscribing to one topic filter. */\r
+ 0, /* flags - currently ignored. */\r
+ mqttexampleMQTT_TIMEOUT_MS );\r
+ configASSERT( xResult == IOT_MQTT_SUCCESS );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvMQTTPublish( void )\r
+{\r
+IotMqttError_t xResult;\r
+IotMqttPublishInfo_t xMQTTPublishInfo;\r
+\r
+ /* Publish a message with QoS1 on the mqttexampleTOPIC topic. Since we are\r
+ * subscribed to the same topic, the MQTT broker will send the same message\r
+ * back to us. It is verified in the publish callback. */\r
+ xMQTTPublishInfo.qos = IOT_MQTT_QOS_1;\r
+ xMQTTPublishInfo.retain = false;\r
+ xMQTTPublishInfo.pTopicName = mqttexampleTOPIC;\r
+ xMQTTPublishInfo.topicNameLength = ( uint16_t ) strlen( mqttexampleTOPIC );\r
+ xMQTTPublishInfo.pPayload = mqttexampleMESSAGE;\r
+ xMQTTPublishInfo.payloadLength = strlen( mqttexampleMESSAGE );\r
+ xMQTTPublishInfo.retryMs = mqttexamplePUBLISH_RETRY_MS;\r
+ xMQTTPublishInfo.retryLimit = mqttexamplePUBLISH_RETRY_LIMIT;\r
+\r
+ /* Use the synchronous API to publish - It is a blocking call and only\r
+ * returns when the publish operation is complete. */\r
+ xResult = IotMqtt_TimedPublish( xMQTTConnection,\r
+ &( xMQTTPublishInfo ),\r
+ 0, /* flags - currently ignored. */\r
+ mqttexampleMQTT_TIMEOUT_MS );\r
+ configASSERT( xResult == IOT_MQTT_SUCCESS );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvMQTTUnsubscribe( void )\r
+{\r
+IotMqttError_t xResult;\r
+IotMqttSubscription_t xMQTTSubscription;\r
+\r
+ /* Unsubscribe from the mqttexampleTOPIC topic filter. */\r
+ xMQTTSubscription.pTopicFilter = mqttexampleTOPIC;\r
+ xMQTTSubscription.topicFilterLength = ( uint16_t ) strlen( mqttexampleTOPIC );\r
+ /* The following members of the IotMqttSubscription_t are ignored by the\r
+ * unsubscribe operation. Just initialize them to avoid "use of uninitialized\r
+ * variable" warnings. */\r
+ xMQTTSubscription.qos = IOT_MQTT_QOS_1;\r
+ xMQTTSubscription.callback.pCallbackContext = NULL;\r
+ xMQTTSubscription.callback.function = NULL;\r
+\r
+ /* Use the synchronous API to unsubscribe - It is a blocking call and only\r
+ * returns when the unsubscribe operation is complete. */\r
+ xResult = IotMqtt_TimedUnsubscribe( xMQTTConnection,\r
+ &( xMQTTSubscription ),\r
+ 1, /* We are unsubscribing from one topic filter. */\r
+ 0, /* flags - currently ignored. */\r
+ mqttexampleMQTT_TIMEOUT_MS );\r
+ configASSERT( xResult == IOT_MQTT_SUCCESS );\r
+}\r
+/*-----------------------------------------------------------*/\r
+\r
+static void prvMQTTDisconnect( void )\r
+{\r
+ /* Send a MQTT DISCONNECT packet to the MQTT broker to do a graceful\r
+ * disconnect. */\r
+ IotMqtt_Disconnect( xMQTTConnection,\r
+ 0 /* flags - 0 means a graceful disconnect by sending MQTT DISCONNECT. */\r
+ );\r
+}\r
+/*-----------------------------------------------------------*/\r