We will be using the MQTT helper library in the nRF Connect SDK to connect over MQTT. This library sits on top of the Zephyr MQTT API, and simplifies connecting over MQTT and takes care of the socket handling.
If you want to learn how to use the Zephyr MQTT API directly, MQTT library in Lesson 4 of the Cellular IoT Fundamentals course covers this topic.
In this topic, we will cover how to enable and configure the library to connect to an MQTT broker.
There are a few general steps needed to use the library, which we will cover in detail in the exercise section of this lesson.
- Enabling the MQTT helper library
- Defining callback functions for various MQTT events, e.g
on_mqtt_connackandon_mqtt_publish - Initializing the library with the callback functions using
mqtt_helper_init() - Connecting to the MQTT broker with
mqtt_helper_connect() - Publish to topics using
struct mqtt_publish_paramandmqtt_helper_publish() - Subscribe to topics using
struct mqtt_topic,struct mqtt_subscription_listandmqtt_helper_subscribe() - Adding TLS to secure the connection
Enabling the library
First step is to enable the library in the application, using the Kconfig CONFIG_MQTT_HELPER. This Kconfig also selects CONFIG_MQTT_LIB which is the Kconfig that enables the Zephyr MQTT API.
CONFIG_MQTT_HELPER=yKconfigThen, we need to include the header file for the library in the main.c file, like this.
#include <net/mqtt_helper.h>CDefine callback functions
Before initializing the library, we first need to define callback functions that will be called upon receiving various MQTT control packets from the broker.
The various callback functions are defined in struct mqtt_helper_cfg, which has the following signature

struct mqtt_helper_cfg signatureIn the exercises in this lesson, we will define functions for on_connack, on_suback, on_publish and on_disconnect. These callbacks have the following signatures
static void on_mqtt_connack(enum mqtt_conn_return_code return_code, bool session_present);
static void on_mqtt_suback(uint16_t message_id, int result);
static void on_mqtt_publish(struct mqtt_helper_buf topic, struct mqtt_helper_buf payload)
static void on_mqtt_disconnect(int result)CNotice that CONNACK, SUBACK, and DISCONNECT all contain a result or return_code that contains the result of the operation, or reason for the operation in the case of DISCONNECT packets from the broker.
Initializing the library
To initialize the library, we will use the API call mqtt_helper_init(), which takes the parameter of type struct mqtt_helper_cfg with all the callback functions as an input.

mqtt_helper_init() signature
struct mqtt_helper_cfg signatureTo initialize the library, we first define a variable struct mqtt_helper_cfg with the callback functions that we have defined. Then pass it to mqtt_helper_init().
struct mqtt_helper_cfg config = {
.cb = {
.on_connack = on_mqtt_connack,
.on_disconnect = on_mqtt_disconnect,
.on_publish = on_mqtt_publish,
.on_suback = on_mqtt_suback,
},
};
err = mqtt_helper_init(&config);
if (err) {
LOG_ERR("Failed to initialize MQTT helper, error: %d", err);
return 0;
}CConnect to the MQTT broker
To connect we will use the function mqtt_connect(), which takes the struct mqtt_helper_conn_params as a parameter.

mqtt_helper_connect() signature
struct mqtt_helper_conn_params signatureFirst we define the struct mqtt_helper_conn_params and set the relevant members, in our case hostname and device_id. The MQTT protocol provides the option of a username and password to authenticate with the broker, however this is outside the scope of this lesson.
struct mqtt_helper_conn_params conn_params = {
.hostname.ptr = "mqtt.nordicsemi.academy",
.hostname.size = strlen("mqtt.nordicsemi.academy"),
.device_id.ptr = "nrf7002dk-1234",
.device_id.size = strlen("nrf7002dk-1234"),
};
err = mqtt_helper_connect(&conn_params);
if (err) {
LOG_ERR("Failed to connect to MQTT, error code: %d", err);
return 0;
}CPublish 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, which is an array consisting of all the topics, and pass that to mqtt_helper_subscribe() to request subscription from the broker.

struct mqtt_topic
struct mqtt_subscription_listTo publish to a topic, we define struct mqtt_publish_param, where we can set the message to publish, the topic to publish the message to and the QoS through struct mqtt_publish_message. To set the message ID, the MQTT helper library has mqtt_helper_msg_id_get() which simply returns a positive non-zero value that increments for each call.
This structure also has two flag members, dup_flag to indicate a retransmission and retain_flag, if the message should be stored persistently.

struct mqtt_publish_param
struct mqtt_publish_messageWhen struct mqtt_publish_param is defined, pass it to mqtt_helper_publish() to publish the message.
Enabling TLS
To enable connection over TLS, we first enable the following Kconfig
CONFIG_MQTT_LIB_TLS=y
CONFIG_TLS_CREDENTIALS=y
CONFIG_NET_SOCKETS_SOCKOPT_TLS=yKconfig-
CONFIG_MQTT_LIB_TLSenables TLS support in the Zephyr MQTT API CONFIG_TLS_CREDENTIALSenables TLS credentials management systemCONFIG_NET_SOCKETS_SOCKOPT_TLSenables TLS socket option support which automatically establishes a TLS connection to the remote host
This will also configure the MQTT helper library to use MQTT broker port 8883, which is default for TLS connection.
In addition, we need to set a couple TLS related Kconfigs in the MQTT helper library
CONFIG_MQTT_HELPER_SEC_TAG=24
CONFIG_MQTT_HELPER_CERTIFICATES_FOLDER="src/credentials"KconfigCONFIG_MQTT_HELPER_SEC_TAG sets the security tag where the TLS credentials are storedCONFIG_MQTT_HELPER_CERTIFICATES_FOLDER sets the default path for the folder where the credentials are stored (relative to the application directory).
By default, the MQTT helper library expects the credentials to be in PEM format.