Commit Graph

113 Commits

Author SHA1 Message Date
Robert Lubos
35af68b840 net: mqtt: Allow to bind client to a specific interface
Add a new "if_name" pointer to the transport configuration structure,
allowing the application to bind MQTT client to a specific network
interface.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2025-06-11 16:18:31 -07:00
Robert Lubos
8935579d0a net: mqtt: Improve disconnect error notification for MQTT 5.0
As MQTT 5.0 allows to specify the disconnect reason in the Disconnect
packet, use this new feature to improve error notification to the
broker, according to the error guidelines in the MQTT 5.0 spec.
For most cases, a generic arbitrary mapping between errno values and
reason codes is used, however the parser can specify the disconnect
reason code manually to better handle certain corner cases (like invalid
topic alias used).

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2025-03-26 16:19:42 +01:00
Robert Lubos
e9da3b3e0c net: mqtt: Add support for MQTT 5.0 topic aliases
Add support for handling topic aliases received from the broker.
The MQTT client implementation will store received topic for further use
in case consecutive PUBLISH received from the broker contains no topic
but alias only.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2025-03-26 16:19:42 +01:00
Robert Lubos
1d743fa65a net: mqtt: Add support for MQTT 5.0 AUTH packet
Add support for a new AUTH message introduced in MQTT 5.0.
This is a new mechanism specified by MQTT 5.0, which allows clients and
brokers for enhanced authentication in between CONNECT and CONNACK
exchange. An additional MQTT event (MQTT_EVT_AUTH) was specified which
is triggered when the AUTH packet arrives from the broker.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2025-03-26 16:19:42 +01:00
Robert Lubos
55e1c10894 net: mqtt: Add MQTT 5.0 support for DISCONNECT
Add support for DICONNECT message specified in MQTT 5.0.
As with MQTT 5.0, the disconnect can now also be initiated by the
broker, it was needed to add decoder support for the message.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2025-03-26 16:19:42 +01:00
Robert Lubos
2459ffae41 net: mqtt: Add MQTT 5.0 support for SUBACK/UNSUBACK
Add support for SUBACK/UNSUBACK messaged specified in MQTT 5.0.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2025-03-26 16:19:42 +01:00
Robert Lubos
efd795b066 net: mqtt: Add MQTT 5.0 support for SUBSCRIBE/UNSUBSCRIBE
Add support for SUBSCRIBE/UNSUBSCRIBE messages specified in MQTT 5.0.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2025-03-26 16:19:42 +01:00
Robert Lubos
c21e64251b net: mqtt: Add MQTT 5.0 support for PUBLISH ACKs
Add support for PUBACK, PUBREC, PUBREL and PUBCOMP specified in MQTT
5.0. As all of these acknowledgment packets have similar format,
introduced a common encoder/decoder to handle ACK packets.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2025-03-26 16:19:42 +01:00
Robert Lubos
15ad90aceb net: mqtt: Add MQTT 5.0 support for PUBLISH
Add support for PUBLISH message specified in MQTT 5.0. The message
encoder and decoder were updated to support MQTT properties.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2025-03-26 16:19:42 +01:00
Robert Lubos
6038676b83 net: mqtt: Add MQTT 5.0 support for CONNACK
Add support for CONNACK message specified in MQTT 5.0, along with
property decoders required to decode MQTT properties. Decoded properties
are provided to the application within mqtt_connack_param structure,
accompanying the CONNACK event.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2025-03-26 16:19:42 +01:00
Robert Lubos
8fe2965500 net: mqtt: Add MQTT 5.0 support for CONNECT
Add support for CONNECT message specified in MQTT 5.0, along with
property encoders required to encode MQTT properties which is a new
concept in MQTT 5.0. Connect and will properties can be specified by the
application in the mqtt_client structure before connecting.

Introduce a helper function which allows to verify whether MQTT 5.0 is
used or not, so that it's still possible to use MQTT 3.1 even if MQTT
5.0 support is enabled in Kconfig.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2025-03-26 16:19:42 +01:00
Robert Lubos
1eb9a5c241 net: mqtt: Fix helper macro for encoded binary data length
The macro did not take into account the 2-byte binary data length
encoded before the actual binary data.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2025-03-26 16:19:42 +01:00
Robert Lubos
f31a45f57c net: mqtt: Add Kconfig to select maximum supported MQTT version
It should be possible to select maximum supported MQTT version, so that
for example MQTT 5.0 features can be compiled-out in case they're not
needed.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2025-03-26 16:19:42 +01:00
Andreas Huber
075d5d3009 net: mqtt: Fix missing close function
If POSIX_API is not configured the close function is not available.
Use zsock_close instead.

Signed-off-by: Andreas Huber <andreas.huber@ch.sauter-bc.com>
2024-10-31 09:22:44 -05:00
Pisit Sawangvonganan
6211de87c0 net: mqtt: improve decoder buffer handling
Improve buffer handling logic to use local variables extensively.

This change reduces the number of pointer dereferences, which leads
to more efficient runtime and helps reduce the code size.

Signed-off-by: Pisit Sawangvonganan <pisit@ndrsolution.com>
2024-07-31 13:08:28 +02:00
Pisit Sawangvonganan
45282a41c1 net: mqtt: improve encoder buffer handling
Improve buffer handling logic to use local variables extensively.

This change reduces the number of pointer dereferences, which leads
to more efficient runtime and helps reduce the code size.

Signed-off-by: Pisit Sawangvonganan <pisit@ndrsolution.com>
2024-07-31 13:08:28 +02:00
Robert Lubos
4625fa713f net: mqtt: Fix possible socket leak with websocket transport
In case underlying TCP/TLS connection is already down, the
websocket_disconnect() call is expected to fail, as it involves
communication. Therefore, mqtt_client_websocket_disconnect() should not
quit early in such cases, as it could lead to an underlying socket leak.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2024-07-05 12:29:33 +02:00
frei tycho
382670690c net: change controlling expressions in while to Boolean
Use `do { ... } while (false)` instead of `do { ... } while (0)`.

Signed-off-by: frei tycho <tfrei@baumer.com>
2024-06-11 20:03:16 +03:00
sukrit buddeewong
3ad8d32d18 net: mqtt: Implement ALPN Support for socket mqtt
Implement the ALPN Support for Mqtt Library allow mqtt to have
ability to utilize ALPN for connect to server that support ALPN, such
as AWS IoT Core

Signed-off-by: sukrit buddeewong <sukrit.omu@gmail.com>
2024-03-14 17:04:11 -05:00
Saravanan Sekar
bdb26cfe02 net: mqtt: close tcp socket after websocket_disconnect
websocket_disconnect api does not closes mqtt's tcp socket, so
tcp socket must be closed after done.

Signed-off-by: Saravanan Sekar <saravanan@linumiz.com>
2023-06-19 09:18:45 +01:00
Jun Qing Zou
aae379f245 net: mqtt: Debug logging of pointers
Cast pointer to `void *` for `%p` parameter.
Otherwise lots of warnings in the log like below:

 `<wrn> cbprintf_package: (unsigned) char * used for %p argument.
 It's recommended to cast it to void * because it may cause
 misbehavior in certain configurations. String:"%s: (%p): >>
 length:0x%08x cur:%p, end:%p" argument:3`

Signed-off-by: Jun Qing Zou <jun.qing.zou@nordicsemi.no>
2023-03-15 15:02:47 +01:00
Robert Lubos
4234e801b5 net: sockets: Fix TLS_HOSTNAME option length inconsistency
The TLS_HOSTNAME socket option expects a NULL terminated string and
doesn't really care about the optlen provided. However, as the option
expects that the string is NULL terminated, the optlen value should take
NULL character into account, for consistency across the codebase.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2023-01-27 19:23:36 +09:00
Grixa Yrev
2a992c65c0 net: websocket: new receiving algorithm
websocket_recv_msg() is reworked with using fsm. Now the function
return 0 when payload is empty, -ENOTCONN if socket close. Receiving
empty ping and sending empty pong were added in tests.
Fixes #52327

Signed-off-by: Grixa Yrev <grixayrev@yandex.ru>
2022-12-20 17:05:12 +00:00
Gerard Marull-Paretas
5113c1418d subsystems: migrate includes to <zephyr/...>
In order to bring consistency in-tree, migrate all subsystems code to
the new prefix <zephyr/...>. Note that the conversion has been scripted,
refer to zephyrproject-rtos#45388 for more details.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
2022-05-09 12:07:35 +02:00
Jordan Yates
04d29c4eb4 net: mqtt: remove custom logging macros
Remove the custom MQTT logging macros and just use the NET macros
directly. The custom macros provide no additional functionality and the
non-standard naming can cause confusion.

Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
2022-04-06 17:41:06 +02:00
Robert Lubos
5110629ac1 net: mqtt: Fix SOCKS5 setsockopt error handling
Transports should close the socket in case of `setsockopt()` failure,
otherwise we end up with a leaked socket, as it won't be closed
elsewhere.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2021-12-01 13:54:30 -06:00
Lucas Dietrich
0a0e9079c3 net: mqtt: Add support for TLS option TLS_CERT_NOCOPY
Add an option in MQTT client context to take advantage of the
"TLS_CERT_NOCOPY" option when using  TLS socket transport.

Signed-off-by: Lucas Dietrich <ld.adecy@gmail.com>
2021-11-25 10:44:17 -05:00
Caspar Friedrich
c3ca5ada1a net: mqtt: Return meaningful error code from mqtt_init()
The condition checks whether the connection was established or not. The
return value should reflect that.

Signed-off-by: Caspar Friedrich <c.s.w.friedrich@gmail.com>
2021-10-21 10:56:32 -04:00
Robert Lubos
f0ec61ef70 net: mqtt: Handle incomplete zsock_sendmsg write
In case zsock_sendmsg did not send all of the data requested, update the
`struct msghdr` content and retry.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2021-09-29 11:08:40 +02:00
Marcin Niestroj
02fa7be52d net: mqtt: check mqtt_abort() function parameters before locking
Function parameters can be checked without MQTT instance lock being
held. Additionally if NULL parameter would be passed (which this check
tries to handle), then function would return without releasing lock.

Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
2021-09-02 19:36:03 -04:00
Vlad Tuhut
7580623a36 net: mqtt: Add custom transport type
Add new custom transport type.
This allows user defined transport for MQTT communication.
The user must implement the transport procedure.

Fixes **#27015**

Signed-off-by: Vlad Tuhut <vlad.tuhut@raptor-technologies.ro>
2021-06-29 11:34:57 -04:00
Pete Skeggs
e0de4ff227 net: mqtt: log struct mqtt_utf8 with hexdump
Add NET_HEXDUMP_DBG/ERR/WARN/INFO macros, then use them for new
MQTT_HEXDUMP_TRC/ERR/WARN/INFO macros.

Log struct mqtt_utf8 using MQTT_HEXDUMP_TRC. One cannot safely log
mqtt_utf8 strings due to no guarantee of a NULL terminator being
present.  Also, logging without log_strdup() as if it were a NULL
terminated string asserts when CONFIG_LOG_IMMEDIATE=n. This solves
both issues.

Signed-off-by: Pete Skeggs <peter.skeggs@nordicsemi.no>
2021-03-05 12:49:22 +02:00
Simen S. Røstad
adb8087707 net: mqtt: Return -1 if keepalive messages are disabled.
In mqtt_keepalive_time_left(), return -1 if keep alive messages are
disabled by setting CONFIG_MQTT_KEEPALIVE=0.

This allows to use mqtt_keepalive_time_left() directly as an input
for poll(). If no keep-alive is expected, -1 would indicate
that poll() can block until new data is available on the socket.

Signed-off-by: Simen S. Røstad <simen.rostad@nordicsemi.no>
2020-12-08 14:08:36 -05:00
Jan Pohanka
fff28ad8ae net: mqtt: use zsock_ functions
Using zephyr's internals zsock_ calls make mqtt library more compatible,
now it does not depend on NET_SOCKETS_POSIX_NAMES.

Signed-off-by: Jan Pohanka <xhpohanka@gmail.com>
2020-10-01 17:35:45 +03:00
Marcin Niestroj
9a791dd6bb net: mqtt: Reset client state before notifying MQTT_EVT_DISCONNECT
MQTT client state is protected using mutex. That mutex however is
temporarily unlocked when calling event callbacks. This means that in
client_disconnect() transport can already be disconnected, but without
marking it as such in client->internal.state.

When mutex is unlocked in event_notify() function, then there are two
possible paths of failure:

1) First possibility is when RX and TX are called from two separate
   threads, so that the other thread gets resumed and functions like
   verify_tx_state() (e.g. in mqtt_publish()) allow to continue
   communication over disconnected medium.
2) Another possibility is that user calls mqtt_abort() or
   mqtt_disconnect() in event handler.

In both cases MQTT library tries to send or receive data, possibly
followed by second close() of underlying file descriptor.

Prevent using disconnected transport by clearing MQTT client state right
after calling mqtt_transport_disconnect(), without releasing mutex, even
for a while.

Signed-off-by: Marcin Niestroj <m.niestroj@grinn-global.com>
2020-09-30 14:30:43 +03:00
Robert Lubos
aec5f0a3ef net: mqtt: Prevent double CONNACK event notification on server reject
Currently, the application could receive a duplicate CONNACK event, in
case the server rejected the connection at MQTT level (with an error
code provided with CONNACK message). A subsequent connection close (with
`mqtt_abort` for instance) would produce the duplicate event.

Fix this by reporting back to the MQTT engine, that the connection was
refused, so it can close the connection rightaway. Rework the event
notification logic, so that DISCONNECT event instead of a duplicate
CONNACK event is notified in that case.

Also, prevent the MQTT engine from notyfing DISCONNECT event in case of
socket errors during initial connection phase (i. e. before
`mqtt_connect` function finished).

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2020-07-27 13:24:11 +02:00
Xavier Naveira
0fd16f8b78 net: mqtt: Make client "cleansession" flag configurable.
Cleansession is hardcoded to 1 but some use case might require 0
to make the sessions persistent (ie get messages sent while the
client was offline)

Signed-off-by: Xavier Naveira <xnaveira@gmail.com>
2020-06-09 10:09:04 +03:00
Kumar Gala
a1b77fd589 zephyr: replace zephyr integer types with C99 types
git grep -l 'u\(8\|16\|32\|64\)_t' | \
		xargs sed -i "s/u\(8\|16\|32\|64\)_t/uint\1_t/g"
	git grep -l 's\(8\|16\|32\|64\)_t' | \
		xargs sed -i "s/s\(8\|16\|32\|64\)_t/int\1_t/g"

Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
2020-06-08 08:23:57 -05:00
Jukka Rissanen
65a1bebe85 net: Replace NET_WAIT_FOREVER by SYS_FOREVER_MS
As we now have SYS_FOREVER_MS, use that instead of network
specific NET_WAIT_FOREVER.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-05-05 16:29:23 +03:00
Robert Lubos
073ec8d4aa net: mqtt: Refactor because of timeout overhaul
Align MQTT with timeout API changes.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2020-04-09 21:58:42 +03:00
Jukka Rissanen
1ecac129c8 net: mqtt: websocket: Only accept data packets in RX
Check the message type and only accept MQTT binary data.

Fixes #24156

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
2020-04-09 16:16:57 +03:00
Robert Lubos
b173c177db net: mqtt: Improve PUBLISH message length validation
Identify when received PUBLISH message is malformed and overall packet
length received is smaller than parsed variable header lenght.
Add unit test to cover this case.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2020-03-28 09:36:12 +02:00
Robert Lubos
6110a7cb63 net: mqtt: Improve buffer bounds validation in mqtt_read_message_chunk
Verify more strictly that data read from the transport fits into RX
buffer. Switch to unsigned integers, where possible, to prevent
unnecessary signed/unsigned operations.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2020-03-28 09:36:12 +02:00
Robert Lubos
1ad165a62d net: mqtt: Fix packet length decryption
The standard allows up to 4 bytes of packet length data, while current
implementation parsed up to 5 bytes.

Add additional unit test, which verifies that error is reported in case
of invalid packet length.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2020-03-28 09:36:12 +02:00
Marcin Niestroj
c0b50c72be net: mqtt: use MQTT_UTF8_LITERAL() to simplify code and fix debug log
Contents of mqtt_3_1_0_proto_desc and mqtt_3_1_1_proto_desc were logged
with following code:

  MQTT_TRC("Encoding Protocol Description. Str:%s Size:%08x.",
           mqtt_proto_desc->utf8, mqtt_proto_desc->size);

This resulted in invalid log, since they were not NULL-terminated
strings. Use MQTT_UTF8_LITERAL() to initialize both utf8 strings to make
sure they are NULL-terminated now and valid to print and
log. Additionally this makes the code a bit shorter.

Signed-off-by: Marcin Niestroj <m.niestroj@grinn-global.com>
2020-03-13 10:06:18 +02:00
PK Chan
9f9e00a62d net: mqtt: Added event for MQTT ping response.
There are scenarios where there is a NAT firewall in between MQTT
client and server. In such case, the NAT TCP timeout may be shorter
than MQTT keepalive timeout and TCP timeout. The the MQTT ping
request message is dropped by the NAT firewall, so that it cannot be
received by the server, resulting in void MQTT ping response message.
There is no TCP FIN or RST at all. The application looks hang-up
until TCP timeout happens on the client side, which may take too
long.

Therefore, the event MQTT_EVT_PINGRESP is added to inform the
application that the route between client and server is still valid.

Signed-off-by: PK Chan <pak.kee.chan@nordicsemi.no>
2020-03-12 11:07:14 +02:00
Robert Lubos
0c8d81c46f net: mqtt: Add write message handler
Add new transport handler for MQTT, with sendmsg-like functionality.
This allows TCP transport to send PUBLISH packets w/o fragmentation at
the TCP layer. Implement this new functionality for all existing
transports.

Fixes #22679

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2020-03-10 14:10:18 +02:00
Robert Lubos
5b58273a34 net: mqtt: Fix incorrect error code use in log
`mqtt_transport_write` failue was logged with `errno` value which is not
correct as the return value from the function is valid in this case.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2020-03-10 14:10:18 +02:00
Michael Scott
bab2f80fa7 net: mqtt: mqtt_live should only return success when ping sent
Users of mqtt_live() have no idea when it actually sends a ping.
As a result it's very hard to know when to use mqtt_input() to
process the incoming PINGACK.

Instead of returning a 0 result when a ping isn't generated in
mqtt_live(), let's return -EAGAIN.

Signed-off-by: Michael Scott <mike@foundries.io>
2020-01-28 15:45:08 -05:00
Robert Lubos
7557e57572 net: mqtt: Make mqtt_live return the mqtt_ping result
The MQTT connection is closed in case an mqtt_ping fails anyway, so
it's better to let the application know early that something went
wrong.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2020-01-24 21:30:55 -05:00