Quality RTOS & Embedded Software

LIBRARIES
NOTE: The LW MQTT demo is in the FreeRTOS Labs.  The libraries in the FreeRTOS Labs download directory are fully functional, but undergoing optimizations or refactoring to improve memory usage, modularity, documentation, demo usability, or test coverage.  They are available as part of the FreeRTOS-Labs download

Basic MQTT Demo (Lightweight API)

Notice: It is our recommendation to always use strong mutual authentication in any Internet of Things (IoT) application. The lightweight project (this page) is only provided to demonstrate the usage of the lightweight MQTT API. This project is not intended to be an example suitable for production use.

Introduction

The lightweight MQTT demo project uses the FreeRTOS Windows port, enabling it to be built and evaluated with the free Community version of Visual Studios on Windows, so without the need for any particular MCU hardware. The lightweight MQTT demo is intended to showcase the features of a lightweight API. This lightweight API requires no dynamic memory allocation, nor does it have any dependencies on other libraries unlike the fully managed API. It also does not maintain any internal state. Note that this demo does not create a secure connection. Like the basic MQTT demo, the lightweight MQTT demo can connect to any non-secure MQTT broker. The instructions provided below will demonstrate how to connect to either Mosquitto’s test broker hosted on the internet or on a server running locally on the host. This demo is intended to be used as a learning exercise only. All MQTT messages are sent in plaintext and are not encrypted. Do NOT send any confidential information from your device to the MQTT broker. The MQTT broker is publicly hosted by a 3rd party that is not affiliated with FreeRTOS. This MQTT broker may be unavailable at any time, and it is not maintained by FreeRTOS. Note: Mosquitto is an open source MQTT message broker that supports MQTT versions 5.0, 3.1.1, and 3.1. It is part of the Eclipse foundation and is a project.

 

Code Size of Lightweight MQTT API (example generated with GCC for ARM Cortex-M)
FileWith -O1 OptimisationWith -Os Optimisation
iot_mqtt_lightweight_api.c1.0K0.7K
iot_mqtt_helper.c0.8K0.8K
Total estimate (configurations defined here)1.8K1.5K
 

Source Code Organization

Click to enlarge
The Visual Studio solution for the lightweight MQTT demo is called mqtt_light_weight_demo.sln and is located in the FreeRTOS-LabsDemoFreeRTOS_IoT_Librariesmqttmqtt_light_weight directory of the main FreeRTOS download. Note: This project is part of the main download.

Configuring the Demo Project

The demo uses the FreeRTOS+TCP TCP/IP stack, so follow the instructions provided for the TCP/IP starter project to ensure you:
  1. Have the pre-requisite components installed (such as WinPCap).
  2. Optionally set a static or dynamic IP address, gateway address and netmask.
  3. Optionally set a MAC address.
  4. Select an Ethernet network interface on your host machine.
  5. …and importantly test your network connection before attempting to run the MQTT demo.
All these setting should be performed in the MQTT demo project, not the TCP/IP starter project referenced from the same page! As delivered the TCP/IP stack is configured to use a dynamic IP address.

Configuring the MQTT Broker Connection

Configure the Client ID The Client ID is currently hard coded within the source file (FreeRTOS-LabsDemoFreeRTOS_IoT_Librariesincludemqtt_demo_profile.h). As it is hard coded, every user who downloads the demo will have the same Client ID. Change it to something unique in the line below or else only one client will be able to connect to the broker at a time. #define mqttdemoprofileCLIENT_IDENTIFIER "mqttexampleclient" Mosquitto Public Message Broker (Web Hosted) The demo project is pre-configured to communicate with Mosquitto’s publicly hosted message broker at “test.mosqitto.org” – so the network to which the demo is connected must have a DHCP service and internet access. Note public MQTT brokers can be slow. If you would like to connect to a different public broker then:
  1. Open FreeRTOS-LabsDemoFreeRTOS_IoT_Librariesincludemqtt_demo_profile.h.
  2. Edit the following lines to be correct for your chosen broker:#define mqttdemoprofileBROKER_ENDPOINT "test.mosquitto.org" #define mqttdemoprofileBROKER_PORT 1883
Mosquitto Local Message Broker (Host Machine) It is also possible to run the Mosquitto broker locally, either on your host machine (the machine used to build the demo application), or another machine on your local network. To do this:
  1. Follow the instructions on https://mosquitto.org/download/ to download and install Mosquitto locally.
  2. Find the IP address of your host machine (run the ipconfig command on Windows, or ifconfig on Linux or macOS).
  3. Open FreeRTOS-LabsDemoFreeRTOS_IoT_Librariesincludemqtt_demo_profile.h.
  4. Edit the following lines so mqttdemoprofileBROKER_ENDPOINT is set to the IP address of the machine on which Mosquitto is running. #define mqttdemoprofileBROKER_ENDPOINT "test.mosquitto.org" #define mqttdemoprofileBROKER_PORT 1883
Note: Port number 1883 is the default port number for unencrypted MQTT. If you cannot use that port (for example if it is blocked by your IT security policy) then change the port used by Mosquitto to a high port number (for example something in the 50000 to 55000 range), and set mqttexampleMQTT_BROKER_PORT accordingly.

Building the Demo Project

The demo project uses the free community edition of Visual Studio. To build the demo:
  1. Open the FreeRTOS-LabsDemoFreeRTOS_IoT_Librariesmqttmqtt_light_weightmqtt_light_weight_demo.sln Visual Studio solution file from within the Visual Studio IDE
  2. Select ‘build solution’ from the IDE’s ‘build’ menu

Functionality

The demo creates a single application task that loops through a set of examples that demonstrate how to connect to the broker, subscribe to a topic on the broker, publish to a topic on the broker, and disconnect from the broker again. The demo application both subscribes to and publishes to the same topic, as a result of which each time the demo publishes a message to the MQTT broker the broker sends the same message back to the demo application. The structure of the demo is shown below:
static void prvMQTTDemoTask( void * pvParameters )
{
const TickType_t xNoDelay = ( TickType_t ) 0;
Socket_t xMQTTSocket;
uint32_t ulPublishCount = 0;
const uint32_t ulMaxPublishCount = 5UL;

	/* Remove compiler warnings about unused parameters. */
	( void ) pvParameters;

	for( ; ; )
	{
		/* Don't expect any notifications to be pending yet. */
		configASSERT( ulTaskNotifyTake( pdTRUE, xNoDelay ) == 0 );

		/****************************** Connect. ******************************/
		/* Establish a TCP connection with the MQTT broker. This example connects to
		 * the MQTT broker as specified in mqttexampleMQTT_BROKER_ENDPOINT and
		 * mqttexampleMQTT_BROKER_PORT at the top of this file. */
		configPRINTF( ( "Create a TCP connection to %srn",
                                mqttexampleMQTT_BROKER_ENDPOINT ) );
		xMQTTSocket = prvCreateTCPConnectionToBroker();

		/* Sends an MQTT Connect packet over the already connected TCP socket
		 * xMQTTSocket, and waits for connection acknowledgment (CONNACK) packet. */
		configPRINTF( ( "Creating an MQTT connection to %srn",
                                mqttexampleMQTT_BROKER_ENDPOINT ) );
		prvCreateMQTTConnectionWithBroker( xMQTTSocket );

		/**************************** Subscribe. ******************************/

		/* The client is now connected to the broker. Subscribe to the topic
		 * as specified in mqttexampleTOPIC at the top of this file by sending a
		 * subscribe packet then waiting for a subscribe acknowledgment (SUBACK).
		 * This client will then publish to the same topic it subscribed to, so it
		 * will expect all the messages it sends to the broker to be sent back to it
		 * from the broker. This demo uses QOS0 in Subscribe, therefore, the Publish
		 * messages received from the broker will have QOS0. */
		configPRINTF( ( "Attempt to subscribed to the MQTT topic %srn",
                                mqttexampleTOPIC ) );
		prvMQTTSubscribeToTopic( xMQTTSocket );
		configPRINTF( ( "Sent Subscribe message to the broker. rn" ) );

		/* Process incoming packet from the broker. After sending the subscribe, the
		 * client may receive a publish before it receives a subscribe ack. Therefore,
		 * call generic incoming packet processing function. Since this demo is
		 * subscribing to the topic to which no one is publishing, probability of
		 * receiving Publish message before subscribe ack is zero; but application
		 * must be ready to receive any packet. This demo uses the generic packet
		 * processing function everywhere to highlight this fact. */
		prvMQTTProcessIncomingPacket( xMQTTSocket );

		/********************* Publish and Keep Alive Loop. ***********************/
		/* Publish messages with QOS0, send and process Keep alive messages. */
		for( ulPublishCount = 0; ulPublishCount < ulMaxPublishCount; ulPublishCount++ )
		{
			configPRINTF( ( "Publish to the MQTT topic %srn",
                                        mqttexampleTOPIC ) );
			prvMQTTPublishToTopic( xMQTTSocket );

			/* Process incoming publish echo, since application subscribed
                         * to the same topic the broker will send publish message back
                         * to the application. */
			configPRINTF( ( "Attempt to receive publish message from broker"
                                        "rn" ) );
			/* Process Incoming packet from the broker */
			prvMQTTProcessIncomingPacket( xMQTTSocket );

			/* Leave Connection Idle for some time */
			configPRINTF( ( "Keeping Connection Idlern" ) );
			vTaskDelay( pdMS_TO_TICKS( mqttexampleKEEP_ALIVE_DELAY ) );
			/* Send Ping request to broker and receive ping response */
			configPRINTF( ( "Sending Ping Request to the brokerrn" ) );
			prvMQTTKeepAlive( xMQTTSocket );

			/* Process Incoming packet from the broker */
			prvMQTTProcessIncomingPacket( xMQTTSocket );
		}

		/********************* Unsubscribe from the topic. ***********************/
		configPRINTF( ( "Unsubscribe from the MQTT topic %s.rn",
                                mqttexampleTOPIC ) );
		prvMQTTUnsubscribeFromTopic( xMQTTSocket );
		/* Process Incoming packet from the broker. */
		prvMQTTProcessIncomingPacket( xMQTTSocket );

		/***************************** Disconnect. *******************************/
		/* Send an MQTT Disconnect packet over the already connected TCP socket. 
		 * There is no corresponding response for the disconnect packet. After
                 * sending disconnect, client must close the network connection. */
		configPRINTF( ( "Disconnecting the MQTT connection with %s.rn",
                                mqttexampleMQTT_BROKER_ENDPOINT ) );
		prvMQTTDisconnect( xMQTTSocket );

		/* Close the network connection.  */
		prvGracefulShutDown( xMQTTSocket );

		/* Wait for some time between two iterations to ensure that we do not
		 * bombard the public test mosquitto broker. */
		configPRINTF( ( "prvMQTTDemoTask() completed an iteration successfully. "
                                "Total free heap is %urn",
                                xPortGetFreeHeapSize() ) );
		configPRINTF( ( "Short delay before starting the next iteration.... "
                                "rnrn" ) );
		vTaskDelay( pdMS_TO_TICKS( mqttexampleDELAY_BETWEEN_DEMO_ITERATIONS ) );
	}
}

Where prvCreateTCPConnectionToBroker() is defined as:

static Socket_t prvCreateTCPConnectionToBroker( void )

static Socket_t prvCreateTCPConnectionToBroker( void )
{
Socket_t xMQTTSocket = FREERTOS_INVALID_SOCKET;
struct freertos_sockaddr xBrokerAddress;
uint32_t ulBrokerIPAddress;
BaseType_t xStatus = pdFAIL;

	/* This is the socket used to connect to the MQTT broker. */
	xMQTTSocket = FreeRTOS_socket( FREERTOS_AF_INET,
	                               FREERTOS_SOCK_STREAM,
	                               FREERTOS_IPPROTO_TCP );

	if( xMQTTSocket != FREERTOS_INVALID_SOCKET )
	{
		/* Socket was created.  Locate then connect to the MQTT broker. */
		ulBrokerIPAddress = FreeRTOS_gethostbyname( mqttexampleMQTT_BROKER_ENDPOINT );

		if( ulBrokerIPAddress != 0 )
		{
			xBrokerAddress.sin_port =
                            FreeRTOS_htons( mqttexampleMQTT_BROKER_PORT );
			xBrokerAddress.sin_addr = ulBrokerIPAddress;

			if( FreeRTOS_connect( xMQTTSocket,
                                              &xBrokerAddress,
                                              sizeof( xBrokerAddress ) ) == 0 )
			{
				/* Connection was successful. */
				xStatus = pdPASS;
			}
			else
			{
				configPRINTF( ( "Located but could not "
                                                "connect to MQTT broker %s."
                                                "rnrn",
                                                mqttexampleMQTT_BROKER_ENDPOINT ) );
			}
		}
		else
		{
			configPRINTF( ( "Could not locate MQTT broker %s."
                                        "rnrn",
                                        mqttexampleMQTT_BROKER_ENDPOINT ) );
		}
	}
	else
	{
		configPRINTF( ( "Could not create TCP socket.rnrn" ) );
	}

	/* If the socket was created but the connection was not successful then delete
	the socket again. */
	if( xStatus == pdFAIL )
	{
		if( xMQTTSocket != FREERTOS_INVALID_SOCKET )
		{
			FreeRTOS_closesocket( xMQTTSocket );
			xMQTTSocket = FREERTOS_INVALID_SOCKET;
		}
	}

	return xMQTTSocket;
}
The screenshot below shows the expected output when the demo is executing correctly.
Click to enlarge

Connecting to the MQTT Broker

The function prvCreateMQTTConnectionWithBroker() demonstrates how to establish an unencrypted connection to a MQTT broker with clean session. It uses the FreeRTOS+TCP network interface which is implemented in the file FreeRTOS-LabsSourceFreeRTOS-IoT-Librariesabstractionsplatformfreertosiot_network_freertos.c. The definition of prvCreateMQTTConnectionWithBroker() is shown below:
static void prvCreateMQTTConnectionWithBroker( Socket_t xMQTTSocket )
{
IotMqttConnectInfo_t xConnectInfo;
size_t xRemainingLength;
size_t xPacketSize;
IotMqttError_t xResult;
IotMqttPacketInfo_t xIncomingPacket;
BaseType_t xStatus;

	/***
	 * For readability, error handling in this function is restricted to the use of
	 * asserts().
	 ***/

	/* Many fields not used in this demo so start with everything at 0. */
	memset( ( void * ) &xConnectInfo, 0x00, sizeof( xConnectInfo ) );

	/* Start with a clean session i.e. direct the MQTT broker to discard any
	 * previous session data. Also, establishing a connection with clean session
	 * will ensure that the broker does not store any data when this client
	 * gets disconnected. */
	xConnectInfo.cleanSession = true;

	/* The client identifier is used to uniquely identify this MQTT client to
	 * the MQTT broker. In a production device the identifier can be something
	 * unique, such as a device serial number. */
	xConnectInfo.pClientIdentifier = mqttexampleCLIENT_IDENTIFIER;
	xConnectInfo.clientIdentifierLength =
            ( uint16_t ) strlen( mqttexampleCLIENT_IDENTIFIER );

	/* Get size requirement for the connect packet */
	xResult = IotMqtt_GetConnectPacketSize( &xConnectInfo,
                                                &xRemainingLength,
                                                &xPacketSize );

	/* Make sure the packet size is less than static buffer size. */
	configASSERT( xResult == IOT_MQTT_SUCCESS );
	configASSERT( xPacketSize < mqttexampleSHARED_BUFFER_SIZE );
	/* Serialize MQTT connect packet into the provided buffer. */
	xResult = IotMqtt_SerializeConnect( &xConnectInfo,
                                            xRemainingLength,
                                            ucSharedBuffer,
                                            xPacketSize );
	configASSERT( xResult == IOT_MQTT_SUCCESS );

	xStatus = FreeRTOS_send( xMQTTSocket,
                                 ( void * ) ucSharedBuffer,
                                 xPacketSize,
                                 0 );
	configASSERT( xStatus == ( BaseType_t ) xPacketSize );

	/* Reset all fields of the incoming packet structure. */
	memset( ( void * ) &xIncomingPacket, 0x00, sizeof( IotMqttPacketInfo_t ) );

	/* Wait for connection acknowledgment. We cannot assume received data is the
	 * connection acknowledgment. Therefore this function reads type and remaining
	 * length of the received packet, before processing entire packet - although in
	 * this case to keep the example simple error checks are just performed by
	 * asserts.
	 */
	xResult = IotMqtt_GetIncomingMQTTPacketTypeAndLength( &xIncomingPacket,
                                                              getNextByte,
                                                              ( void * ) xMQTTSocket );
	configASSERT( xResult == IOT_MQTT_SUCCESS );
	configASSERT( xIncomingPacket.type == MQTT_PACKET_TYPE_CONNACK );
	configASSERT( xIncomingPacket.remainingLength <= mqttexampleSHARED_BUFFER_SIZE );

	/* Now receive the reset of the packet into the statically allocated buffer. */
	xStatus = FreeRTOS_recv( xMQTTSocket,
                                 ( void * ) ucSharedBuffer,
                                 xIncomingPacket.remainingLength,
                                 0 );
	configASSERT( xStatus == ( BaseType_t ) xIncomingPacket.remainingLength );

	xIncomingPacket.pRemainingData = ucSharedBuffer;
	xResult = IotMqtt_DeserializeResponse( &xIncomingPacket );

	configASSERT( xResult == IOT_MQTT_SUCCESS );

	if( xResult != IOT_MQTT_SUCCESS )
	{
		configPRINTF( ( "Connection with MQTT broker failed.rn" ) );
	}
}

Subscribing to a MQTT Topic

The function prvMQTTSubscribeToTopic() demonstrates how to subscribe to a topic filter on the MQTT broker. The example demonstrates how to subscribe to one topic filter but it possible to pass a list of topic filters in the same subscribe API call to subscribe to more than one topic filters. The definition of the function is shown below:
static void prvMQTTSubscribeToTopic( Socket_t xMQTTSocket )
{
IotMqttError_t xResult;
IotMqttSubscription_t xMQTTSubscription[ 1 ];
size_t xRemainingLength;
size_t xPacketSize;
size_t xSubscriptionCount;
BaseType_t xStatus;

	/***
	 * For readability, error handling in this function is restricted to the use of
	 * asserts().
	 ***/


	/* Some fields not used by this demo so start with everything at 0. */
	memset( ( void * ) &xMQTTSubscription, 0x00, sizeof( xMQTTSubscription ) );

        xSubscriptionCount = sizeof( xMQTTSubscription ) / sizeof( IotMqttSubscription_t );

	/* Subscribe to the mqttexampleTOPIC topic filter. This example subscribes to
	 * only one topic and uses QOS0. */
	xMQTTSubscription[ 0 ].qos = IOT_MQTT_QOS_0;
	xMQTTSubscription[ 0 ].pTopicFilter = mqttexampleTOPIC;
	xMQTTSubscription[ 0 ].topicFilterLength = ( uint16_t ) strlen( mqttexampleTOPIC );

	xResult = IotMqtt_GetSubscriptionPacketSize( IOT_MQTT_SUBSCRIBE,
	                                             xMQTTSubscription,
	                                             xSubscriptionCount,
	                                             &xRemainingLength, &xPacketSize );

	/* Make sure the packet size is less than static buffer size. */
	configASSERT( xResult == IOT_MQTT_SUCCESS );
	configASSERT( xPacketSize < mqttexampleSHARED_BUFFER_SIZE );

	/* Serialize subscribe into statically allocated ucSharedBuffer. */
	xResult = IotMqtt_SerializeSubscribe( xMQTTSubscription,
	                                      xSubscriptionCount,
	                                      xRemainingLength,
	                                      &usSubscribePacketIdentifier,
	                                      ucSharedBuffer,
	                                      xPacketSize );

	configASSERT( xResult == IOT_MQTT_SUCCESS );

	/* Send Subscribe request to the broker. */
	xStatus = FreeRTOS_send( xMQTTSocket, ( void * ) ucSharedBuffer, xPacketSize, 0 );
	configASSERT( xStatus == ( BaseType_t ) xPacketSize );
}

Publishing to a Topic

The function prvMQTTPublishToTopic() demonstrates how to publish on a topic on the MQTT broker. The definition of the function is shown below:
static void prvMQTTPublishToTopic( Socket_t xMQTTSocket )
{
IotMqttError_t xResult;
IotMqttPublishInfo_t xMQTTPublishInfo;
size_t xRemainingLength;
size_t xPacketSize = 0;
uint8_t * pusPacketIdentifierHigh;
BaseType_t xStatus;

	/***
	 * For readability, error handling in this function is restricted to the use of
	 * asserts().
	 ***/

	/* Some fields not used by this demo so start with everything at 0. */
	memset( ( void * ) &xMQTTPublishInfo, 0x00, sizeof( xMQTTPublishInfo ) );

	/* This demo uses QOS0 */
	xMQTTPublishInfo.qos = IOT_MQTT_QOS_0;
	xMQTTPublishInfo.retain = false;
	xMQTTPublishInfo.pTopicName = mqttexampleTOPIC;
	xMQTTPublishInfo.topicNameLength = ( uint16_t ) strlen( mqttexampleTOPIC );
	xMQTTPublishInfo.pPayload = mqttexampleMESSAGE;
	xMQTTPublishInfo.payloadLength = strlen( mqttexampleMESSAGE );

	/* Find out length of Publish packet size. */
	xResult = IotMqtt_GetPublishPacketSize( &xMQTTPublishInfo,
                                                &xRemainingLength,
                                                &xPacketSize );
	configASSERT( xResult == IOT_MQTT_SUCCESS );
	/* Make sure the packet size is less than static buffer size */
	configASSERT( xPacketSize < mqttexampleSHARED_BUFFER_SIZE );

	xResult = IotMqtt_SerializePublish( &xMQTTPublishInfo,
	                                    xRemainingLength,
	                                    &usPublishPacketIdentifier,
	                                    &pusPacketIdentifierHigh,
	                                    ucSharedBuffer,
	                                    xPacketSize );
	configASSERT( xResult == IOT_MQTT_SUCCESS );

	/* Send Publish message to the broker. */
	xStatus = FreeRTOS_send( xMQTTSocket, ( void * ) ucSharedBuffer, xPacketSize, 0 );
	configASSERT( xStatus == ( BaseType_t ) xPacketSize );
}

Unsubscribing from a Topic

The function prvMQTTUnsubscribeFromTopic() demonstrates how to unsubscribe from a topic on the MQTT broker. The definition of the function is shown below:
static void prvMQTTUnsubscribeFromTopic( Socket_t xMQTTSocket )
{
IotMqttError_t xResult;
IotMqttSubscription_t xMQTTSubscription[ 1 ];
size_t xRemainingLength;
size_t xPacketSize;
size_t xSubscriptionCount;
BaseType_t xStatus;

        xSubscriptionCount = sizeof( xMQTTSubscription ) / sizeof( IotMqttSubscription_t );

	/* Some fields not used by this demo so start with everything at 0. */
	memset( ( void * ) &xMQTTSubscription, 0x00, sizeof( xMQTTSubscription ) );

	/* Unsubscribe to the mqttexampleTOPIC topic filter. The task handle is passed
	 * as the callback context which is used by the callback to send a task
	 * notification to this task.*/
	xMQTTSubscription[ 0 ].qos = IOT_MQTT_QOS_0;
	xMQTTSubscription[ 0 ].pTopicFilter = mqttexampleTOPIC;
	xMQTTSubscription[ 0 ].topicFilterLength = ( uint16_t ) strlen( mqttexampleTOPIC );

	xResult = IotMqtt_GetSubscriptionPacketSize( IOT_MQTT_UNSUBSCRIBE,
	                                             xMQTTSubscription,
	                                             xSubscriptionCount,
	                                             &xRemainingLength,
	                                             &xPacketSize );
	configASSERT( xResult == IOT_MQTT_SUCCESS );
	/* Make sure the packet size is less than static buffer size */
	configASSERT( xPacketSize < mqttexampleSHARED_BUFFER_SIZE );

	xResult = IotMqtt_SerializeUnsubscribe( xMQTTSubscription,
	                                        xSubscriptionCount,
	                                        xRemainingLength,
	                                        &usUnsubscribePacketIdentifier,
	                                        ucSharedBuffer,
	                                        xPacketSize );
	configASSERT( xResult == IOT_MQTT_SUCCESS );

	/* Send Unsubscribe request to the broker. */
	xStatus = FreeRTOS_send( xMQTTSocket, ( void * ) ucSharedBuffer, xPacketSize, 0 );
	configASSERT( xStatus == ( BaseType_t ) xPacketSize );
}

Sending a Keep-Alive Ping Request

The function prvMQTTKeepAlive() demonstrates how to send a ping request packet for MQTT keep-alive. The definition of the function is shown below:
static void prvMQTTKeepAlive( Socket_t xMQTTSocket )
{
IotMqttError_t xResult;
BaseType_t xStatus;

	/* PingReq is fixed length packet, therefore there is no need to
         * calculate the size, just makes sure static buffer can accommodate
         * ping request. */
	configASSERT( MQTT_PACKET_PINGREQ_SIZE <= mqttexampleSHARED_BUFFER_SIZE );

	xResult = IotMqtt_SerializePingreq( ucSharedBuffer,
                                            MQTT_PACKET_PINGREQ_SIZE );
	configASSERT( xResult == IOT_MQTT_SUCCESS );

	/* Send Ping Request to the broker. */
	xStatus = FreeRTOS_send( xMQTTSocket,
                                 ( void * ) ucSharedBuffer,
                                 MQTT_PACKET_PINGREQ_SIZE,
                                 0 );
	configASSERT( xStatus == ( BaseType_t ) MQTT_PACKET_PINGREQ_SIZE );
}

Processing Incoming MQTT Packets

To function prvMQTTProcessIncomingPacket demonstrates how process an incoming MQTT packet. The definition of the function is shown below:
static void prvMQTTProcessIncomingPacket( Socket_t xMQTTSocket )
{
IotMqttError_t xResult;
IotMqttPacketInfo_t xIncomingPacket;
BaseType_t xStatus;

	/***
	 * For readability, error handling in this function is restricted to the use of
	 * asserts().
	 ***/

	memset( ( void * ) &xIncomingPacket, 0x00, sizeof( IotMqttPacketInfo_t ) );

	/* Determine incoming packet type and remaining length. */
	xResult = IotMqtt_GetIncomingMQTTPacketTypeAndLength( &xIncomingPacket,
                                                              getNextByte,
                                                              ( void * ) xMQTTSocket );
	configASSERT( xResult == IOT_MQTT_SUCCESS );
	configASSERT( xIncomingPacket.remainingLength <= mqttexampleSHARED_BUFFER_SIZE );

	/* Current implementation expects an incoming Publish and three different
	 * responses ( SUBACK, PINGRESP and UNSUBACK ). */

	/* Receive the remaining bytes. */
	xStatus = FreeRTOS_recv( xMQTTSocket,
                                 ( void * ) ucSharedBuffer,
                                 xIncomingPacket.remainingLength,
                                 0 );
	configASSERT( xStatus == ( BaseType_t ) xIncomingPacket.remainingLength );

	xIncomingPacket.pRemainingData = ucSharedBuffer;

	if( ( xIncomingPacket.type & 0xf0 ) == MQTT_PACKET_TYPE_PUBLISH )
	{
		xResult = IotMqtt_DeserializePublish( &xIncomingPacket );
		configASSERT( xResult == IOT_MQTT_SUCCESS );
		/* Process incoming Publish message. */
		prvMQTTProcessIncomingPublish( &xIncomingPacket );
	}
	else
	{
		/* If the received packet is not a Publish message, then
                 * it is an ACK for one of the messages we sent out, verify
                 * that the ACK packet is a valid MQTT packet. */
		xResult = IotMqtt_DeserializeResponse( &xIncomingPacket );
		configASSERT( xResult == IOT_MQTT_SUCCESS );
		/* Process the response */
		prvMQTTProcessResponse( &xIncomingPacket );
	}
}

Disconnecting from the MQTT Message Broker

The function prvMQTTDisconnect() demonstrates how to gracefully disconnect from the MQTT broker. The definition of the function is shown below:
static void prvMQTTDisconnect( Socket_t xMQTTSocket )
{
IotMqttError_t xResult;
BaseType_t xStatus;

	/* Disconnect is fixed length packet, therefore there is no need to calculate the size,
	 * just makes sure static buffer can accommodate disconnect request. */
	configASSERT( MQTT_PACKET_DISCONNECT_SIZE <= mqttexampleSHARED_BUFFER_SIZE );

	xResult = IotMqtt_SerializeDisconnect( ucSharedBuffer,
                                               MQTT_PACKET_DISCONNECT_SIZE );
	configASSERT( xResult == IOT_MQTT_SUCCESS );

	xStatus = FreeRTOS_send( xMQTTSocket,
                                 ( void * ) ucSharedBuffer,
                                 MQTT_PACKET_DISCONNECT_SIZE, 0 );
	configASSERT( xStatus == ( BaseType_t ) MQTT_PACKET_DISCONNECT_SIZE );
}
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.