Skip to content

Commit dff3daa

Browse files
committed
wip: init mqtt5 connect storage changes
1 parent 650ad30 commit dff3daa

9 files changed

Lines changed: 126 additions & 21 deletions

include/aws/mqtt/private/client_impl_shared.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ AWS_MQTT_API int aws_mqtt_iot_sdk_metrics_storage_init(
154154
struct aws_allocator *allocator,
155155
const struct aws_mqtt_iot_sdk_metrics *metrics_options);
156156

157+
AWS_MQTT_API size_t aws_mqtt_iot_sdk_metrics_compute_storage_size(const struct aws_mqtt_iot_sdk_metrics *metrics);
158+
157159
AWS_MQTT_API void aws_mqtt_iot_sdk_metrics_storage_clean_up(struct aws_mqtt_iot_sdk_metrics_storage *metrics_storage);
158160

159161
AWS_MQTT_API enum aws_mqtt311_impl_type aws_mqtt_client_connection_get_impl_type(
@@ -173,7 +175,8 @@ AWS_MQTT_API struct aws_event_loop *aws_mqtt_client_connection_get_event_loop(
173175
*
174176
* @param original_username The original username
175177
* @param metrics The metrics configuration
176-
* @param output_username Buffer to store the modified username
178+
* @param output_username Buffer to store the modified username. If the function succeed, caller is responsible to release
179+
* the memory for output_username.
177180
*
178181
* @return AWS_OP_SUCCESS on success, AWS_OP_ERR on failure
179182
*/
@@ -184,4 +187,12 @@ int aws_mqtt_append_sdk_metrics_to_username(
184187
const struct aws_mqtt_iot_sdk_metrics metrics,
185188
struct aws_byte_buf *output_username);
186189

190+
/**
191+
* Get final username length
192+
*/
193+
AWS_MQTT_API
194+
size_t aws_mqtt_append_sdk_metrics_to_username_size(
195+
const struct aws_byte_cursor *original_username,
196+
const struct aws_mqtt_iot_sdk_metrics metrics);
197+
187198
#endif /* AWS_MQTT_PRIVATE_CLIENT_IMPL_SHARED_H */

include/aws/mqtt/v5/mqtt5_types.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
#include <aws/common/array_list.h>
1212
#include <aws/common/byte_buf.h>
1313

14+
struct aws_mqtt_iot_sdk_metrics;
15+
1416
AWS_PUSH_SANE_WARNING_LEVEL
1517

1618
/**
@@ -394,6 +396,9 @@ struct aws_mqtt5_packet_connect_view {
394396
/* Do not bind these. We don't support AUTH packets yet. For decode/encade testing purposes only. */
395397
const struct aws_byte_cursor *authentication_method;
396398
const struct aws_byte_cursor *authentication_data;
399+
400+
/* IoT SDK metrics configuration */
401+
const struct aws_mqtt_iot_sdk_metrics *metrics;
397402
};
398403

399404
/**

source/client.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,7 @@ static void s_mqtt_client_connection_destroy_final(struct aws_mqtt_client_connec
871871
/* Clean up metrics */
872872
if (connection->metrics) {
873873
aws_mqtt_iot_sdk_metrics_storage_clean_up(connection->metrics);
874+
connection->metrics = NULL;
874875
}
875876

876877
aws_byte_buf_clean_up(&connection->username_with_metrics_buf);

source/client_impl_shared.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ struct aws_event_loop *aws_mqtt_client_connection_get_event_loop(const struct aw
232232
* IoT SDK Metrics
233233
********************************************************************************************************************/
234234

235-
static size_t s_aws_mqtt_iot_sdk_metrics_compute_storage_size(const struct aws_mqtt_iot_sdk_metrics *metrics) {
235+
size_t aws_mqtt_iot_sdk_metrics_compute_storage_size(const struct aws_mqtt_iot_sdk_metrics *metrics) {
236236
if (metrics == NULL) {
237237
return 0;
238238
}
@@ -264,7 +264,7 @@ int aws_mqtt_iot_sdk_metrics_storage_init(
264264
return AWS_OP_SUCCESS;
265265
}
266266

267-
size_t storage_capacity = s_aws_mqtt_iot_sdk_metrics_compute_storage_size(metrics_options);
267+
size_t storage_capacity = aws_mqtt_iot_sdk_metrics_compute_storage_size(metrics_options);
268268
if (aws_byte_buf_init(&metrics_storage->storage, allocator, storage_capacity)) {
269269
return AWS_OP_ERR;
270270
}
@@ -329,6 +329,5 @@ void aws_mqtt_iot_sdk_metrics_storage_clean_up(struct aws_mqtt_iot_sdk_metrics_s
329329
}
330330
aws_byte_buf_clean_up(&metrics_storage->storage);
331331

332-
aws_mem_release(metrics_storage->allocator, &metrics_storage);
333-
metrics_storage = NULL;
332+
aws_mem_release(metrics_storage->allocator, metrics_storage);
334333
}

source/mqtt_iot_sdk_metrics.c

Lines changed: 58 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,6 @@ int aws_mqtt_append_sdk_metrics_to_username(
5454
}
5555
}
5656

57-
bool metrics_added = false;
58-
5957
/* Add SDK if not present */
6058
if (!has_sdk) {
6159
if (aws_byte_buf_append(&metrics_string, &sdk_str)) {
@@ -67,15 +65,13 @@ int aws_mqtt_append_sdk_metrics_to_username(
6765
if (aws_byte_buf_append(&metrics_string, &sdk_attr_value)) {
6866
goto error;
6967
}
70-
71-
metrics_added = true;
7268
}
7369

7470
/* Add Platform if not present */
7571
if (!has_platform) {
7672
struct aws_byte_cursor platform_cursor = aws_get_platform_build_os_string();
7773
if (platform_cursor.len > 0) {
78-
if (metrics_added) {
74+
if (metrics_string.len > 0) {
7975
if (aws_byte_buf_append(&metrics_string, &amp)) {
8076
goto error;
8177
}
@@ -85,7 +81,6 @@ int aws_mqtt_append_sdk_metrics_to_username(
8581
aws_byte_buf_append(&metrics_string, &platform_cursor)) {
8682
goto error;
8783
}
88-
metrics_added = true;
8984
}
9085
}
9186

@@ -131,3 +126,60 @@ int aws_mqtt_append_sdk_metrics_to_username(
131126
aws_byte_buf_clean_up(&metrics_string);
132127
return AWS_OP_ERR;
133128
}
129+
130+
size_t aws_mqtt_append_sdk_metrics_to_username_size(
131+
const struct aws_byte_cursor *original_username,
132+
const struct aws_mqtt_iot_sdk_metrics metrics) {
133+
134+
/* Build metrics string */
135+
size_t metrics_string_size = 0;
136+
137+
/* Check if the attributes already exists in username */
138+
bool has_sdk = false;
139+
bool has_platform = false;
140+
bool has_query = false;
141+
142+
struct aws_byte_cursor sdk_str = aws_byte_cursor_from_c_str("SDK=");
143+
struct aws_byte_cursor platform_str = aws_byte_cursor_from_c_str("Platform=");
144+
struct aws_byte_cursor question_mark_str = aws_byte_cursor_from_c_str("?");
145+
146+
// TODO: we ignored the metadata field for now, need to add them in the future
147+
148+
if (original_username && original_username->len > 0) {
149+
struct aws_byte_cursor question_mark_find;
150+
has_query =
151+
AWS_OP_SUCCESS == aws_byte_cursor_find_exact(original_username, &question_mark_str, &question_mark_find);
152+
if (has_query) {
153+
struct aws_byte_cursor temp_cursor;
154+
has_sdk = AWS_OP_SUCCESS == aws_byte_cursor_find_exact(&question_mark_find, &sdk_str, &temp_cursor);
155+
has_platform =
156+
AWS_OP_SUCCESS == aws_byte_cursor_find_exact(&question_mark_find, &platform_str, &temp_cursor);
157+
}
158+
}
159+
160+
/* Add SDK if not present */
161+
if (!has_sdk) {
162+
metrics_string_size += sdk_str.len;
163+
164+
struct aws_byte_cursor sdk_attr_value =
165+
metrics.library_name.len > 0 ? metrics.library_name : aws_byte_cursor_from_c_str("IoTDeviceSDK/C");
166+
167+
metrics_string_size += sdk_attr_value.len;
168+
}
169+
170+
/* Add Platform if not present */
171+
if (!has_platform) {
172+
struct aws_byte_cursor platform_cursor = aws_get_platform_build_os_string();
173+
if (platform_cursor.len > 0) {
174+
// Add amp sign if metrics is not empty
175+
metrics_string_size += metrics_string_size + metrics_string_size > 0 ? 1 : 0;
176+
177+
metrics_string_size += platform_str.len + platform_cursor.len;
178+
}
179+
}
180+
181+
/* Build final output */
182+
/* original_username + 1 character of "?" or "&" + metrics string*/
183+
size_t total_size = (original_username ? original_username->len : 0) + 1 + metrics_string_size;
184+
return total_size;
185+
}

source/v5/mqtt5_options_storage.c

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <aws/common/uuid.h>
1212
#include <aws/io/channel_bootstrap.h>
1313
#include <aws/io/event_loop.h>
14+
#include <aws/mqtt/private/client_impl_shared.h>
1415
#include <aws/mqtt/private/v5/mqtt5_client_impl.h>
1516
#include <aws/mqtt/private/v5/mqtt5_utils.h>
1617
#include <aws/mqtt/v5/mqtt5_client.h>
@@ -643,7 +644,11 @@ static size_t s_aws_mqtt5_packet_connect_compute_storage_size(const struct aws_m
643644

644645
storage_size += view->client_id.len;
645646
if (view->username != NULL) {
646-
storage_size += view->username->len;
647+
if (view->metrics) {
648+
storage_size += aws_mqtt_append_sdk_metrics_to_username_size(view->username, *view->metrics);
649+
} else {
650+
storage_size += view->username->len;
651+
}
647652
}
648653
if (view->password != NULL) {
649654
storage_size += view->password->len;
@@ -652,6 +657,8 @@ static size_t s_aws_mqtt5_packet_connect_compute_storage_size(const struct aws_m
652657
storage_size +=
653658
s_aws_mqtt5_user_property_set_compute_storage_size(view->user_properties, view->user_property_count);
654659

660+
storage_size += aws_mqtt_iot_sdk_metrics_compute_storage_size(view->metrics);
661+
655662
if (view->authentication_method != NULL) {
656663
storage_size += view->authentication_method->len;
657664
}
@@ -686,8 +693,23 @@ int aws_mqtt5_packet_connect_storage_init(
686693

687694
if (view->username != NULL) {
688695
storage->username = *view->username;
689-
if (aws_byte_buf_append_and_update(&storage->storage, &storage->username)) {
690-
return AWS_OP_ERR;
696+
struct aws_byte_buf metrics_username_buf;
697+
AWS_ZERO_STRUCT(metrics_username_buf);
698+
699+
/* Apply metrics to username if configured */
700+
if (view->metrics) {
701+
struct aws_byte_cursor username_cur = storage->username;
702+
if (aws_mqtt_append_sdk_metrics_to_username(
703+
allocator, &username_cur, *view->metrics, &metrics_username_buf)) {
704+
return AWS_OP_ERR;
705+
}
706+
storage->username = aws_byte_cursor_from_buf(&metrics_username_buf);
707+
708+
if (aws_byte_buf_append_and_update(&storage->storage, &storage->username)) {
709+
aws_byte_buf_clean_up(&metrics_username_buf);
710+
return AWS_OP_ERR;
711+
}
712+
aws_byte_buf_clean_up(&metrics_username_buf);
691713
}
692714

693715
storage_view->username = &storage->username;

tests/v3/mqtt311_testing_utils.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -586,9 +586,9 @@ static const struct aws_byte_cursor PLATFORM_ATT_STR = AWS_BYTE_CUR_INIT_FROM_ST
586586

587587
void aws_test_mqtt_build_expected_metrics(
588588
struct aws_allocator *allocator,
589-
struct aws_byte_cursor *original_username,
590-
struct aws_byte_cursor sdk,
591-
struct aws_byte_cursor *platform,
589+
const struct aws_byte_cursor *original_username,
590+
const struct aws_byte_cursor sdk,
591+
const struct aws_byte_cursor *platform,
592592
struct aws_byte_buf *expected_buf) {
593593
struct aws_byte_cursor platform_to_use = platform ? *platform : aws_get_platform_build_os_string();
594594
if (original_username) {

tests/v3/mqtt311_testing_utils.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,9 +152,9 @@ void aws_test311_on_connection_termination_fn(void *userdata);
152152

153153
void aws_test_mqtt_build_expected_metrics(
154154
struct aws_allocator *allocator,
155-
struct aws_byte_cursor *original_username,
156-
struct aws_byte_cursor sdk,
157-
struct aws_byte_cursor *platform,
155+
const struct aws_byte_cursor *original_username,
156+
const struct aws_byte_cursor sdk,
157+
const struct aws_byte_cursor *platform,
158158
struct aws_byte_buf *expected_buf);
159159

160160
AWS_EXTERN_C_END

tests/v5/mqtt5_operation_and_storage_tests.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* SPDX-License-Identifier: Apache-2.0.
44
*/
55

6+
#include "../v3/mqtt311_testing_utils.h"
7+
68
#include <aws/common/string.h>
79

810
#include "mqtt5_testing_utils.h"
@@ -672,6 +674,12 @@ static int s_mqtt5_connect_storage_new_set_all_fn(struct aws_allocator *allocato
672674
.topic = aws_byte_cursor_from_c_str(PUBLISH_TOPIC),
673675
};
674676

677+
struct aws_mqtt_iot_sdk_metrics metrics = {
678+
.library_name = aws_byte_cursor_from_c_str("TestSDK/1.0"),
679+
.metadata_entries = NULL,
680+
.metadata_count = 0,
681+
};
682+
675683
struct aws_mqtt5_packet_connect_view connect_options = {
676684
.keep_alive_interval_seconds = 50,
677685
.client_id = aws_byte_cursor_from_string(s_client_id),
@@ -690,6 +698,7 @@ static int s_mqtt5_connect_storage_new_set_all_fn(struct aws_allocator *allocato
690698
.user_properties = s_user_properties,
691699
.authentication_method = &s_authentication_method_cursor,
692700
.authentication_data = &s_authentication_data_cursor,
701+
.metrics = &metrics
693702
};
694703

695704
struct aws_mqtt5_packet_connect_storage connect_storage;
@@ -700,8 +709,14 @@ static int s_mqtt5_connect_storage_new_set_all_fn(struct aws_allocator *allocato
700709
ASSERT_SUCCESS(s_aws_mqtt5_connect_storage_verify_required_properties(&connect_storage, &connect_options));
701710

702711
struct aws_mqtt5_packet_connect_view *stored_view = &connect_storage.storage_view;
712+
713+
/* Build expected username with metrics */
714+
struct aws_byte_buf expected_username;
715+
AWS_ZERO_STRUCT(expected_username);
716+
aws_test_mqtt_build_expected_metrics(allocator, connect_options.username, metrics.library_name, NULL, &expected_username);
717+
ASSERT_BIN_ARRAYS_EQUALS(expected_username.buffer, expected_username.len, connect_storage.username.ptr, connect_storage.username.len);
718+
aws_byte_buf_clean_up(&expected_username);
703719

704-
AWS_VERIFY_VIEW_STORAGE_RELATIONSHIP_NULLABLE_CURSOR(&connect_storage, &connect_options, username);
705720
AWS_VERIFY_VIEW_STORAGE_RELATIONSHIP_NULLABLE_CURSOR(&connect_storage, &connect_options, password);
706721
AWS_VERIFY_VIEW_STORAGE_RELATIONSHIP_NULLABLE_UINT(
707722
&connect_storage, &connect_options, session_expiry_interval_seconds);

0 commit comments

Comments
 (0)