Skip to content
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

Adding MQTTv5 Properties (Publish) #2613

Merged
merged 5 commits into from
Jul 27, 2023

Conversation

RLeclair
Copy link
Member

@RLeclair RLeclair commented Jul 21, 2023

  • Adding MQTTv5 properties on publish. Current implementation works with Mosquitto.
  • Renamed structs, functions, and variables to mqtt5.
  • Added unit tests testing all relevant properties, tested against local broker.
  • Excludes pre-existing files with low coverage.

Copy link
Member

@CIPop CIPop left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've left a few comments regarding code organization and public APIs.

sdk/inc/azure/core/az_mqtt5.h Outdated Show resolved Hide resolved
sdk/inc/azure/core/az_mqtt5.h Show resolved Hide resolved
sdk/inc/azure/core/az_mqtt5.h Outdated Show resolved Hide resolved
sdk/inc/azure/core/az_mqtt5.h Outdated Show resolved Hide resolved
sdk/inc/azure/core/az_mqtt5.h Outdated Show resolved Hide resolved
sdk/inc/azure/core/az_mqtt5.h Outdated Show resolved Hide resolved
sdk/inc/azure/core/az_mqtt5.h Outdated Show resolved Hide resolved
* and they are subject to change in future versions of the SDK which would break your code.
*/

#ifndef _az_MQTT5_H
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General about functions in this file: API documentation should describe both:

  1. usage of the API (within our SDK).
  2. instructions for developers that want to port the interface to another platform.

sdk/inc/azure/platform/az_mqtt5_mosquitto.h Outdated Show resolved Hide resolved
sdk/src/azure/core/CMakeLists.txt Show resolved Hide resolved
*
* @return The string value of the property.
*/
AZ_NODISCARD AZ_INLINE az_span az_mqtt5_property_string_get(az_mqtt5_property_string* prop_str)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we've got a getter for this, should str be internal?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The type az_mqtt5_property_string should be different for different MQTT implementations.

E.g. for ESP-MQTT it won't need two az_spans: instead, it will call into esp_mqtt5_client_get_user_property (example).

The struct in that case would need to hold on to the key/value pointers in order to allow freeing them later.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed struct declaration for all az_mqtt5_property_*. They are now declared inside az_mqtt5_[platform implementation]. Removed inline attribute of the getter functions and they are also now declared in az_mqtt5_[platform implementation].

sdk/inc/azure/core/az_mqtt5.h Show resolved Hide resolved
sdk/inc/azure/core/az_mqtt5.h Outdated Show resolved Hide resolved
* @brief The string value of the property.
*/
az_span str;
} az_mqtt5_property_string;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does this need to be a custom type instead of just an az_span (similar to the byte and int properties that don't have a special type)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is because we want the properties to be strongly typed, it will help distinguish between az_mqtt5_property_string and az_mqtt5_property_binarydata which are both az_spans but not the same from a MQTT perspective.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's actually because in some MQTT implementations these need to be freed and the primitive types do not.
In some cases freeing is done by libc/free(void*) but in many cases it is not somemqttstack_destroy(somemqttstack_string_type).

sdk/inc/azure/core/az_mqtt5_connection.h Outdated Show resolved Hide resolved
sdk/src/azure/platform/az_mosquitto5.c Show resolved Hide resolved
{
(void)mqtt5;
property_bag->_internal.options
= options == NULL ? az_mqtt5_property_bag_options_default() : *options;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we even allow setting options for mosquitto if we aren't going to do anything with them?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're keeping the pattern of initializing with options which involves setting, though for a mosquitto specific case it would make sense to just allow options to be NULL. @CIPop thoughts? The above line is now:
property_bag->properties = options == NULL ? NULL : options->properties;

sdk/src/azure/platform/az_mosquitto5.c Show resolved Hide resolved
sdk/tests/platform/test_az_mqtt5_policy.c Show resolved Hide resolved
cmocka_unit_test(test_az_mqtt5_policy_init_valid_success),
cmocka_unit_test(test_az_mqtt5_policy_outbound_connect_success),
cmocka_unit_test(test_az_mqtt5_policy_outbound_sub_success),
cmocka_unit_test(test_az_mqtt5_policy_outbound_pub_properties_success),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need a test without properties too?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added test w/o properties!

@RLeclair
Copy link
Member Author

Will address rest of comments in a follow-up PR. Merging to unblock other work.

@RLeclair RLeclair merged commit 5336993 into Azure:feature/v2 Jul 27, 2023
21 checks passed
@RLeclair RLeclair deleted the raulleclair/mqtt-v5 branch July 27, 2023 00:55
@@ -369,6 +379,17 @@ AZ_NODISCARD az_mqtt5_property_bag_options az_mqtt5_property_bag_options_default
};
}

AZ_NODISCARD az_result az_mqtt5_property_bag_empty(az_mqtt5_property_bag* property_bag)
{
_az_PRECONDITION_NOT_NULL(property_bag);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to fail if the property bag is null, or just not free?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is checking that the pointer to the property_bag struct is not null, in the case of mosquitto if we see that the internal pointer is null we know that it has already been freed and we should not do anything

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using _az_PRECONDITION_NOT_NULL will by default cause the entire program to hang instead of just skipping the free though.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We never set the property_bag variable to NULL so there is no issue there unless the user mistakenly sets it to NULL

/**
* @brief MQTT 5 property string.
*
* @note Depending on the MQTT 5 stack implementation, string may need to be freed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we would be calling these in the hfsm, should the comment indicate that they always should be free'd or that the free method can always be safely called since some mqtt implementations do require it? (similar to what you say in line 313)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed comment to "should always be freed". The method for freeing should always be safe.

*
* @param[in] prop_str The MQTT 5 property string.
*
* @note After getting the string value, the property string must be freed using
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this free required after the read/find, not the get? At the point the user is calling get, the property has already been allocated and needs to be free'd regardless

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved the comment to the read functions

/**
* @brief MQTT 5 property binary data.
*
* @note Depending on the MQTT 5 stack implementation, string pair data may need to be freed.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @note Depending on the MQTT 5 stack implementation, string pair data may need to be freed.
* @note Depending on the MQTT 5 stack implementation, binary data may need to be freed.

sdk/inc/azure/core/az_mqtt5.h Outdated Show resolved Hide resolved
AZ_MQTT5_PROPERTY_TYPE_USER_PROPERTY = 38,
} az_mqtt5_property_type;

// Porting 3. The following functions must be implemented and will be called by the SDK to interact
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the 3 here for?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It follows part 2 of the porting instructions in az_mqtt5.h, I added some clarification `// Porting az_mqtt5 ..."

* @brief This header defines the MQTT 5 property bag and its related methods. The following
* structures and API are used by the SDK when sending and receiving MQTT5 properties.
*
* @note A property bag struct contains an internal property bag options struct. These options
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: not internal anymore/not contained in the property bag(?)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed, thanks for pointing that out!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants