-
Notifications
You must be signed in to change notification settings - Fork 120
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
Conversation
RLeclair
commented
Jul 21, 2023
•
edited
Loading
edited
- 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.
There was a problem hiding this 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.
* and they are subject to change in future versions of the SDK which would break your code. | ||
*/ | ||
|
||
#ifndef _az_MQTT5_H |
There was a problem hiding this comment.
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:
- usage of the API (within our SDK).
- instructions for developers that want to port the interface to another platform.
sdk/inc/azure/core/az_mqtt5.h
Outdated
* | ||
* @return The string value of the property. | ||
*/ | ||
AZ_NODISCARD AZ_INLINE az_span az_mqtt5_property_string_get(az_mqtt5_property_string* prop_str) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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_span
s: 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.
There was a problem hiding this comment.
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
Outdated
* @brief The string value of the property. | ||
*/ | ||
az_span str; | ||
} az_mqtt5_property_string; |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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)
.
{ | ||
(void)mqtt5; | ||
property_bag->_internal.options | ||
= options == NULL ? az_mqtt5_property_bag_options_default() : *options; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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;
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), |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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!
Will address rest of comments in a follow-up PR. Merging to unblock other work. |
@@ -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); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* @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. |
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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(?)
There was a problem hiding this comment.
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!