@@ -155,19 +155,7 @@ static int unpack_raw_data(uint32_t length, struct buf_ctx *buf,
155155 return 0 ;
156156}
157157
158- /**
159- * @brief Unpacks variable length integer from the buffer from the offset
160- * requested.
161- *
162- * @param[inout] buf A pointer to the buf_ctx structure containing current
163- * buffer position.
164- * @param[out] val Memory where the value is to be unpacked.
165- *
166- * @retval Number of bytes parsed if the procedure is successful.
167- * @retval -EINVAL if the length decoding would use more that 4 bytes.
168- * @retval -EAGAIN if the buffer would be exceeded during the read.
169- */
170- static int unpack_variable_int (struct buf_ctx * buf , uint32_t * val )
158+ int unpack_variable_int (struct buf_ctx * buf , uint32_t * val )
171159{
172160 uint8_t shift = 0U ;
173161 int bytes = 0 ;
@@ -435,6 +423,43 @@ int decode_user_property(struct property_decoder *prop,
435423 return 0 ;
436424}
437425
426+ int decode_sub_id_property (struct property_decoder * prop ,
427+ uint32_t * remaining_len ,
428+ struct buf_ctx * buf )
429+ {
430+ uint32_t * sub_id_array = prop -> data ;
431+ uint32_t * chosen = NULL ;
432+ uint32_t value ;
433+ int bytes ;
434+
435+ bytes = unpack_variable_int (buf , & value );
436+ if (bytes < 0 ) {
437+ return - EINVAL ;
438+ }
439+
440+ if (* remaining_len < bytes ) {
441+ return - EINVAL ;
442+ }
443+
444+ * remaining_len -= bytes ;
445+ * prop -> found = true;
446+
447+ for (int i = 0 ; i < CONFIG_MQTT_SUBSCRIPTION_ID_PROPERTIES_MAX ; i ++ ) {
448+ if (sub_id_array [i ] == 0 ) {
449+ chosen = & sub_id_array [i ];
450+ break ;
451+ }
452+ }
453+
454+ if (chosen == NULL ) {
455+ NET_DBG ("Cannot parse all subscription id properties, ignore excess" );
456+ } else {
457+ * chosen = value ;
458+ }
459+
460+ return 0 ;
461+ }
462+
438463static int properties_decode (struct property_decoder * prop , uint8_t cnt ,
439464 struct buf_ctx * buf )
440465{
@@ -479,12 +504,14 @@ static int properties_decode(struct property_decoder *prop, uint8_t cnt,
479504 switch (type ) {
480505 case MQTT_PROP_SESSION_EXPIRY_INTERVAL :
481506 case MQTT_PROP_MAXIMUM_PACKET_SIZE :
507+ case MQTT_PROP_MESSAGE_EXPIRY_INTERVAL :
482508 err = decode_uint32_property (current_prop ,
483509 & properties_len , buf );
484510 break ;
485511 case MQTT_PROP_RECEIVE_MAXIMUM :
486512 case MQTT_PROP_TOPIC_ALIAS_MAXIMUM :
487513 case MQTT_PROP_SERVER_KEEP_ALIVE :
514+ case MQTT_PROP_TOPIC_ALIAS :
488515 err = decode_uint16_property (current_prop ,
489516 & properties_len , buf );
490517 break ;
@@ -493,6 +520,7 @@ static int properties_decode(struct property_decoder *prop, uint8_t cnt,
493520 case MQTT_PROP_WILDCARD_SUBSCRIPTION_AVAILABLE :
494521 case MQTT_PROP_SUBSCRIPTION_IDENTIFIER_AVAILABLE :
495522 case MQTT_PROP_SHARED_SUBSCRIPTION_AVAILABLE :
523+ case MQTT_PROP_PAYLOAD_FORMAT_INDICATOR :
496524 err = decode_uint8_property (current_prop ,
497525 & properties_len , buf );
498526 break ;
@@ -501,6 +529,8 @@ static int properties_decode(struct property_decoder *prop, uint8_t cnt,
501529 case MQTT_PROP_RESPONSE_INFORMATION :
502530 case MQTT_PROP_SERVER_REFERENCE :
503531 case MQTT_PROP_AUTHENTICATION_METHOD :
532+ case MQTT_PROP_RESPONSE_TOPIC :
533+ case MQTT_PROP_CONTENT_TYPE :
504534 err = decode_string_property (current_prop ,
505535 & properties_len , buf );
506536 break ;
@@ -509,9 +539,14 @@ static int properties_decode(struct property_decoder *prop, uint8_t cnt,
509539 & properties_len , buf );
510540 break ;
511541 case MQTT_PROP_AUTHENTICATION_DATA :
542+ case MQTT_PROP_CORRELATION_DATA :
512543 err = decode_binary_property (current_prop ,
513544 & properties_len , buf );
514545 break ;
546+ case MQTT_PROP_SUBSCRIPTION_IDENTIFIER :
547+ err = decode_sub_id_property (current_prop ,
548+ & properties_len , buf );
549+ break ;
515550 default :
516551 err = - ENOTSUP ;
517552 }
@@ -665,7 +700,68 @@ int connect_ack_decode(const struct mqtt_client *client, struct buf_ctx *buf,
665700 return 0 ;
666701}
667702
668- int publish_decode (uint8_t flags , uint32_t var_length , struct buf_ctx * buf ,
703+ #if defined(CONFIG_MQTT_VERSION_5_0 )
704+ static int publish_properties_decode (struct buf_ctx * buf ,
705+ struct mqtt_publish_param * param )
706+ {
707+ struct property_decoder prop [] = {
708+ {
709+ & param -> prop .payload_format_indicator ,
710+ & param -> prop .rx .has_payload_format_indicator ,
711+ MQTT_PROP_PAYLOAD_FORMAT_INDICATOR
712+ },
713+ {
714+ & param -> prop .message_expiry_interval ,
715+ & param -> prop .rx .has_message_expiry_interval ,
716+ MQTT_PROP_MESSAGE_EXPIRY_INTERVAL
717+ },
718+ {
719+ & param -> prop .topic_alias ,
720+ & param -> prop .rx .has_topic_alias ,
721+ MQTT_PROP_TOPIC_ALIAS
722+ },
723+ {
724+ & param -> prop .response_topic ,
725+ & param -> prop .rx .has_response_topic ,
726+ MQTT_PROP_RESPONSE_TOPIC
727+ },
728+ {
729+ & param -> prop .correlation_data ,
730+ & param -> prop .rx .has_correlation_data ,
731+ MQTT_PROP_CORRELATION_DATA
732+ },
733+ {
734+ & param -> prop .user_prop ,
735+ & param -> prop .rx .has_user_prop ,
736+ MQTT_PROP_USER_PROPERTY
737+ },
738+ {
739+ & param -> prop .subscription_identifier ,
740+ & param -> prop .rx .has_subscription_identifier ,
741+ MQTT_PROP_SUBSCRIPTION_IDENTIFIER
742+ },
743+ {
744+ & param -> prop .content_type ,
745+ & param -> prop .rx .has_content_type ,
746+ MQTT_PROP_CONTENT_TYPE
747+ }
748+ };
749+
750+ return properties_decode (prop , ARRAY_SIZE (prop ), buf );
751+ }
752+ #else
753+ static int publish_properties_decode (struct buf_ctx * buf ,
754+ struct mqtt_publish_param * param )
755+ {
756+ ARG_UNUSED (param );
757+ ARG_UNUSED (buf );
758+
759+ return - ENOTSUP ;
760+ }
761+ #endif /* CONFIG_MQTT_VERSION_5_0 */
762+
763+ int publish_decode (const struct mqtt_client * client , uint8_t flags ,
764+ uint32_t var_length , struct buf_ctx * buf ,
669765 struct mqtt_publish_param * param )
670766{
671767 int err_code ;
@@ -691,6 +787,16 @@ int publish_decode(uint8_t flags, uint32_t var_length, struct buf_ctx *buf,
691787 var_header_length += sizeof (uint16_t );
692788 }
693789
790+ if (mqtt_is_version_5_0 (client )) {
791+ err_code = publish_properties_decode (buf , param );
792+ if (err_code < 0 ) {
793+ return err_code ;
794+ }
795+
796+ /* Add parsed properties length */
797+ var_header_length += err_code ;
798+ }
799+
694800 if (var_length < var_header_length ) {
695801 NET_ERR ("Corrupted PUBLISH message, header length (%u) larger "
696802 "than total length (%u)" , var_header_length ,
0 commit comments