@@ -2779,13 +2779,123 @@ static int s_aws_mqtt_client_connection_5_get_stats(
27792779 return AWS_OP_SUCCESS ;
27802780}
27812781
2782+ struct aws_mqtt_set_metrics_task {
2783+ struct aws_task task ;
2784+ struct aws_allocator * allocator ;
2785+ struct aws_mqtt_client_connection_5_impl * adapter ;
2786+
2787+ struct aws_mqtt_iot_sdk_metrics_storage * metrics_storage ;
2788+ };
2789+
2790+ static void s_aws_mqtt_set_metrics_task_destroy (struct aws_mqtt_set_metrics_task * task ) {
2791+ if (task == NULL ) {
2792+ return ;
2793+ }
2794+
2795+ aws_mqtt_iot_sdk_metrics_storage_clean_up (task -> metrics_storage );
2796+
2797+ aws_mem_release (task -> allocator , task );
2798+ }
2799+
2800+ static void s_set_metrics_task_fn (struct aws_task * task , void * arg , enum aws_task_status status ) {
2801+ (void )task ;
2802+
2803+ struct aws_mqtt_set_metrics_task * set_task = arg ;
2804+ struct aws_mqtt_client_connection_5_impl * adapter = set_task -> adapter ;
2805+ if (status != AWS_TASK_STATUS_RUN_READY ) {
2806+ goto done ;
2807+ }
2808+
2809+ /* we're in the mqtt5 client's event loop; it's safe to access internal state */
2810+ struct aws_mqtt5_packet_connect_storage * old_connect = adapter -> client -> config -> connect ;
2811+
2812+ /*
2813+ * Packet storage stores binary data in a single buffer. The safest way to replace some binary data is
2814+ * to make a new storage from the old storage, deleting the old storage after construction is complete.
2815+ */
2816+ struct aws_mqtt5_packet_connect_view new_connect_view = old_connect -> storage_view ;
2817+
2818+ if (set_task -> metrics_storage ) {
2819+ new_connect_view .metrics = & set_task -> metrics_storage -> storage_view ;
2820+ } else {
2821+ new_connect_view .metrics = NULL ;
2822+ }
2823+
2824+ if (aws_mqtt5_packet_connect_view_validate (& new_connect_view )) {
2825+ AWS_LOGF_ERROR (
2826+ AWS_LS_MQTT5_TO_MQTT3_ADAPTER , "id=%p: mqtt3-to-5-adapter - invalid CONNECT metrics" , (void * )adapter );
2827+ goto done ;
2828+ }
2829+
2830+ struct aws_mqtt5_packet_connect_storage * new_connect =
2831+ aws_mem_calloc (adapter -> allocator , 1 , sizeof (struct aws_mqtt5_packet_connect_storage ));
2832+
2833+ if (aws_mqtt5_packet_connect_storage_init (new_connect , adapter -> allocator , & new_connect_view )) {
2834+ aws_mem_release (adapter -> allocator , new_connect );
2835+ goto done ;
2836+ }
2837+
2838+ adapter -> client -> config -> connect = new_connect ;
2839+ aws_mqtt5_packet_connect_storage_clean_up (old_connect );
2840+ aws_mem_release (old_connect -> allocator , old_connect );
2841+
2842+ done :
2843+
2844+ aws_ref_count_release (& adapter -> internal_refs );
2845+
2846+ s_aws_mqtt_set_metrics_task_destroy (set_task );
2847+ }
2848+
2849+ static struct aws_mqtt_set_metrics_task * s_aws_mqtt_set_metrics_task_new (
2850+ struct aws_allocator * allocator ,
2851+ struct aws_mqtt_client_connection_5_impl * adapter ,
2852+ const struct aws_mqtt_iot_sdk_metrics * metrics ) {
2853+
2854+ struct aws_mqtt_set_metrics_task * set_task = aws_mem_calloc (allocator , 1 , sizeof (struct aws_mqtt_set_metrics_task ));
2855+ if (set_task == NULL ) {
2856+ return NULL ;
2857+ }
2858+
2859+ aws_task_init (& set_task -> task , s_set_metrics_task_fn , (void * )set_task , "SetMetricsTask" );
2860+ set_task -> allocator = allocator ;
2861+ set_task -> adapter = (struct aws_mqtt_client_connection_5_impl * )aws_ref_count_acquire (& adapter -> internal_refs );
2862+
2863+ if (metrics != NULL ) {
2864+ set_task -> metrics_storage = aws_mem_calloc (allocator , 1 , sizeof (struct aws_mqtt_iot_sdk_metrics_storage ));
2865+ if (aws_mqtt_iot_sdk_metrics_storage_init (set_task -> metrics_storage , allocator , metrics )) {
2866+ aws_ref_count_release (& adapter -> internal_refs );
2867+ aws_mem_release (allocator , set_task );
2868+ return NULL ;
2869+ }
2870+ }
2871+
2872+ return set_task ;
2873+ }
2874+
27822875static int s_aws_mqtt_client_connection_5_set_metrics (void * impl , const struct aws_mqtt_iot_sdk_metrics * metrics ) {
2783- (void )impl ;
2784- (void )metrics ;
2876+ struct aws_mqtt_client_connection_5_impl * adapter = impl ;
27852877
2786- /* MQTT5 adapter does not support metrics configuration */
2787- AWS_LOGF_WARN (AWS_LS_MQTT5_TO_MQTT3_ADAPTER , "MQTT5 adapter does not support metrics configuration" );
2788- return aws_raise_error (AWS_ERROR_UNSUPPORTED_OPERATION );
2878+ if (aws_mqtt_validate_iot_sdk_metrics_utf8 (metrics )) {
2879+ AWS_LOGF_DEBUG (
2880+ AWS_LS_MQTT5_TO_MQTT3_ADAPTER , "id=%p: Invalid utf8 or forbidden codepoints in metrics." , (void * )adapter );
2881+ return aws_raise_error (AWS_ERROR_INVALID_UTF8 );
2882+ }
2883+
2884+ struct aws_mqtt_set_metrics_task * task = s_aws_mqtt_set_metrics_task_new (adapter -> allocator , adapter , metrics );
2885+ if (task == NULL ) {
2886+ int error_code = aws_last_error ();
2887+ AWS_LOGF_ERROR (
2888+ AWS_LS_MQTT5_TO_MQTT3_ADAPTER ,
2889+ "id=%p: failed to create set metrics task, error code %d(%s)" ,
2890+ (void * )adapter ,
2891+ error_code ,
2892+ aws_error_debug_str (error_code ));
2893+ return AWS_OP_ERR ;
2894+ }
2895+
2896+ aws_event_loop_schedule_task_now (adapter -> loop , & task -> task );
2897+
2898+ return AWS_OP_SUCCESS ;
27892899}
27902900
27912901static uint16_t s_aws_mqtt_5_resubscribe_existing_topics (
0 commit comments