MQTT library

The nRF Connect SDK contains the MQTT library which is an MQTT client library. Let’s go over how to enable and configure the library to connect to an MQTT broker.

The MQTT library is built on top of the sockets API, so the library handles creating the socket used to communicate with the MQTT broker.

There are a few general steps needed to use the library, which we will cover in detail in Exercise 1:

  1. Creating, initializing and configuring mqtt client, struct mqtt_client
  2. Connecting to the MQTT broker
  3. Creating the MQTT event handler and handling the different events. Based on QoS of message, different cases
  4. Publish to topics, struct mqtt_publish_param and mqtt_publish()
  5. Subscribe to topics, struct mqtt_topic, struct mqtt_subscription_list and mqtt_subscribe()
  6. Keeping the connection alive, mqtt_live()
  7. Adding TLS to secure the connection

Create an MQTT client

The first step is to initialize and configure the MQTT client, of type struct mqtt_client. This is the structure that maintains information relevant to the client, and is passed to all subsequent calls relevant to the client, like subscribing or publishing to topics.

static struct mqtt_client client_ctx

Before configuring the structure, we must initialize it with mqtt_client_init().

Then we can set parameters like the broker details, the callback function and client ID.

Define the callback function

Define the callback function of type mqtt_evt_cb_t, which takes the client struct mqtt_client and the event struct mqtt_evt as parameters.

struct mqtt_evt signature

mqtt_evt_type contains the full list of possible MQTT events. The two essential MQTT events which we will discuss now are MQTT_EVT_CONNACK and MQTT_EVT_PUBLISH.

MQTT_EVT_CONNACK: acknowledgment of connection request. The event result being 0 indicates a successful connection.

This event is important because once a successful connection as been established, the client can subscribe to the applicable topics.

MQTT_EVT_PUBLISH: message from broker, that a message has been published to a topic we subscribe to.

This event is important because we want to examine the published message in the application and depending on what message is published determine what to do next.

For all the other events, we will simply print the result of the event on the console.

Connect to the MQTT broker

To connect we will use the function mqtt_connect(), which takes the client as a parameter. This will create the appropriate socket, accessed in client_ctx.transport.tcp.sock and establish a TLS/TCP connection.

To receive incoming packets, we call mqtt_input(). Just like in Lesson 3 Exercise 2, we poll the socket for a POLLIN event to know when to call this function. Additionally, due to the keep-alive functionality of MQTT, we periodically call mqtt_live() to keep the connection alive.

Just like closing the socket, it is important to call mqtt_disconnect() to close the connection and deallocate the resources.

Publish and subscribe

To subscribe to topics, we define a struct mqtt_topic for each topic and set the name of the topic and the QoS. Then we define struct mqtt_subscription_list, essentially an array consiting of all the topics, and pass that to mqtt_subscribe() along with the client.

To publish to a topic, we define struct mqtt_publish_param and set the name of the topic to publish to, along with the QoS, message to publish and message ID. This structure also has two flag members, dup_flag to indicate a retransmission and retain_flag, if the message should be stored persistently. Then pass this to mqtt_publish() along with the client, to publish the message.

Using MQTT with TLS

To enable TLS support for the MQTT Library, we first enable the following Kconfig

Then we set the transport type of the client to be secure. This is done in the mqtt_transport transport field in struct mqtt_client, by setting transport.type to MQTT_TRANSPORT_SECURE.

Then define struct mqtt_sec_config and set the TLS configuration for the application. This includes the hostname for the MQTT broker, the security tags, and the preference for peer verification. Also note that when connecting over TLS, the socket handle is found at client_ctx.transport.tls.sock.

Lastly, before establishing an LTE connection, we need to write the certificate for the TLS connection to the modem, using modem_key_mgmt_write(), which uses the AT command %CMNG we used in Lesson 2.

Register an account
Already have an account? Log in
(All fields are required unless specified optional)

Forgot your password?
Enter your email address, and we will send a link to reset your password.