Skip to content

samples: net: mqtt_publisher: Enable MQTT 5.0 support #89040

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions samples/net/mqtt_publisher/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@ Overview
publish/subscribe messaging protocol optimized for small sensors and
mobile devices.

The Zephyr MQTT Publisher sample application is a MQTT v3.1.1
client that sends MQTT PUBLISH messages to a MQTT broker.
See the `MQTT V3.1.1 spec`_ for more information.
The Zephyr MQTT Publisher sample application is a MQTT client that sends
MQTT PUBLISH messages to a MQTT broker. The sample supports MQTT client in
version v3.1.1 (default) and v5.0.

.. _MQTT V3.1.1 spec: http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html
See the `MQTT v3.1.1 spec`_ and `MQTT v5.0 spec`_ for more information about
MQTT v3.1.1 and v5.0, respectively.

.. _MQTT v3.1.1 spec: https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html
.. _MQTT v5.0 spec: https://docs.oasis-open.org/mqtt/mqtt/v5.0/mqtt-v5.0.html

The source code of this sample application can be found at:
:zephyr_file:`samples/net/mqtt_publisher`.
Expand Down Expand Up @@ -136,6 +140,23 @@ Open another terminal window and type:

$ mosquitto_sub -t sensors

MQTT v5.0 support
=================

The sample can be configured to use MQTT v5.0 instead of MQTT v3.1.1. To enable
MQTT v5.0 in the sample, build it with ``-DEXTRA_CONF_FILE=overlay-mqtt-5.conf``
parameter. The sample should work with any broker supporting MQTT v5.0, however
it was specifically tested with mosquitto version 2.0.21. Server side
configuration in this particular case is the same as for MQTT v3.1.1.

When the sample is configured in the MQTT v5.0 mode, it makes use of the topic
aliasing feature. i.e. if the broker reports it supports topic aliases, the
client will register a topic alias for the default ``sensors`` topic, and use it
for consecutive MQTT Publish messages. It can be observed (for example using
Wireshark) how the actual topic is only present in the first Publish message, and
all subsequent Publish messages are smaller, as they include topic alias
property only.

Connecting securely using TLS
=============================

Expand Down
1 change: 1 addition & 0 deletions samples/net/mqtt_publisher/overlay-mqtt-5.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CONFIG_MQTT_VERSION_5_0=y
47 changes: 42 additions & 5 deletions samples/net/mqtt_publisher/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,14 @@ static APP_BMEM struct sockaddr socks5_proxy;

static APP_BMEM struct pollfd fds[1];
static APP_BMEM int nfds;

static APP_BMEM bool connected;

/* Whether to include full topic in the publish message, or alias only (MQTT 5). */
static APP_BMEM bool include_topic;
static APP_BMEM bool aliases_enabled;

#define APP_TOPIC_ALIAS 1

#if defined(CONFIG_MQTT_LIB_TLS)

#include "test_certs.h"
Expand Down Expand Up @@ -155,6 +160,18 @@ void mqtt_evt_handler(struct mqtt_client *const client,
connected = true;
LOG_INF("MQTT client connected!");

#if defined(CONFIG_MQTT_VERSION_5_0)
if (evt->param.connack.prop.rx.has_topic_alias_maximum &&
evt->param.connack.prop.topic_alias_maximum > 0) {
LOG_INF("Topic aliases allowed by the broker, max %u.",
evt->param.connack.prop.topic_alias_maximum);

aliases_enabled = true;
} else {
LOG_INF("Topic aliases disallowed by the broker.");
}
#endif

break;

case MQTT_EVT_DISCONNECT:
Expand Down Expand Up @@ -242,19 +259,32 @@ static char *get_mqtt_topic(void)

static int publish(struct mqtt_client *client, enum mqtt_qos qos)
{
struct mqtt_publish_param param;
struct mqtt_publish_param param = { 0 };

/* Always true for MQTT 3.1.1.
* True only on first publish message for MQTT 5.0 if broker allows aliases.
*/
if (include_topic) {
param.message.topic.topic.utf8 = (uint8_t *)get_mqtt_topic();
param.message.topic.topic.size =
strlen(param.message.topic.topic.utf8);
}

param.message.topic.qos = qos;
param.message.topic.topic.utf8 = (uint8_t *)get_mqtt_topic();
param.message.topic.topic.size =
strlen(param.message.topic.topic.utf8);
param.message.payload.data = get_mqtt_payload(qos);
param.message.payload.len =
strlen(param.message.payload.data);
param.message_id = sys_rand16_get();
param.dup_flag = 0U;
param.retain_flag = 0U;

#if defined(CONFIG_MQTT_VERSION_5_0)
if (aliases_enabled) {
param.prop.topic_alias = APP_TOPIC_ALIAS;
include_topic = false;
}
#endif

return mqtt_publish(client, &param);
}

Expand Down Expand Up @@ -308,7 +338,11 @@ static void client_init(struct mqtt_client *client)
client->client_id.size = strlen(MQTT_CLIENTID);
client->password = NULL;
client->user_name = NULL;
#if defined(CONFIG_MQTT_VERSION_5_0)
client->protocol_version = MQTT_VERSION_5_0;
#else
client->protocol_version = MQTT_VERSION_3_1_1;
#endif

/* MQTT buffers configuration */
client->rx_buf = rx_buffer;
Expand Down Expand Up @@ -435,6 +469,9 @@ static int publisher(void)
{
int i, rc, r = 0;

include_topic = true;
aliases_enabled = false;

LOG_INF("attempting to connect: ");
rc = try_to_connect(&client_ctx);
PRINT_RESULT("try_to_connect", rc);
Expand Down