Skip to content

Commit a3cdc17

Browse files
committed
[nrf fromtree] 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 <[email protected]> (cherry picked from commit e9da3b3)
1 parent 5f8ba7d commit a3cdc17

File tree

3 files changed

+81
-3
lines changed

3 files changed

+81
-3
lines changed

include/zephyr/net/mqtt.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,15 @@ struct mqtt_binstr {
242242
uint32_t len; /**< Length of binary stream. */
243243
};
244244

245+
/** @brief Abstracts aliased topic. */
246+
struct mqtt_topic_alias {
247+
/** UTF-8 encoded topic name. */
248+
uint8_t topic_buf[CONFIG_MQTT_TOPIC_ALIAS_STRING_MAX];
249+
250+
/** Topic name size. */
251+
uint16_t topic_size;
252+
};
253+
245254
/** @brief Abstracts MQTT UTF-8 encoded topic that can be subscribed
246255
* to or published.
247256
*/
@@ -866,6 +875,11 @@ struct mqtt_internal {
866875

867876
/** Internal. Remaining payload length to read. */
868877
uint32_t remaining_payload;
878+
879+
#if defined(CONFIG_MQTT_VERSION_5_0)
880+
/** Internal. MQTT 5.0 topic alias mapping. */
881+
struct mqtt_topic_alias topic_aliases[CONFIG_MQTT_TOPIC_ALIAS_MAX];
882+
#endif /* CONFIG_MQTT_VERSION_5_0 */
869883
};
870884

871885
/**

subsys/net/lib/mqtt/mqtt_decoder.c

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,56 @@ static int publish_properties_decode(struct buf_ctx *buf,
749749

750750
return properties_decode(prop, ARRAY_SIZE(prop), buf);
751751
}
752+
753+
static int publish_topic_alias_check(struct mqtt_client *client,
754+
struct mqtt_publish_param *param)
755+
{
756+
uint16_t alias = param->prop.topic_alias;
757+
struct mqtt_utf8 *topic_str = &param->message.topic.topic;
758+
struct mqtt_topic_alias *topic_alias;
759+
760+
/* Topic alias must not exceed configured CONFIG_MQTT_TOPIC_ALIAS_MAX */
761+
if (alias > CONFIG_MQTT_TOPIC_ALIAS_MAX) {
762+
return -EBADMSG;
763+
}
764+
765+
if (topic_str->size == 0) {
766+
/* In case there's no topic, topic alias must be set */
767+
if (alias == 0) {
768+
return -EBADMSG;
769+
}
770+
771+
/* Topic alias number corresponds to the aliases array index. */
772+
topic_alias = &client->internal.topic_aliases[alias - 1];
773+
774+
/* In case topic alias has not been configured yet, report an error. */
775+
if (topic_alias->topic_size == 0) {
776+
return -EBADMSG;
777+
}
778+
779+
topic_str->utf8 = topic_alias->topic_buf;
780+
topic_str->size = topic_alias->topic_size;
781+
782+
return 0;
783+
}
784+
785+
/* If topic is present and topic alias is set, configure the alias locally. */
786+
if (alias > 0) {
787+
topic_alias = &client->internal.topic_aliases[alias - 1];
788+
789+
if (topic_str->size > ARRAY_SIZE(topic_alias->topic_buf)) {
790+
NET_ERR("Topic too long (%d bytes) to store, increase "
791+
"CONFIG_MQTT_TOPIC_ALIAS_STRING_MAX",
792+
topic_str->size);
793+
return -EBADMSG;
794+
}
795+
796+
memcpy(topic_alias->topic_buf, topic_str->utf8, topic_str->size);
797+
topic_alias->topic_size = topic_str->size;
798+
}
799+
800+
return 0;
801+
}
752802
#else
753803
static int publish_properties_decode(struct buf_ctx *buf,
754804
struct mqtt_publish_param *param)
@@ -758,9 +808,18 @@ static int publish_properties_decode(struct buf_ctx *buf,
758808

759809
return -ENOTSUP;
760810
}
811+
812+
static int publish_topic_alias_check(struct mqtt_client *client,
813+
struct mqtt_publish_param *param)
814+
{
815+
ARG_UNUSED(client);
816+
ARG_UNUSED(param);
817+
818+
return -ENOTSUP;
819+
}
761820
#endif /* CONFIG_MQTT_VERSION_5_0 */
762821

763-
int publish_decode(const struct mqtt_client *client, uint8_t flags,
822+
int publish_decode(struct mqtt_client *client, uint8_t flags,
764823
uint32_t var_length, struct buf_ctx *buf,
765824
struct mqtt_publish_param *param)
766825
{
@@ -795,6 +854,11 @@ int publish_decode(const struct mqtt_client *client, uint8_t flags,
795854

796855
/* Add parsed properties length */
797856
var_header_length += err_code;
857+
858+
err_code = publish_topic_alias_check(client, param);
859+
if (err_code < 0) {
860+
return err_code;
861+
}
798862
}
799863

800864
if (var_length < var_header_length) {

subsys/net/lib/mqtt/mqtt_internal.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,7 @@ int connect_ack_decode(const struct mqtt_client *client, struct buf_ctx *buf,
387387

388388
/**@brief Decode MQTT Publish packet.
389389
*
390-
* @param[in] MQTT client for which packet is decoded.
390+
* @param[inout] MQTT client for which packet is decoded.
391391
* @param[in] flags Byte containing message type and flags.
392392
* @param[in] var_length Length of the variable part of the message.
393393
* @param[inout] buf A pointer to the buf_ctx structure containing current
@@ -396,7 +396,7 @@ int connect_ack_decode(const struct mqtt_client *client, struct buf_ctx *buf,
396396
*
397397
* @return 0 if the procedure is successful, an error code otherwise.
398398
*/
399-
int publish_decode(const struct mqtt_client *client, uint8_t flags,
399+
int publish_decode(struct mqtt_client *client, uint8_t flags,
400400
uint32_t var_length, struct buf_ctx *buf,
401401
struct mqtt_publish_param *param);
402402

0 commit comments

Comments
 (0)