From 0c64f25334ce3c993cf9e211dec878e0df769692 Mon Sep 17 00:00:00 2001 From: Vera Xia Date: Mon, 4 Dec 2023 14:05:18 -0800 Subject: [PATCH] Mqtt5 GA API Review (#575) --- bin/mqtt5_canary/main.cpp | 4 +- include/aws/crt/mqtt/Mqtt5Client.h | 38 ++++-- include/aws/crt/mqtt/Mqtt5Packets.h | 78 ++++++++++- include/aws/crt/mqtt/Mqtt5Types.h | 195 +++++++++++++++++++++++++++- include/aws/iot/Mqtt5Client.h | 16 ++- source/iot/Mqtt5Client.cpp | 11 +- source/mqtt/Mqtt5Client.cpp | 9 +- source/mqtt/Mqtt5Packets.cpp | 56 +++++--- tests/Mqtt5ClientTest.cpp | 12 +- 9 files changed, 372 insertions(+), 47 deletions(-) diff --git a/bin/mqtt5_canary/main.cpp b/bin/mqtt5_canary/main.cpp index 24901dd78..6df78de77 100644 --- a/bin/mqtt5_canary/main.cpp +++ b/bin/mqtt5_canary/main.cpp @@ -426,14 +426,14 @@ static int s_AwsMqtt5CanaryOperationSubscribe(struct AwsMqtt5CanaryTestClient *t .WithNoLocal(false) .WithQOS(Mqtt5::QOS::AWS_MQTT5_QOS_AT_LEAST_ONCE) .WithRetainHandlingType(Mqtt5::RetainHandlingType::AWS_MQTT5_RHT_SEND_ON_SUBSCRIBE) - .WithRetain(false); + .WithRetainAsPublished(false); Mqtt5::Subscription subscription2; subscription2.WithTopicFilter(testClient->sharedTopic) .WithNoLocal(false) .WithQOS(Mqtt5::QOS::AWS_MQTT5_QOS_AT_LEAST_ONCE) .WithRetainHandlingType(Mqtt5::RetainHandlingType::AWS_MQTT5_RHT_SEND_ON_SUBSCRIBE) - .WithRetain(false); + .WithRetainAsPublished(false); std::shared_ptr packet = std::make_shared(allocator); packet->WithSubscription(std::move(subscription1)); diff --git a/include/aws/crt/mqtt/Mqtt5Client.h b/include/aws/crt/mqtt/Mqtt5Client.h index bd846a4d6..38fdf2db3 100644 --- a/include/aws/crt/mqtt/Mqtt5Client.h +++ b/include/aws/crt/mqtt/Mqtt5Client.h @@ -147,7 +147,7 @@ namespace Aws * Controls how the reconnect delay is modified in order to smooth out the distribution of reconnection * attempt timepoints for a large set of reconnecting clients. */ - JitterMode m_reconnectMode; + ExponentialBackoffJitterMode m_reconnectMode; /** * Minimum amount of time to wait to reconnect after a disconnect. Exponential backoff is performed @@ -383,47 +383,47 @@ namespace Aws * Notifies the MQTT5 client that you want it to transition to the stopped state, disconnecting any * existing connection and stopping subsequent reconnect attempts. * - * @param disconnectOptions (optional) properties of a DISCONNECT packet to send as part of the shutdown + * @param disconnectPacket (optional) properties of a DISCONNECT packet to send as part of the shutdown * process * * @return bool: true if operation succeed, otherwise false */ - bool Stop(std::shared_ptr disconnectOptions) noexcept; + bool Stop(std::shared_ptr disconnectPacket) noexcept; /** * Tells the client to attempt to send a PUBLISH packet * - * @param publishOptions: packet PUBLISH to send to the server + * @param publishPacket: packet PUBLISH to send to the server * @param onPublishCompletionCallback: callback on publish complete, default to NULL * * @return true if the publish operation succeed otherwise false */ bool Publish( - std::shared_ptr publishOptions, + std::shared_ptr publishPacket, OnPublishCompletionHandler onPublishCompletionCallback = NULL) noexcept; /** * Tells the client to attempt to subscribe to one or more topic filters. * - * @param subscribeOptions: SUBSCRIBE packet to send to the server + * @param subscribePacket: SUBSCRIBE packet to send to the server * @param onSubscribeCompletionCallback: callback on subscribe complete, default to NULL * * @return true if the subscription operation succeed otherwise false */ bool Subscribe( - std::shared_ptr subscribeOptions, + std::shared_ptr subscribePacket, OnSubscribeCompletionHandler onSubscribeCompletionCallback = NULL) noexcept; /** * Tells the client to attempt to unsubscribe to one or more topic filters. * - * @param unsubscribeOptions: UNSUBSCRIBE packet to send to the server + * @param unsubscribePacket: UNSUBSCRIBE packet to send to the server * @param onUnsubscribeCompletionCallback: callback on unsubscribe complete, default to NULL * * @return true if the unsubscription operation succeed otherwise false */ bool Unsubscribe( - std::shared_ptr unsubscribeOptions, + std::shared_ptr unsubscribePacket, OnUnsubscribeCompletionHandler onUnsubscribeCompletionCallback = NULL) noexcept; /** @@ -517,11 +517,11 @@ namespace Aws /** * Sets mqtt5 connection options * - * @param packetConnect package connection options + * @param connectPacket package connection options * * @return this option object */ - Mqtt5ClientOptions &WithConnectOptions(std::shared_ptr packetConnect) noexcept; + Mqtt5ClientOptions &WithConnectOptions(std::shared_ptr connectPacket) noexcept; /** * Sets session behavior. Overrides how the MQTT5 client should behave with respect to MQTT sessions. @@ -595,15 +595,27 @@ namespace Aws */ Mqtt5ClientOptions &WithConnackTimeoutMs(uint32_t connackTimeoutMs) noexcept; + /** + * @deprecated The function is deprecated, please use `Mqtt5ClientOptions::WithAckTimeoutSec(uint32_t)` + * + * Sets Operation Timeout(Seconds). Time interval to wait for an ack after sending a QoS 1+ PUBLISH, + * SUBSCRIBE, or UNSUBSCRIBE before failing the operation. + * + * @param ackTimeoutSec + * + * @return this option object + */ + Mqtt5ClientOptions &WithAckTimeoutSeconds(uint32_t ackTimeoutSec) noexcept; + /** * Sets Operation Timeout(Seconds). Time interval to wait for an ack after sending a QoS 1+ PUBLISH, * SUBSCRIBE, or UNSUBSCRIBE before failing the operation. * - * @param ackTimeoutSeconds + * @param ackTimeoutSec * * @return this option object */ - Mqtt5ClientOptions &WithAckTimeoutSeconds(uint32_t ackTimeoutSeconds) noexcept; + Mqtt5ClientOptions &WithAckTimeoutSec(uint32_t ackTimeoutSec) noexcept; /** * Sets callback for transform HTTP request. diff --git a/include/aws/crt/mqtt/Mqtt5Packets.h b/include/aws/crt/mqtt/Mqtt5Packets.h index 7d127040d..b68f9a0a8 100644 --- a/include/aws/crt/mqtt/Mqtt5Packets.h +++ b/include/aws/crt/mqtt/Mqtt5Packets.h @@ -500,10 +500,18 @@ namespace Aws uint16_t getReceiveMaximumFromServer() const noexcept; /** + * @deprecated the function is deprecated, please use + * `NegotiatedSettings::getMaximumPacketSizeToServer()` + * * @return The maximum packet size the server is willing to accept. */ uint32_t getMaximumPacketSizeBytes() const noexcept; + /** + * @return The maximum packet size the server is willing to accept. + */ + uint32_t getMaximumPacketSizeToServer() const noexcept; + /** * @return returns the maximum allowed topic alias value on publishes sent from client to server */ @@ -521,6 +529,17 @@ namespace Aws * * @return The maximum amount of time in seconds between client packets. */ + uint16_t getServerKeepAliveSec() const noexcept; + + /** + * @deprecated The function is deprecated, please use `NegotiatedSettings::getServerKeepAliveSec()` + * + * The maximum amount of time in seconds between client packets. The client should use PINGREQs to + * ensure this limit is not breached. The server will disconnect the client for inactivity if no MQTT + * packet is received in a time interval equal to 1.5 x this value. + * + * @return The maximum amount of time in seconds between client packets. + */ uint16_t getServerKeepAlive() const noexcept; /** @@ -939,6 +958,8 @@ namespace Aws const Crt::Optional &getReceiveMaximum() const noexcept; /** + * @deprecated The function is deprecated, please use `ConnectPacket::getMaximumPacketSizeToServer()` + * * Notifies the server of the maximum packet size the client is willing to handle. If * omitted or null, then no limit beyond the natural limits of MQTT packet size is requested. * @@ -949,6 +970,17 @@ namespace Aws */ const Crt::Optional &getMaximumPacketSizeBytes() const noexcept; + /** + * Notifies the server of the maximum packet size the client is willing to handle. If + * omitted or null, then no limit beyond the natural limits of MQTT packet size is requested. + * + * See [MQTT5 Maximum Packet + * Size](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901050) + * + * @return The maximum packet size the client is willing to handle + */ + const Crt::Optional &getMaximumPacketSizeToServer() const noexcept; + /** * A time interval, in seconds, that the server should wait (for a session reconnection) before sending * the will message associated with the connection's session. If omitted or null, the server will send @@ -1175,6 +1207,20 @@ namespace Aws * @return A time interval, in seconds, that the server will persist this connection's MQTT session * state for. */ + const Crt::Optional &getSessionExpiryIntervalSec() const noexcept; + + /** + * @deprecated The function is deprecated, please use `ConnAckPacket::getSessionExpiryIntervalSec()`. + * + * A time interval, in seconds, that the server will persist this connection's MQTT session state + * for. If present, this value overrides any session expiry specified in the preceding CONNECT packet. + * + * See [MQTT5 Session Expiry + * Interval](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901082) + * + * @return A time interval, in seconds, that the server will persist this connection's MQTT session + * state for. + */ const Crt::Optional &getSessionExpiryInterval() const noexcept; /** @@ -1304,6 +1350,18 @@ namespace Aws * * @return Server-requested override of the keep alive interval, in seconds */ + const Crt::Optional &getServerKeepAliveSec() const noexcept; + + /** + * @deprecated The function is deprecated, please use `ConnAckPacket::getServerKeepAliveSec()`. + * Server-requested override of the keep alive interval, in seconds. If null, the keep alive value sent + * by the client should be used. + * + * See [MQTT5 Server Keep + * Alive](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901094) + * + * @return Server-requested override of the keep alive interval, in seconds + */ const Crt::Optional &getServerKeepAlive() const noexcept; /** @@ -1360,7 +1418,7 @@ namespace Aws * See [MQTT5 Session Expiry * Interval](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901082) */ - Crt::Optional m_sessionExpiryInterval; + Crt::Optional m_sessionExpiryIntervalSec; /** * The maximum amount of in-flight QoS 1 or 2 messages that the server is willing to handle at once. If @@ -1455,7 +1513,7 @@ namespace Aws * See [MQTT5 Server Keep * Alive](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901094) */ - Crt::Optional m_serverKeepAlive; + Crt::Optional m_serverKeepAliveSec; /** * A value that can be used in the creation of a response topic associated with this connection. @@ -1880,6 +1938,20 @@ namespace Aws * @param retain bool * @return The Subscription Object after setting the reason string. */ + Subscription &WithRetainAsPublished(bool retain) noexcept; + + /** + * @deprecated The function is deprecated, please use `Subscription::WithRetainAsPublished(bool)`. + * + * Sets should the server not send publishes to a client when that client was the one who sent the + * publish? The value will be default to false. + * + * See [MQTT5 Subscription + * Options](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901169) + * + * @param retain bool + * @return The Subscription Object after setting the reason string. + */ Subscription &WithRetain(bool retain) noexcept; /** @@ -1937,7 +2009,7 @@ namespace Aws * See [MQTT5 Subscription * Options](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901169) */ - bool m_retain; + bool m_retainAsPublished; /** * Should retained messages on matching topics be sent in reaction to this subscription? If undefined, diff --git a/include/aws/crt/mqtt/Mqtt5Types.h b/include/aws/crt/mqtt/Mqtt5Types.h index b7aa4f356..77cf1420d 100644 --- a/include/aws/crt/mqtt/Mqtt5Types.h +++ b/include/aws/crt/mqtt/Mqtt5Types.h @@ -17,6 +17,14 @@ namespace Aws * * Enum values match [MQTT5 * spec](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901234) encoding values. + * + * + * + * + * + * + *
Enumerator
AWS_MQTT5_QOS_AT_MOST_ONCEhttps://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901235
AWS_MQTT5_QOS_AT_LEAST_ONCEhttps://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901236
AWS_MQTT5_QOS_EXACTLY_ONCEhttps://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901237
+ * */ using QOS = aws_mqtt5_qos; @@ -25,6 +33,34 @@ namespace Aws * * Enum values match [MQTT5 * spec](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901079) encoding values. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Enumerator
AWS_MQTT5_CRC_SUCCESS0
AWS_MQTT5_CRC_UNSPECIFIED_ERROR128
AWS_MQTT5_CRC_MALFORMED_PACKET129
AWS_MQTT5_CRC_PROTOCOL_ERROR130
AWS_MQTT5_CRC_IMPLEMENTATION_SPECIFIC_ERROR131
AWS_MQTT5_CRC_UNSUPPORTED_PROTOCOL_VERSION132
AWS_MQTT5_CRC_CLIENT_IDENTIFIER_NOT_VALID133
AWS_MQTT5_CRC_BAD_USERNAME_OR_PASSWORD134
AWS_MQTT5_CRC_NOT_AUTHORIZED135
AWS_MQTT5_CRC_SERVER_UNAVAILABLE136
AWS_MQTT5_CRC_SERVER_BUSY137
AWS_MQTT5_CRC_BANNED138
AWS_MQTT5_CRC_BAD_AUTHENTICATION_METHOD140
AWS_MQTT5_CRC_TOPIC_NAME_INVALID144
AWS_MQTT5_CRC_PACKET_TOO_LARGE149
AWS_MQTT5_CRC_QUOTA_EXCEEDED151
AWS_MQTT5_CRC_PAYLOAD_FORMAT_INVALID153
AWS_MQTT5_CRC_RETAIN_NOT_SUPPORTED154
AWS_MQTT5_CRC_QOS_NOT_SUPPORTED155
AWS_MQTT5_CRC_USE_ANOTHER_SERVER156
AWS_MQTT5_CRC_SERVER_MOVED157
AWS_MQTT5_CRC_CONNECTION_RATE_EXCEEDED159
+ * + * */ using ConnectReasonCode = aws_mqtt5_connect_reason_code; @@ -33,6 +69,40 @@ namespace Aws * * Enum values match [MQTT5 * spec](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901208) encoding values. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Enumerator
AWS_MQTT5_DRC_NORMAL_DISCONNECTION0
AWS_MQTT5_DRC_DISCONNECT_WITH_WILL_MESSAGE4
AWS_MQTT5_DRC_UNSPECIFIED_ERROR128
AWS_MQTT5_DRC_MALFORMED_PACKET129
AWS_MQTT5_DRC_PROTOCOL_ERROR130
AWS_MQTT5_DRC_IMPLEMENTATION_SPECIFIC_ERROR131
AWS_MQTT5_DRC_NOT_AUTHORIZED135
AWS_MQTT5_DRC_SERVER_BUSY137
AWS_MQTT5_DRC_SERVER_SHUTTING_DOWN139
AWS_MQTT5_DRC_KEEP_ALIVE_TIMEOUT141
AWS_MQTT5_DRC_SESSION_TAKEN_OVER142
AWS_MQTT5_DRC_TOPIC_FILTER_INVALID143
AWS_MQTT5_DRC_TOPIC_NAME_INVALID144
AWS_MQTT5_DRC_RECEIVE_MAXIMUM_EXCEEDED147
AWS_MQTT5_DRC_TOPIC_ALIAS_INVALID148
AWS_MQTT5_DRC_PACKET_TOO_LARGE149
AWS_MQTT5_DRC_MESSAGE_RATE_TOO_HIGH150
AWS_MQTT5_DRC_QUOTA_EXCEEDED151
AWS_MQTT5_DRC_ADMINISTRATIVE_ACTION152
AWS_MQTT5_DRC_PAYLOAD_FORMAT_INVALID153
AWS_MQTT5_DRC_RETAIN_NOT_SUPPORTED154
AWS_MQTT5_DRC_QOS_NOT_SUPPORTED155
AWS_MQTT5_DRC_USE_ANOTHER_SERVER156
AWS_MQTT5_DRC_SERVER_MOVED157
AWS_MQTT5_DRC_SHARED_SUBSCRIPTIONS_NOT_SUPPORTED158
AWS_MQTT5_DRC_CONNECTION_RATE_EXCEEDED159
AWS_MQTT5_DRC_MAXIMUM_CONNECT_TIME160
AWS_MQTT5_DRC_SUBSCRIPTION_IDENTIFIERS_NOT_SUPPORTED161
AWS_MQTT5_DRC_WILDCARD_SUBSCRIPTIONS_NOT_SUPPORTED162
+ * */ using DisconnectReasonCode = aws_mqtt5_disconnect_reason_code; @@ -41,6 +111,18 @@ namespace Aws * * Data model of an [MQTT5 * PUBACK](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901121) packet + * + * + * + * + * + * + * + * + * + * + * + *
Enumerator
AWS_MQTT5_PARC_SUCCESS0
AWS_MQTT5_PARC_NO_MATCHING_SUBSCRIBERS16
AWS_MQTT5_PARC_UNSPECIFIED_ERROR128
AWS_MQTT5_PARC_IMPLEMENTATION_SPECIFIC_ERROR131
AWS_MQTT5_PARC_NOT_AUTHORIZED135
AWS_MQTT5_PARC_TOPIC_NAME_INVALID144
AWS_MQTT5_PARC_PACKET_IDENTIFIER_IN_USE145
AWS_MQTT5_PARC_QUOTA_EXCEEDED151
AWS_MQTT5_PARC_PAYLOAD_FORMAT_INVALID153
*/ using PubAckReasonCode = aws_mqtt5_puback_reason_code; @@ -49,6 +131,19 @@ namespace Aws * * Enum values match [MQTT5 * spec](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901124) encoding values. + * + * + * + * + * + * + * + * + * + * + * + * + *
Enumerator
AWS_MQTT5_PARC_SUCCESS0
AWS_MQTT5_PARC_NO_MATCHING_SUBSCRIBERS16
AWS_MQTT5_PARC_UNSPECIFIED_ERROR128
AWS_MQTT5_PARC_IMPLEMENTATION_SPECIFIC_ERROR131
AWS_MQTT5_PARC_NOT_AUTHORIZED135
AWS_MQTT5_PARC_TOPIC_NAME_INVALID144
AWS_MQTT5_PARC_PACKET_IDENTIFIER_IN_USE145
AWS_MQTT5_PARC_QUOTA_EXCEEDED151
AWS_MQTT5_PARC_PAYLOAD_FORMAT_INVALID153
*/ using SubAckReasonCode = aws_mqtt5_suback_reason_code; @@ -58,17 +153,49 @@ namespace Aws * * Enum values match [MQTT5 * spec](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901194) encoding values. + * + * + * + * + * + * + * + * + * + * + *
Enumerator
AWS_MQTT5_UARC_SUCCESS0
AWS_MQTT5_UARC_NO_SUBSCRIPTION_EXISTED17
AWS_MQTT5_UARC_UNSPECIFIED_ERROR128
AWS_MQTT5_UARC_IMPLEMENTATION_SPECIFIC_ERROR131
AWS_MQTT5_UARC_NOT_AUTHORIZED135
AWS_MQTT5_UARC_TOPIC_FILTER_INVALID143
AWS_MQTT5_UARC_PACKET_IDENTIFIER_IN_USE145
+ * */ using UnSubAckReasonCode = aws_mqtt5_unsuback_reason_code; /** * Controls how the MQTT5 client should behave with respect to MQTT sessions. + * + * + * + * + * + * + *
Enumerator
AWS_MQTT5_CSBT_DEFAULTMaps to AWS_MQTT5_CSBT_CLEAN
AWS_MQTT5_CSBT_CLEANAlways join a new, clean session
AWS_MQTT5_CSBT_REJOIN_POST_SUCCESSAlways attempt to rejoin an existing session after an + * initial connection success.
AWS_MQTT5_CSBT_REJOIN_ALWAYSAlways attempt to + * rejoin an existing session. Since the client does not support durable session persistence, this option is + * not guaranteed to be spec compliant because any unacknowledged qos1 publishes (which are part of the + * client session state) will not be present on the initial connection. Until we support durable session + * resumption, this option is technically spec-breaking, but useful.
*/ using ClientSessionBehaviorType = aws_mqtt5_client_session_behavior_type; /** * Additional controls for client behavior with respect to operation validation and flow control; these * checks go beyond the MQTT5 spec to respect limits of specific MQTT brokers. + * + * + * + *
Enumerator
AWS_MQTT5_EVAFCO_NONEDo not do any additional validation or flow control outside of the + * MQTT5 spec
AWS_MQTT5_EVAFCO_AWS_IOT_CORE_DEFAULTSApply additional client-side + * operational flow control that respects the default AWS IoT Core limits. Applies the following flow + * control: (1) Outbound throughput throttled to 512KB/s (2) Outbound publish TPS throttled to 100
+ * */ using ClientExtendedValidationAndFlowControl = aws_mqtt5_extended_validation_and_flow_control_options; @@ -77,6 +204,21 @@ namespace Aws * controls how operations are handled while the client is not connected. In particular, if the client is * not connected, then any operation that would be failed on disconnect (according to these rules) will be * rejected. + * + * + * + * + * + * + *
Enumerator
AWS_MQTT5_COQBT_DEFAULTMaps to AWS_MQTT5_COQBT_FAIL_QOS0_PUBLISH_ON_DISCONNECT
AWS_MQTT5_COQBT_FAIL_NON_QOS1_PUBLISH_ON_DISCONNECTRequeues QoS 1+ publishes on + * disconnect; unacked publishes go to the front, unprocessed publishes stay in place. All other operations + * (QoS 0 publishes, subscribe, unsubscribe) are failed.
AWS_MQTT5_COQBT_FAIL_QOS0_PUBLISH_ON_DISCONNECTQos 0 publishes that are not complete at + * the time of disconnection are failed. Unacked QoS 1+ publishes are requeued at the head of the line for + * immediate retransmission on a session resumption. All other operations are requeued in the original order + * behind any retransmissions.
AWS_MQTT5_COQBT_FAIL_ALL_ON_DISCONNECTAll + * operations that are not complete at the time of disconnection are failed, except those operations that + * the MQTT 5 spec requires to be retransmitted (unacked QoS 1+ publishes).
+ * */ using ClientOperationQueueBehaviorType = aws_mqtt5_client_operation_queue_behavior_type; @@ -86,14 +228,33 @@ namespace Aws * * See [Exponential Backoff and * Jitter](https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/) + * + * + * + * + * + *
Enumerator
AWS_EXPONENTIAL_BACKOFF_JITTER_DEFAULTUses AWS_EXPONENTIAL_BACKOFF_JITTER_FULL
AWS_EXPONENTIAL_BACKOFF_JITTER_NONENo jitter is applied to the exponential + * backoff
AWS_EXPONENTIAL_BACKOFF_JITTER_FULLFull jitter is applied to the + * exponential backoff
AWS_EXPONENTIAL_BACKOFF_JITTER_DECORRELATEDJitter is + * decorrelated from the backoff sequence
+ * */ - using JitterMode = aws_exponential_backoff_jitter_mode; + using ExponentialBackoffJitterMode = aws_exponential_backoff_jitter_mode; + + /** @deprecated JitterMode is deprecated, please use Aws::Crt::Mqtt5::ExponentialBackoffJitterMode */ + using JitterMode = ExponentialBackoffJitterMode; /** * Optional property describing a PUBLISH payload's format. * * Enum values match [MQTT5 * spec](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901111) encoding values. + * + * + * + * + * + *
Enumerator
AWS_MQTT5_PFI_BYTESBytes format.
AWS_MQTT5_PFI_UTF8UTF-8 format.
*/ using PayloadFormatIndicator = aws_mqtt5_payload_format_indicator; @@ -103,6 +264,16 @@ namespace Aws * * Enum values match [MQTT5 * spec](https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901169) encoding values. + * + * + * + * + * + *
Enumerator
AWS_MQTT5_RHT_SEND_ON_SUBSCRIBEServer should send all retained messages on topics that + * match the subscription's filter.
AWS_MQTT5_RHT_SEND_ON_SUBSCRIBE_IF_NEWServer + * should send all retained messages on topics that match the subscription's filter, where this is the first + * (relative to connection) subscription filter that matches the topic with a retained message.
AWS_MQTT5_RHT_DONT_SENDSubscribe must not trigger any retained message publishes from + * the server.
*/ using RetainHandlingType = aws_mqtt5_retain_handling_type; @@ -111,6 +282,28 @@ namespace Aws * Enum values match mqtt spec encoding values. * * https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901022 + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Enumerator
AWS_MQTT5_PT_NONEInternal indicator that the associated packet is null.
AWS_MQTT5_PT_RESERVEDReserved.
AWS_MQTT5_PT_CONNECTCONNECT packet.
AWS_MQTT5_PT_CONNACKCONNACK packet.
AWS_MQTT5_PT_PUBLISHPUBLISH packet.
AWS_MQTT5_PT_PUBACKPUBACK packet.
AWS_MQTT5_PT_PUBRECPUBREC packet.
AWS_MQTT5_PT_PUBRELPUBREL packet.
AWS_MQTT5_PT_PUBCOMPPUBCOMP packet.
AWS_MQTT5_PT_SUBSCRIBESUBSCRIBE packet.
AWS_MQTT5_PT_SUBACKSUBACK packet.
AWS_MQTT5_PT_UNSUBSCRIBEUNSUBSCRIBE packet.
AWS_MQTT5_PT_UNSUBACKUNSUBACK packet.
AWS_MQTT5_PT_PINGREQPINGREQ packet.
AWS_MQTT5_PT_PINGRESPPINGRESP packet.
AWS_MQTT5_PT_DISCONNECTDISCONNECT packet.
AWS_MQTT5_PT_AUTHAUTH packet.
+ * */ using PacketType = aws_mqtt5_packet_type; diff --git a/include/aws/iot/Mqtt5Client.h b/include/aws/iot/Mqtt5Client.h index 6581fc55d..7dacbbf32 100644 --- a/include/aws/iot/Mqtt5Client.h +++ b/include/aws/iot/Mqtt5Client.h @@ -413,11 +413,23 @@ namespace Aws * Sets Operation Timeout(Seconds). Time interval to wait for an ack after sending a QoS 1+ PUBLISH, * SUBSCRIBE, or UNSUBSCRIBE before failing the operation. * - * @param ackTimeoutSeconds + * @param ackTimeoutSec * * @return this option object */ - Mqtt5ClientBuilder &WithAckTimeoutSeconds(uint32_t ackTimeoutSeconds) noexcept; + Mqtt5ClientBuilder &WithAckTimeoutSec(uint32_t ackTimeoutSec) noexcept; + + /** + * @deprecated the function is deprecated, please use `Mqtt5ClientBuilder::WithAckTimeoutSec(uint32_t)` + * + * Sets Operation Timeout(Seconds). Time interval to wait for an ack after sending a QoS 1+ PUBLISH, + * SUBSCRIBE, or UNSUBSCRIBE before failing the operation. + * + * @param ackTimeoutSec + * + * @return this option object + */ + Mqtt5ClientBuilder &WithAckTimeoutSeconds(uint32_t ackTimeoutSec) noexcept; /** * Overrides the default SDK Name to send as a metric in the MQTT CONNECT packet. diff --git a/source/iot/Mqtt5Client.cpp b/source/iot/Mqtt5Client.cpp index f11cc548d..148282e4b 100644 --- a/source/iot/Mqtt5Client.cpp +++ b/source/iot/Mqtt5Client.cpp @@ -379,7 +379,7 @@ namespace Aws Mqtt5ClientBuilder &Mqtt5ClientBuilder::WithOfflineQueueBehavior( ClientOperationQueueBehaviorType operationQueueBehavior) noexcept { - m_options->WithAckTimeoutSeconds(operationQueueBehavior); + m_options->WithOfflineQueueBehavior(operationQueueBehavior); return *this; } @@ -408,12 +408,17 @@ namespace Aws return *this; } - Mqtt5ClientBuilder &Mqtt5ClientBuilder::WithAckTimeoutSeconds(uint32_t ackTimeoutSeconds) noexcept + Mqtt5ClientBuilder &Mqtt5ClientBuilder::WithAckTimeoutSec(uint32_t ackTimeoutSec) noexcept { - m_options->WithAckTimeoutSeconds(ackTimeoutSeconds); + m_options->WithAckTimeoutSec(ackTimeoutSec); return *this; } + Mqtt5ClientBuilder &Mqtt5ClientBuilder::WithAckTimeoutSeconds(uint32_t ackTimeoutSec) noexcept + { + return WithAckTimeoutSec(ackTimeoutSec); + } + Mqtt5ClientBuilder &Mqtt5ClientBuilder::WithSdkName(const Crt::String &sdkName) { m_sdkName = sdkName; diff --git a/source/mqtt/Mqtt5Client.cpp b/source/mqtt/Mqtt5Client.cpp index ebb3188ba..84fb5e09b 100644 --- a/source/mqtt/Mqtt5Client.cpp +++ b/source/mqtt/Mqtt5Client.cpp @@ -347,9 +347,14 @@ namespace Aws return *this; } - Mqtt5ClientOptions &Mqtt5ClientOptions::WithAckTimeoutSeconds(uint32_t ackTimeoutSeconds) noexcept + Mqtt5ClientOptions &Mqtt5ClientOptions::WithAckTimeoutSeconds(uint32_t ackTimeoutSec) noexcept { - m_ackTimeoutSec = ackTimeoutSeconds; + return WithAckTimeoutSec(ackTimeoutSec); + } + + Mqtt5ClientOptions &Mqtt5ClientOptions::WithAckTimeoutSec(uint32_t ackTimeoutSec) noexcept + { + m_ackTimeoutSec = ackTimeoutSec; return *this; } diff --git a/source/mqtt/Mqtt5Packets.cpp b/source/mqtt/Mqtt5Packets.cpp index aa2b93705..b9300e956 100644 --- a/source/mqtt/Mqtt5Packets.cpp +++ b/source/mqtt/Mqtt5Packets.cpp @@ -390,6 +390,11 @@ namespace Aws } const Crt::Optional &ConnectPacket::getMaximumPacketSizeBytes() const noexcept + { + return getMaximumPacketSizeToServer(); + } + + const Crt::Optional &ConnectPacket::getMaximumPacketSizeToServer() const noexcept { return m_maximumPacketSizeBytes; } @@ -808,7 +813,7 @@ namespace Aws { m_sessionPresent = packet.session_present; m_reasonCode = packet.reason_code; - setPacketOptional(m_sessionExpiryInterval, packet.session_expiry_interval); + setPacketOptional(m_sessionExpiryIntervalSec, packet.session_expiry_interval); setPacketOptional(m_receiveMaximum, packet.receive_maximum); setPacketOptional(m_maximumQOS, packet.maximum_qos); setPacketOptional(m_retainAvailable, packet.retain_available); @@ -820,7 +825,7 @@ namespace Aws setPacketOptional(m_wildcardSubscriptionsAvailable, packet.wildcard_subscriptions_available); setPacketOptional(m_subscriptionIdentifiersAvailable, packet.subscription_identifiers_available); setPacketOptional(m_sharedSubscriptionsAvailable, packet.shared_subscriptions_available); - setPacketOptional(m_serverKeepAlive, packet.server_keep_alive); + setPacketOptional(m_serverKeepAliveSec, packet.server_keep_alive); setPacketStringOptional(m_responseInformation, packet.response_information); setPacketStringOptional(m_serverReference, packet.server_reference); } @@ -829,9 +834,14 @@ namespace Aws ConnectReasonCode ConnAckPacket::getReasonCode() const noexcept { return m_reasonCode; } + const Crt::Optional &ConnAckPacket::getSessionExpiryIntervalSec() const noexcept + { + return m_sessionExpiryIntervalSec; + } + const Crt::Optional &ConnAckPacket::getSessionExpiryInterval() const noexcept { - return m_sessionExpiryInterval; + return getSessionExpiryIntervalSec(); } const Crt::Optional &ConnAckPacket::getReceiveMaximum() const noexcept @@ -877,9 +887,14 @@ namespace Aws return m_sharedSubscriptionsAvailable; } + const Crt::Optional &ConnAckPacket::getServerKeepAliveSec() const noexcept + { + return m_serverKeepAliveSec; + } + const Crt::Optional &ConnAckPacket::getServerKeepAlive() const noexcept { - return m_serverKeepAlive; + return getServerKeepAliveSec(); } const Crt::Optional &ConnAckPacket::getResponseInformation() const noexcept @@ -894,14 +909,14 @@ namespace Aws Subscription::Subscription(Allocator *allocator) : m_allocator(allocator), m_topicFilter(""), m_qos(QOS::AWS_MQTT5_QOS_AT_MOST_ONCE), m_noLocal(false), - m_retain(false), m_retainHnadlingType(AWS_MQTT5_RHT_SEND_ON_SUBSCRIBE) + m_retainAsPublished(false), m_retainHnadlingType(AWS_MQTT5_RHT_SEND_ON_SUBSCRIBE) { } Subscription::Subscription(Crt::String topicFilter, Mqtt5::QOS qos, Allocator *allocator) : m_allocator(allocator), m_topicFilter(std::move(topicFilter)), m_qos(qos), m_noLocal(false), - m_retain(false), m_retainHnadlingType(AWS_MQTT5_RHT_SEND_ON_SUBSCRIBE) + m_retainAsPublished(false), m_retainHnadlingType(AWS_MQTT5_RHT_SEND_ON_SUBSCRIBE) { } @@ -921,9 +936,10 @@ namespace Aws m_noLocal = noLocal; return *this; } - Subscription &Subscription::WithRetain(bool retain) noexcept + Subscription &Subscription::WithRetain(bool retain) noexcept { return WithRetainAsPublished(retain); } + Subscription &Subscription::WithRetainAsPublished(bool retain) noexcept { - m_retain = retain; + m_retainAsPublished = retain; return *this; } Subscription &Subscription::WithRetainHandlingType(RetainHandlingType retainHandlingType) noexcept @@ -938,21 +954,21 @@ namespace Aws raw_options.topic_filter = ByteCursorFromString(m_topicFilter); raw_options.no_local = m_noLocal; raw_options.qos = m_qos; - raw_options.retain_as_published = m_retain; + raw_options.retain_as_published = m_retainAsPublished; raw_options.retain_handling_type = m_retainHnadlingType; return true; } Subscription::Subscription(const Subscription &toCopy) noexcept : m_allocator(toCopy.m_allocator), m_topicFilter(toCopy.m_topicFilter), m_qos(toCopy.m_qos), - m_noLocal(toCopy.m_noLocal), m_retain(toCopy.m_retain), + m_noLocal(toCopy.m_noLocal), m_retainAsPublished(toCopy.m_retainAsPublished), m_retainHnadlingType(toCopy.m_retainHnadlingType) { } Subscription::Subscription(Subscription &&toMove) noexcept : m_allocator(toMove.m_allocator), m_topicFilter(std::move(toMove.m_topicFilter)), m_qos(toMove.m_qos), - m_noLocal(toMove.m_noLocal), m_retain(toMove.m_retain), + m_noLocal(toMove.m_noLocal), m_retainAsPublished(toMove.m_retainAsPublished), m_retainHnadlingType(toMove.m_retainHnadlingType) { } @@ -965,7 +981,7 @@ namespace Aws m_qos = toCopy.m_qos; m_topicFilter = toCopy.m_topicFilter; m_noLocal = toCopy.m_noLocal; - m_retain = toCopy.m_retain; + m_retainAsPublished = toCopy.m_retainAsPublished; m_retainHnadlingType = toCopy.m_retainHnadlingType; } return *this; @@ -979,7 +995,7 @@ namespace Aws m_qos = toMove.m_qos; m_topicFilter = std::move(toMove.m_topicFilter); m_noLocal = toMove.m_noLocal; - m_retain = toMove.m_retain; + m_retainAsPublished = toMove.m_retainAsPublished; m_retainHnadlingType = toMove.m_retainHnadlingType; } return *this; @@ -1213,7 +1229,15 @@ namespace Aws return m_receiveMaximumFromServer; } - uint32_t NegotiatedSettings::getMaximumPacketSizeBytes() const noexcept { return m_maximumPacketSizeBytes; } + uint32_t NegotiatedSettings::getMaximumPacketSizeBytes() const noexcept + { + return getMaximumPacketSizeToServer(); + } + + uint32_t NegotiatedSettings::getMaximumPacketSizeToServer() const noexcept + { + return m_maximumPacketSizeBytes; + } uint16_t NegotiatedSettings::getTopicAliasMaximumToServer() const noexcept { @@ -1225,7 +1249,9 @@ namespace Aws return m_topicAliasMaximumToClient; } - uint16_t NegotiatedSettings::getServerKeepAlive() const noexcept { return m_serverKeepAliveSec; } + uint16_t NegotiatedSettings::getServerKeepAliveSec() const noexcept { return m_serverKeepAliveSec; } + + uint16_t NegotiatedSettings::getServerKeepAlive() const noexcept { return getServerKeepAliveSec(); } bool NegotiatedSettings::getRetainAvailable() const noexcept { return m_retainAvailable; } diff --git a/tests/Mqtt5ClientTest.cpp b/tests/Mqtt5ClientTest.cpp index 0d3ae46fd..e398e1478 100644 --- a/tests/Mqtt5ClientTest.cpp +++ b/tests/Mqtt5ClientTest.cpp @@ -121,7 +121,7 @@ static int s_TestMqtt5NewClientFull(Aws::Crt::Allocator *allocator, void *) mqtt5Options.WithReconnectOptions(reconnectOptions); mqtt5Options.WithPingTimeoutMs(1000); mqtt5Options.WithConnackTimeoutMs(100); - mqtt5Options.WithAckTimeoutSeconds(1000); + mqtt5Options.WithAckTimeoutSec(1000); std::promise connectionPromise; std::promise stoppedPromise; @@ -747,7 +747,7 @@ static int s_TestMqtt5DirectConnectionFull(Aws::Crt::Allocator *allocator, void mqtt5Options.WithReconnectOptions(reconnectOptions); mqtt5Options.WithPingTimeoutMs(1000); mqtt5Options.WithConnackTimeoutMs(100); - mqtt5Options.WithAckTimeoutSeconds(1000); + mqtt5Options.WithAckTimeoutSec(1000); std::promise connectionPromise; std::promise stoppedPromise; @@ -1160,7 +1160,7 @@ static int s_TestMqtt5WSConnectionFull(Aws::Crt::Allocator *allocator, void *) mqtt5Options.WithReconnectOptions(reconnectOptions); mqtt5Options.WithPingTimeoutMs(1000); mqtt5Options.WithConnackTimeoutMs(100); - mqtt5Options.WithAckTimeoutSeconds(1000); + mqtt5Options.WithAckTimeoutSec(1000); std::promise connectionPromise; std::promise stoppedPromise; @@ -1624,7 +1624,7 @@ static int s_TestMqtt5NegotiatedSettingsFull(Aws::Crt::Allocator *allocator, voi std::shared_ptr settings = eventData.negotiatedSettings; ASSERT_TRUE(settings->getSessionExpiryIntervalSec() == SESSION_EXPIRY_INTERVAL_SEC); ASSERT_TRUE(settings->getClientId() == CLIENT_ID); - ASSERT_TRUE(settings->getServerKeepAlive() == KEEP_ALIVE_INTERVAL); + ASSERT_TRUE(settings->getServerKeepAliveSec() == KEEP_ALIVE_INTERVAL); connectionPromise.set_value(true); return 0; }); @@ -1678,7 +1678,7 @@ static int s_TestMqtt5NegotiatedSettingsLimit(Aws::Crt::Allocator *allocator, vo mqtt5Options.WithClientConnectionSuccessCallback([&](const OnConnectionSuccessEventData &eventData) { std::shared_ptr settings = eventData.negotiatedSettings; uint16_t receivedmax = settings->getReceiveMaximumFromServer(); - uint32_t max_package = settings->getMaximumPacketSizeBytes(); + uint32_t max_package = settings->getMaximumPacketSizeToServer(); ASSERT_FALSE(receivedmax == RECEIVE_MAX); ASSERT_FALSE(max_package == PACKET_MAX); ASSERT_FALSE(settings->getRejoinedSession()); @@ -2648,7 +2648,7 @@ static int s_TestMqtt5to3AdapterNewClientFull(Aws::Crt::Allocator *allocator, vo mqtt5Options.WithReconnectOptions(reconnectOptions); mqtt5Options.WithPingTimeoutMs(1000); mqtt5Options.WithConnackTimeoutMs(100); - mqtt5Options.WithAckTimeoutSeconds(1000); + mqtt5Options.WithAckTimeoutSec(1000); std::promise connectionPromise; std::promise stoppedPromise;