coreMQTT Demo (with TLS Server Authentication)
coreMQTT is an MIT licensed open source MQTT client C library for microcontroller and small microprocessor based IoT devices.
Notice: We recommend using mutual authentication (both the IoT MQTT client and server authenticate each other) when building any Internet of Things (IoT) application. The demo on this page is only meant for educational purposes as it demonstrates encrypted communication without client authentication. It is not intended for production use.
Single Threaded Vs Multi Threaded
There are two coreMQTT usage models, single threaded
(multitasking). Using the MQTT library solely from one thread within an otherwise multi-threaded application, as the demo documented on this page does, is equivalent to the single threaded use case. Single threaded use cases require the application writer to make repeated explicit calls into the MQTT library. Multithreaded use cases can instead execute the MQTT protocol in the background within an agent (or daemon) task
. Executing the MQTT protocol in an agent task removes the need for the application writer to explicitly manage any MQTT state or call the
API function. Using an agent task also enables multiple application tasks to share a single MQTT connection without the need for synchronization primitives such as mutexes.
This example project is one of three that introduce the concepts described on the “TLS Introduction” page one at a time. The first example demonstrates unencrypted MQTT communication. The second example (on this page) builds on the first to introduce server authentication (where the IoT client authenticates the MQTT server it connects to). The third example builds on the second to introduce strong mutual authentication (where the MQTT server also authenticates the client connecting to it).
This demo does not use mutual authentication so is intended to be used as a learning exercise only.
This MQTT demo uses an mbedTLS-based network transport interface implementation to first establish a server-authenticated TLS connection with the MQTT broker, and then demonstrate the subscribe-publish workflow of MQTT at the QoS 2 level. The demo has the broker echo messages back by subscribing to a single topic filter and then publishing to that same topic. After each publish, it waits to receive the message back from the server at the QoS 2 level. This cycle of publishing to the broker and receiving the same message back from the broker is repeated indefinitely. Messages in this demo are sent at QoS 2 which guarantees exactly once message delivery.
This basic MQTT demo project uses the FreeRTOS Windows port, enabling it to be built and evaluated with the free Community version of Visual Studio on Windows, so without the need for any particular MCU hardware.
Source Code Organization
The demo project is called mqtt_basic_tls_demo.sln and can be found in the FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS directory of the main FreeRTOS download (and in Github, linked from the download page).
Configuring the Demo Project
The demo uses the FreeRTOS+TCP TCP/IP stack. Follow the instructions provided for the TCP/IP starter project to ensure you:
- Have the pre-requisite components installed (such as WinPCap).
- Optionally, set a static or dynamic IP address, gateway address and netmask.
- Optionally, set a MAC address.
- Select an Ethernet network interface on your host machine.
- …and most important, 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
Option 1: Using the publicly hosted Mosquitto MQTT broker (web hosted):
To communicate with Mosquitto’s publicly hosted MQTT broker, follow these steps:
- Open your local copy of
- Set the following two constants as shown here:
#define democonfigMQTT_BROKER_ENDPOINT "test.mosquitto.org"
#define democonfigMQTT_BROKER_PORT (8883)
- Set the constant
#democonfigROOT_CA_PEM (the server’s root CA certificate) to the PEM certificate linked to from the main https://test.mosquitto.org page. The certificate needs to be pasted as a string, so it will look like this:
#define democonfigROOT_CA_PEM \
"... etc. .......................................................\n"\
This setup should work if the demo connects to a network that has a DHCP service and Internet access. Note that the FreeRTOS Windows port only works with a wired Ethernet network adapter, which can be a virtual Ethernet adapter.
You should use a separate MQTT client, such as MQTT.fx, to test the MQTT connection from your host machine to the public MQTT broker.
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 an Eclipse IoT project. The
MQTT broker is not affiliated with or maintained by FreeRTOS and may be unavailable at any time. Further the server authentication used by this broker is based on 1024-bit RSA
, a cipher that is not recommended for production purposes. Do NOT
send any confidential information from your device to this MQTT broker.
Option 2: Using a locally hosted Mosquitto MQTT message broker (host machine)
The Mosquitto broker can also run locally, either on your host machine (the machine used to build the demo application), or another machine on your local network. To do this:
- Follow the instructions on https://mosquitto.org/download/ to download and install Mosquitto locally.
- Open “mosquitto.conf”, which is located in the Mosquitto install directory, and set the following configurations:
- per_listener_settings: true
- port: 8883
- allow_anonymous: false
- cafile: ./mosquitto/config/ca.crt
- certfile: ./mosquitto/config/server.crt
- keyfile: ./mosquitto/config/server.key
- tls_version: tlsv1.2
Note: The configurations “cafile”, “certfile”, and “keyfile” above refer to the locally-generated CA certificate, server certificate, and server key, respectively. These can be generated using OpenSSL. More information can be found on mosquitto.org.
Open your local copy of
Add the following lines to set democonfigMQTT_BROKER_ENDPOINT and democonfigMQTT_BROKER_PORT:
#define democonfigMQTT_BROKER_ENDPOINT "w.x.y.z"
#define democonfigMQTT_BROKER_PORT ( 8883 )
Note: Port number 8883 is the default port number for encrypted 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. The port number used by Mosquitto is set by the “port” parameter in “mosquitto.conf”, which is located in the Mosquitto install directory.
Option 3: An MQTT broker of your choosing:
Any MQTT broker that supports encrypted TCP/IP communication can be used with this demo. To do this:
- Open your local copy of
- Add the following lines with settings specific to your chosen broker:
Optionally, set the server’s root CA certificate (
- #define democonfigMQTT_BROKER_ENDPOINT “your-desired-endpoint”
- #define democonfigMQTT_BROKER_PORT ( 8883 )
#democonfigROOT_CA_PEM ) in
Building the Demo Project
The demo project is built in the same way as the basic MQTT demo (without TLS).
- Open the
FreeRTOS/FreeRTOS-Plus/Demo/coreMQTT_Windows_Simulator/MQTT_Basic_TLS/mqtt_basic_tls_demo.sln Visual Studio solution file from within the Visual Studio IDE.
- Select Build Solution from the IDE’s Build menu.
NOTE: If you are using Microsoft Visual Studio 2017 or earlier, then you must select a Platform Toolset compatible with your version: Project -> RTOSDemos Properties -> Platform Toolset
The demo provides the same functionality and structure as the basic MQTT demo (without TLS), but uses a transport interface that includes TLS in place of the plaintext transport interface.
Connecting to the MQTT Broker (with TLS)
prvConnectToServerWithBackoffRetries() attempts to make a TLS connection to the MQTT broker. If the connection fails, it retries after a timeout. The timeout value will exponentially increase and include jitter until the maximum number of attempts are reached or the maximum timeout value is reached. The function
RetryUtils_BackoffAndSleep() provides exponentially increasing timeout value and returns
RetryUtilsRetriesExhausted when the maximum number of attempts have been reached. The variance in the time between retries is used to ensure a fleet of IoT devices that happen to all get disconnected at the same time don’t all try to reconnect at exactly the same time.
static TlsTransportStatus_t prvConnectToServerWithBackoffRetries(
NetworkCredentials_t * pxNetworkCredentials,
NetworkContext_t * pxNetworkContext )
RetryUtilsStatus_t xRetryUtilsStatus = RetryUtilsSuccess;
pxNetworkCredentials->pRootCa = ( const unsigned char * ) democonfigROOT_CA_PEM;
pxNetworkCredentials->rootCaSize = sizeof( democonfigROOT_CA_PEM );
pxNetworkCredentials->disableSni = democonfigDISABLE_SNI;
RetryUtils_ParamsReset( &xReconnectParams );
xReconnectParams.maxRetryAttempts = MAX_RETRY_ATTEMPTS;
xNetworkStatus = TLS_FreeRTOS_Connect( pxNetworkContext,
if( xNetworkStatus != TLS_TRANSPORT_SUCCESS )
xRetryUtilsStatus = RetryUtils_BackoffAndSleep( &xReconnectParams );
if( xRetryUtilsStatus == RetryUtilsRetriesExhausted )
xNetworkStatus = TLS_TRANSPORT_CONNECT_FAILURE;
} while( ( xNetworkStatus != TLS_TRANSPORT_SUCCESS ) &&
( xRetryUtilsStatus == RetryUtilsSuccess ) );
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.