Skip to content

Commit d942c1d

Browse files
rlubosnashif
authored andcommitted
doc: Add MQTT high-level description
Add high-level documentation for MQTT library. Signed-off-by: Robert Lubos <[email protected]>
1 parent 2e68bc0 commit d942c1d

File tree

2 files changed

+158
-1
lines changed

2 files changed

+158
-1
lines changed

doc/reference/networking/mqtt.rst

Lines changed: 156 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,166 @@
11
.. _mqtt_socket_interface:
22

33
MQTT
4-
#####
4+
####
55

66
Overview
77
********
88

9+
MQTT (Message Queuing Telemetry Transport) is an application layer protocol
10+
which works on top of the TCP/IP stack. It is a lightweight
11+
publish/subscribe messaging transport for machine-to-machine communication.
12+
For more information about the protocol itself, see http://mqtt.org/.
13+
14+
Zephyr provides an MQTT client library built on top of BSD sockets API. The
15+
library is configurable at a per-client basis, with support for MQTT versions
16+
3.1.0 and 3.1.1. The Zephyr MQTT implementation can be used with either plain
17+
sockets communicating over TCP, or with secure sockets communicating over
18+
TLS. See :ref:`bsd_sockets_interface` for more information about Zephyr sockets.
19+
20+
MQTT clients require an MQTT server to connect to. Such a server, called an MQTT Broker,
21+
is responsible for managing client subscriptions and distributing messages
22+
published by clients. There are many implementations of MQTT brokers, one of them
23+
being Eclipse Mosquitto. See https://mosquitto.org/ for more information about
24+
the Eclipse Mosquitto project.
25+
26+
Sample usage
27+
************
28+
29+
To create an MQTT client, a client context structure and buffers need to be
30+
defined:
31+
32+
.. code-block:: c
33+
34+
/* Buffers for MQTT client. */
35+
static u8_t rx_buffer[256];
36+
static u8_t tx_buffer[256];
37+
38+
/* MQTT client context */
39+
static struct mqtt_client client_ctx;
40+
41+
Multiple MQTT client instances can be created in the application and managed
42+
independently. Additionally, a structure for MQTT Broker address information
43+
is needed. This structure must be accessible throughout the lifespan
44+
of the MQTT client and can be shared among MQTT clients:
45+
46+
.. code-block:: c
47+
48+
/* MQTT Broker address information. */
49+
static struct sockaddr_storage broker;
50+
51+
An MQTT client library will notify MQTT events to the application through a
52+
callback function created to handle respective events:
53+
54+
.. code-block:: c
55+
56+
void mqtt_evt_handler(struct mqtt_client *client,
57+
const struct mqtt_evt *evt)
58+
{
59+
switch (evt->type) {
60+
/* Handle events here. */
61+
}
62+
}
63+
64+
For a list of possible events, see :ref:`mqtt_api_reference`.
65+
66+
The client context structure needs to be initialized and set up before it can be
67+
used. An example configuration for TCP transport is shown below:
68+
69+
.. code-block:: c
70+
71+
mqtt_client_init(&client_ctx);
72+
73+
/* MQTT client configuration */
74+
client_ctx.broker = &broker;
75+
client_ctx.evt_cb = mqtt_evt_handler;
76+
client_ctx.client_id.utf8 = (u8_t *)"zephyr_mqtt_client";
77+
client_ctx.client_id.size = sizeof("zephyr_mqtt_client") - 1;
78+
client_ctx.password = NULL;
79+
client_ctx.user_name = NULL;
80+
client_ctx.protocol_version = MQTT_VERSION_3_1_1;
81+
client_ctx.transport.type = MQTT_TRANSPORT_NON_SECURE;
82+
83+
/* MQTT buffers configuration */
84+
client_ctx.rx_buf = rx_buffer;
85+
client_ctx.rx_buf_size = sizeof(rx_buffer);
86+
client_ctx.tx_buf = tx_buffer;
87+
client_ctx.tx_buf_size = sizeof(tx_buffer);
88+
89+
After the configuration is set up, the MQTT client can connect to the MQTT broker.
90+
Call the ``mqtt_connect`` function, which will create the appropriate socket,
91+
establish a TCP/TLS connection, and send an `MQTT CONNECT` message.
92+
When notified, the application should call the ``mqtt_input`` function to process
93+
the response received. Note, that ``mqtt_input`` is a non-blocking function,
94+
therefore the application should use socket ``poll`` to wait for the response.
95+
If the connection was successful, ``MQTT_EVT_CONNACK`` will be notified to the
96+
application through the callback function.
97+
98+
.. code-block:: c
99+
100+
rc = mqtt_connect(&client_ctx);
101+
if (rc != 0) {
102+
return rc;
103+
}
104+
105+
fds[0].fd = client_ctx.transport.tcp.sock;
106+
fds[0].events = ZSOCK_POLLIN;
107+
poll(fds, 1, K_MSEC(5000));
108+
109+
mqtt_input(&client_ctx);
110+
111+
if (!connected) {
112+
mqtt_abort(&client_ctx);
113+
}
114+
115+
In the above code snippet, the MQTT callback function should set the ``connected``
116+
flag upon a successful connection. If the connection fails at the MQTT level
117+
or a timeout occurs, the connection will be aborted, and the underlying socket
118+
closed.
119+
120+
After the connection is established, an application needs to call ``mqtt_input``
121+
and ``mqtt_live`` functions periodically to process incoming data and upkeep
122+
the connection. If an MQTT message is received, an MQTT callback function will
123+
be called and an appropriate event notified.
124+
125+
The connection can be closed by calling the ``mqtt_disconnect`` function.
126+
127+
Zephyr provides sample code utilizing the MQTT client API. See
128+
:ref:`mqtt-publisher-sample` for more information.
129+
130+
Using MQTT with TLS
131+
*******************
132+
133+
The Zephyr MQTT library can be used with TLS transport for secure communication
134+
by selecting a secure transport type (``MQTT_TRANSPORT_SECURE``) and some
135+
additional configuration information:
136+
137+
.. code-block:: c
138+
139+
client_ctx.transport.type = MQTT_TRANSPORT_SECURE;
140+
141+
struct mqtt_sec_config *tls_config = &client_ctx.transport.tls.config;
142+
143+
tls_config->peer_verify = 2;
144+
tls_config->cipher_list = NULL;
145+
tls_config->sec_tag_list = m_sec_tags;
146+
tls_config->sec_tag_count = ARRAY_SIZE(m_sec_tags);
147+
tls_config->hostname = MQTT_BROKER_HOSTNAME;
148+
149+
In this sample code, the ``m_sec_tags`` array holds a list of tags, referencing TLS
150+
credentials that the MQTT library should use for authentication. We do not specify
151+
``cipher_list``, to allow the use of all cipher suites available in the system.
152+
We set ``hostname`` field to broker hostname, which is required for server
153+
authentication. Finally, we enforce peer certificate verification by setting
154+
the ``peer_verify`` field.
155+
156+
Note, that TLS credentials referenced by the ``m_sec_tags`` array must be
157+
registered in the system first. For more information on how to do that, refer
158+
to :ref:`secure sockets documentation <secure_sockets_interface>`.
159+
160+
An example of how to use TLS with MQTT is also present in
161+
:ref:`mqtt-publisher-sample`.
162+
163+
.. _mqtt_api_reference:
9164

10165
API Reference
11166
*************

doc/reference/networking/sockets.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ For example, a call ``recv(sock, 1000, 0)`` may return 100,
6666
meaning that only 100 bytes were read (short read), and the application
6767
needs to retry call(s) to read the remaining 900 bytes.
6868

69+
.. _secure_sockets_interface:
70+
6971
Secure Sockets
7072
**************
7173

0 commit comments

Comments
 (0)