From e610e20b38010561aed7fa41fd6c6f357b6d6ca4 Mon Sep 17 00:00:00 2001 From: Zhihui Xia Date: Fri, 22 Sep 2023 10:44:12 -0700 Subject: [PATCH] update multi_suback behavior --- source/v5/mqtt5_to_mqtt3_adapter.c | 96 +++++++++++++------------ tests/v3/connection_state_test.c | 3 +- tests/v5/mqtt5_to_mqtt3_adapter_tests.c | 9 ++- 3 files changed, 61 insertions(+), 47 deletions(-) diff --git a/source/v5/mqtt5_to_mqtt3_adapter.c b/source/v5/mqtt5_to_mqtt3_adapter.c index cb1391d7..f8c47cdd 100644 --- a/source/v5/mqtt5_to_mqtt3_adapter.c +++ b/source/v5/mqtt5_to_mqtt3_adapter.c @@ -2188,6 +2188,12 @@ static void s_aws_mqtt5_to_mqtt3_adapter_subscribe_completion_fn( struct aws_mqtt5_to_mqtt3_adapter_operation_subscribe *subscribe_op = complete_ctx; struct aws_mqtt_client_connection_5_impl *adapter = subscribe_op->base.adapter; struct aws_mqtt_subscription_set_subscription_record *record = NULL; + size_t reason_code_count = 0; + + if (suback != NULL) { + reason_code_count = suback->reason_code_count; + } + size_t subscription_count = aws_array_list_length(&subscribe_op->subscriptions); if (subscribe_op->on_suback != NULL) { AWS_LOGF_DEBUG( @@ -2200,16 +2206,15 @@ static void s_aws_mqtt5_to_mqtt3_adapter_subscribe_completion_fn( enum aws_mqtt_qos granted_qos = AWS_MQTT_QOS_AT_MOST_ONCE; - size_t subscription_count = aws_array_list_length(&subscribe_op->subscriptions); if (subscription_count > 0) { aws_array_list_get_at(&subscribe_op->subscriptions, &record, 0); topic_filter = record->subscription_view.topic_filter; } - if (suback != NULL) { - if (suback->reason_code_count > 0) { - granted_qos = s_convert_mqtt5_suback_reason_code_to_mqtt3_granted_qos(suback->reason_codes[0]); - } + if (reason_code_count > 0) { + granted_qos = s_convert_mqtt5_suback_reason_code_to_mqtt3_granted_qos(suback->reason_codes[0]); + } else if (record) { + granted_qos = (enum aws_mqtt_qos)(record->subscription_view.qos); } else { granted_qos = AWS_MQTT_QOS_FAILURE; } @@ -2228,50 +2233,51 @@ static void s_aws_mqtt5_to_mqtt3_adapter_subscribe_completion_fn( "id=%p: mqtt3-to-5-adapter, completing multi-topic subscribe", (void *)adapter); - if (suback == NULL) { - (*subscribe_op->on_multi_suback)( - &adapter->base, subscribe_op->base.id, NULL, error_code, subscribe_op->on_multi_suback_user_data); - } else { - AWS_VARIABLE_LENGTH_ARRAY( - struct aws_mqtt_topic_subscription, multi_sub_subscription_buf, suback->reason_code_count); - AWS_VARIABLE_LENGTH_ARRAY( - struct aws_mqtt_topic_subscription *, multi_sub_subscription_ptr_buf, suback->reason_code_count); - struct aws_mqtt_topic_subscription *subscription_ptr = - (struct aws_mqtt_topic_subscription *)multi_sub_subscription_buf; - - struct aws_array_list multi_sub_list; - aws_array_list_init_static( - &multi_sub_list, - multi_sub_subscription_ptr_buf, - suback->reason_code_count, - sizeof(struct aws_mqtt_topic_subscription *)); - - size_t subscription_count = aws_array_list_length(&subscribe_op->subscriptions); - - for (size_t i = 0; i < suback->reason_code_count; ++i) { - struct aws_mqtt_topic_subscription *subscription = subscription_ptr + i; - AWS_ZERO_STRUCT(*subscription); - - subscription->qos = s_convert_mqtt5_suback_reason_code_to_mqtt3_granted_qos(suback->reason_codes[i]); - - if (i < subscription_count) { - aws_array_list_get_at(&subscribe_op->subscriptions, &record, i); + // If the suback does not contains any data, we directly extract the data from subscribe_op + if (reason_code_count == 0) { + reason_code_count = subscription_count; + } - subscription->topic = record->subscription_view.topic_filter; - subscription->on_publish = record->subscription_view.on_publish_received; - subscription->on_publish_ud = record->subscription_view.callback_user_data; - subscription->on_cleanup = record->subscription_view.on_cleanup; - } + AWS_VARIABLE_LENGTH_ARRAY(struct aws_mqtt_topic_subscription, multi_sub_subscription_buf, reason_code_count); + AWS_VARIABLE_LENGTH_ARRAY( + struct aws_mqtt_topic_subscription *, multi_sub_subscription_ptr_buf, reason_code_count); + struct aws_mqtt_topic_subscription *subscription_ptr = + (struct aws_mqtt_topic_subscription *)multi_sub_subscription_buf; + + struct aws_array_list multi_sub_list; + aws_array_list_init_static( + &multi_sub_list, + multi_sub_subscription_ptr_buf, + reason_code_count, + sizeof(struct aws_mqtt_topic_subscription *)); + + for (size_t i = 0; i < reason_code_count; ++i) { + struct aws_mqtt_topic_subscription *subscription = subscription_ptr + i; + AWS_ZERO_STRUCT(*subscription); + + if (i < subscription_count) { + aws_array_list_get_at(&subscribe_op->subscriptions, &record, i); + + subscription->topic = record->subscription_view.topic_filter; + subscription->on_publish = record->subscription_view.on_publish_received; + subscription->on_publish_ud = record->subscription_view.callback_user_data; + subscription->on_cleanup = record->subscription_view.on_cleanup; + } - aws_array_list_push_back(&multi_sub_list, &subscription); + if (suback != NULL) { + subscription->qos = s_convert_mqtt5_suback_reason_code_to_mqtt3_granted_qos(suback->reason_codes[i]); + } else { + subscription->qos = (enum aws_mqtt_qos)(record->subscription_view.qos); } - (*subscribe_op->on_multi_suback)( - &adapter->base, - subscribe_op->base.id, - &multi_sub_list, - error_code, - subscribe_op->on_multi_suback_user_data); + + aws_array_list_push_back(&multi_sub_list, &subscription); } + (*subscribe_op->on_multi_suback)( + &adapter->base, + subscribe_op->base.id, + &multi_sub_list, + error_code, + subscribe_op->on_multi_suback_user_data); } aws_mqtt5_to_mqtt3_adapter_operation_table_remove_operation( diff --git a/tests/v3/connection_state_test.c b/tests/v3/connection_state_test.c index 6a3e086f..ec8bb0d2 100644 --- a/tests/v3/connection_state_test.c +++ b/tests/v3/connection_state_test.c @@ -619,7 +619,8 @@ static void s_on_multi_suback( aws_mutex_lock(&state_test_data->lock); state_test_data->subscribe_completed = true; - if (!error_code) { + // The suback would return the subscription data regardless of error_code + if (topic_subacks) { size_t length = aws_array_list_length(topic_subacks); for (size_t i = 0; i < length; ++i) { struct aws_mqtt_topic_subscription *subscription = NULL; diff --git a/tests/v5/mqtt5_to_mqtt3_adapter_tests.c b/tests/v5/mqtt5_to_mqtt3_adapter_tests.c index 3b6c9dba..cf6b88f9 100644 --- a/tests/v5/mqtt5_to_mqtt3_adapter_tests.c +++ b/tests/v5/mqtt5_to_mqtt3_adapter_tests.c @@ -2785,7 +2785,8 @@ static void s_aws_mqtt5_to_mqtt3_adapter_test_fixture_record_subscribe_multi_com .error_code = error_code, }; - if (error_code == AWS_ERROR_SUCCESS) { + // The subscription would return subscription data regardless of error code + if (topic_subacks) { size_t granted_count = aws_array_list_length(topic_subacks); aws_array_list_init_dynamic( @@ -2957,6 +2958,12 @@ static int s_mqtt5to3_adapter_subscribe_multi_null_suback_fn(struct aws_allocato }, }; + aws_array_list_init_static_from_initialized( + &expected_events[0].granted_subscriptions, + (void *)subscriptions, + 2, + sizeof(struct aws_mqtt_topic_subscription)); + aws_mqtt_client_connection_disconnect( connection, s_aws_mqtt5_to_mqtt3_adapter_test_fixture_record_disconnection_complete, &fixture);