[mqtt-client] reason codes & properties documented

Summary: related to T12804

Reviewers: ivica

Reviewed By: ivica

Subscribers: miljen

Differential Revision: https://repo.mireo.local/D26113
This commit is contained in:
Korina Šimičević
2023-10-16 15:57:26 +02:00
parent 296e28da93
commit 22f1330fed
15 changed files with 497 additions and 268 deletions

View File

@@ -14,11 +14,11 @@ namespace async_mqtt5 {
* in the DISCONNECT packet as the reason for the disconnection.
*/
enum class disconnect_rc_e : std::uint8_t {
/// Close the connection normally. Do not send the \ref will Message.
/** Close the connection normally. Do not send the \ref will Message. */
normal_disconnection = 0x00,
/// The Client wishes to disconnect but requires that
/// the Server also publishes its \ref will Message.
/** The Client wishes to disconnect but requires that
the Server also publishes its \ref will Message. */
disconnect_with_will_message = 0x04,
// TODO: these reason codes should not be available to the user, only the client
@@ -43,29 +43,29 @@ namespace client {
* \details Represents error that occur on the client side.
*/
enum class error : int {
/// [unused] A fatal error occurred.
/** [unused] A fatal error occurred. */
fatal_error = 100,
/// Malformed packet has been detected.
/** Malformed packet has been detected. */
malformed_packet,
/// There are no more available Packet Identifiers to use.
/** There are no more available Packet Identifiers to use. */
pid_overrun,
/// [unused] The Client has reconnected.
/** [unused] The Client has reconnected. */
reconnected,
/// The Client has been disconnected.
/** The Client has been disconnected. */
disconnected,
// publish
/// The Server does not support the specified \ref qos_e.
/** The Server does not support the specified \ref qos_e. */
qos_not_supported,
/// The Server dos not support retained messages.
/** The Server dos not support retained messages. */
retain_not_available,
/// The Client attempted to send a Topic Alias that is greater than Topic Alias Maximum.
/** The Client attempted to send a Topic Alias that is greater than Topic Alias Maximum. */
topic_alias_maximum_reached
};
@@ -199,14 +199,15 @@ public:
if (_category == suback)
return "The subscription is accepted with maximum QoS sent at 0";
if (_category == disconnect)
return "Close the connection normally";
return "Close the connection normally. Do not send the Will Message";
return "The operation completed successfully";
case 0x01:
return "The subscription is accepted with maximum QoS sent at 1";
case 0x02:
return "The subscription is accepted with maximum QoS sent at 2";
case 0x04:
return "The Client wishes to disconnect with the Will Message";
return "The Client wishes to disconnect but requires"
"that the Server also publishes its Will Message";
case 0x10:
return "The message is accepted but there are no subscribers";
case 0x11:
@@ -216,7 +217,8 @@ public:
case 0x19:
return "Initiate a re-authentication";
case 0x80:
return "Unspecified error occurred";
return "The Server does not wish to reveal the reason for the"
"failure, or none of the other Reason Codes apply";
case 0x81:
return "Data within the packet could not be correctly parsed";
case 0x82:
@@ -249,7 +251,7 @@ public:
return "Another Connection using the same ClientID has connected "
"causing this Connection to be closed";
case 0x8f:
return "The Topic Name is not malformed, but it is not accepted";
return "The Topic Filer is not malformed, but it is not accepted";
case 0x90:
return "The Topic Name is not malformed, but it is not accepted";
case 0x91:
@@ -295,7 +297,7 @@ public:
case 0xff:
return "No reason code";
default:
return "Invalid reason code.";
return "Invalid reason code";
}
}
};
@@ -303,54 +305,153 @@ public:
namespace reason_codes {
using enum category;
/** No Reason Code. A \ref client::error occurred.*/
constexpr reason_code empty {};
constexpr reason_code success { 0x00 };
constexpr reason_code normal_disconnection { 0x00, disconnect };
constexpr reason_code granted_qos_0 { 0x00, suback };
constexpr reason_code granted_qos_1 { 0x01 };
constexpr reason_code granted_qos_2 { 0x02 };
constexpr reason_code disconnect_with_will_message { 0x04 };
constexpr reason_code no_matching_subscribers { 0x10 };
constexpr reason_code no_subscription_existed { 0x11 };
constexpr reason_code continue_authentication { 0x18 };
constexpr reason_code reauthenticate { 0x19 };
/** The operation completed successfully. */
constexpr reason_code success{ 0x00 };
constexpr reason_code unspecified_error { 0x80 };
constexpr reason_code malformed_packet { 0x81 };
constexpr reason_code protocol_error { 0x82 };
constexpr reason_code implementation_specific_error { 0x83 };
constexpr reason_code unsupported_protocol_version { 0x84 };
constexpr reason_code client_id_not_valid { 0x85 };
constexpr reason_code bad_username_or_password { 0x86 };
constexpr reason_code not_authorized { 0x87 };
constexpr reason_code server_unavailable { 0x88 };
constexpr reason_code server_busy { 0x89 };
constexpr reason_code banned { 0x8a };
constexpr reason_code server_shutting_down { 0x8b };
constexpr reason_code bad_authentication_method { 0x8c };
constexpr reason_code keep_alive_timeout { 0x8d };
constexpr reason_code session_taken_over { 0x8e };
constexpr reason_code topic_filter_invalid { 0x8f };
constexpr reason_code topic_name_invalid { 0x90 };
constexpr reason_code packet_id_in_use { 0x91 };
constexpr reason_code packet_id_not_found { 0x92 };
constexpr reason_code receive_maximum_exceeded { 0x93 };
constexpr reason_code topic_alias_invalid { 0x94 };
constexpr reason_code packet_too_large { 0x95 };
constexpr reason_code message_rate_too_high { 0x96 };
constexpr reason_code quota_exceeded { 0x97 };
constexpr reason_code administrative_action { 0x98 };
constexpr reason_code payload_format_invalid { 0x99 };
constexpr reason_code retain_not_supported { 0x9a };
constexpr reason_code qos_not_supported { 0x9b };
constexpr reason_code use_another_server { 0x9c };
constexpr reason_code server_moved { 0x9d };
constexpr reason_code shared_subscriptions_not_supported { 0x9e };
constexpr reason_code connection_rate_exceeded { 0x9f };
constexpr reason_code maximum_connect_time { 0xa0 };
constexpr reason_code subscription_ids_not_supported { 0xa1 };
constexpr reason_code wildcard_subscriptions_not_supported { 0xa2 };
/** Close the connection normally. Do not send the Will Message. */
constexpr reason_code normal_disconnection{ 0x00, disconnect };
/** The subscription is accepted with maximum QoS sent at 0. */
constexpr reason_code granted_qos_0{ 0x00, suback };
/** The subscription is accepted with maximum QoS sent at 1. */
constexpr reason_code granted_qos_1{ 0x01 };
/** The subscription is accepted with maximum QoS sent at 2 */
constexpr reason_code granted_qos_2{ 0x02 };
/** The Client wishes to disconnect but requires that
the Server also publishes its Will Message. */
constexpr reason_code disconnect_with_will_message{ 0x04 };
/** The message is accepted but there are no subscribers. */
constexpr reason_code no_matching_subscribers{ 0x10 };
/** No matching Topic Filter is being used by the Client. */
constexpr reason_code no_subscription_existed{ 0x11 };
/** Continue the authentication with another step. */
constexpr reason_code continue_authentication{ 0x18 };
/** Initiate a re-authentication. */
constexpr reason_code reauthenticate{ 0x19 };
/** The Server does not wish to reveal the reason for the
failure, or none of the other Reason Codes apply. */
constexpr reason_code unspecified_error{ 0x80 };
/** Data within the packet could not be correctly parsed. */
constexpr reason_code malformed_packet{ 0x81 };
/** Data in the packet does not conform to this specification. */
constexpr reason_code protocol_error{ 0x82 };
/** The packet is valid but not accepted by this Server. */
constexpr reason_code implementation_specific_error{ 0x83 };
/** The Server does not support the requested version of the MQTT protocol. */
constexpr reason_code unsupported_protocol_version{ 0x84 };
/** The Client ID is valid but not allowed by this Server. */
constexpr reason_code client_id_not_valid{ 0x85 };
/** The Server does not accept the User Name or Password provided. */
constexpr reason_code bad_username_or_password{ 0x86 };
/** The request is not authorized. */
constexpr reason_code not_authorized{ 0x87 };
/** The MQTT Server is not available. */
constexpr reason_code server_unavailable{ 0x88 };
/** The MQTT Server is busy, try again later. */
constexpr reason_code server_busy{ 0x89 };
/** The Client has been banned by administrative action. */
constexpr reason_code banned{ 0x8a };
/** The Server is shutting down. */
constexpr reason_code server_shutting_down{ 0x8b };
/** The authentication method is not supported or
does not match the method currently in use. */
constexpr reason_code bad_authentication_method{ 0x8c };
/** No packet has been received for 1.5 times the Keepalive time. */
constexpr reason_code keep_alive_timeout{ 0x8d };
/** Another Connection using the same ClientID has connected
causing this Connection to be closed. */
constexpr reason_code session_taken_over{ 0x8e };
/** The Topic Filter is not malformed, but it is not accepted. */
constexpr reason_code topic_filter_invalid{ 0x8f };
/** The Topic Name is not malformed, but it is not accepted. */
constexpr reason_code topic_name_invalid{ 0x90 };
/** The Packet Identifier is already in use. */
constexpr reason_code packet_id_in_use{ 0x91 };
/** The Packet Identifier is not known. */
constexpr reason_code packet_id_not_found{ 0x92 };
/** The Client or Server has received more than Receive
Maximum publication for which it has not sent PUBACK or PUBCOMP. */
constexpr reason_code receive_maximum_exceeded{ 0x93 };
/** The Client or Server received a PUBLISH packet containing
a Topic Alias greater than the Maximum Topic Alias. */
constexpr reason_code topic_alias_invalid{ 0x94 };
/** The packet exceeded the maximum permissible size. */
constexpr reason_code packet_too_large{ 0x95 };
/** The received data rate is too high. */
constexpr reason_code message_rate_too_high{ 0x96 };
/** An implementation or administrative imposed limit has been exceeded. */
constexpr reason_code quota_exceeded{ 0x97 };
/** The Connection is closed due to an administrative action. */
constexpr reason_code administrative_action{ 0x98 };
/** The Payload does not match the specified Payload Format Indicator. */
constexpr reason_code payload_format_invalid{ 0x99 };
/** The Server does not support retained messages. */
constexpr reason_code retain_not_supported{ 0x9a };
/** The Server does not support the QoS the Client specified or
it is greater than the Maximum QoS specified. */
constexpr reason_code qos_not_supported{ 0x9b };
/** The Client should temporarily use another server. */
constexpr reason_code use_another_server{ 0x9c };
/** The Client should permanently use another server. */
constexpr reason_code server_moved{ 0x9d };
/** The Server does not support Shared Subscriptions for this Client. */
constexpr reason_code shared_subscriptions_not_supported{ 0x9e };
/** The connection rate limit has been exceeded. */
constexpr reason_code connection_rate_exceeded{ 0x9f };
/** The maximum connection time authorized for this
connection has been exceeded. */
constexpr reason_code maximum_connect_time{ 0xa0 };
/** The Server does not support Subscription Identifiers. */
constexpr reason_code subscription_ids_not_supported{ 0xa1 };
/** The Server does not support Wildcard Subscriptions. */
constexpr reason_code wildcard_subscriptions_not_supported{ 0xa2 };
namespace detail {

View File

@@ -126,7 +126,8 @@ public:
/**
* \brief Cancel all asynchronous operations.
*
* \details All outstanding operations will complete with `boost::asio::error::operation_aborted`.
* \details All outstanding operations will complete
* with `boost::asio::error::operation_aborted`.
*/
void cancel() {
get_executor().execute([svc_ptr = _svc_ptr]() {
@@ -137,7 +138,9 @@ public:
/**
* \brief Assign a \ref will Message.
*
* \details The \ref will Message that will be published after the Network Connection is closed.
* \details The \ref will Message that the Broker should publish
* after the Network Connection is closed and it is not
* closed normally.
*/
mqtt_client& will(will will) {
_svc_ptr->will(std::move(will));
@@ -324,7 +327,7 @@ public:
* to Topics that the Client subscribed to. The PUBLISH packets can be received
* with \ref mqtt_client::async_receive function.
*
* \param topic \ref subscribe_topic of interest.
* \param topic A \ref subscribe_topic of interest.
* \param props SUBSCRIBE properties.
* \param token Completion token that will be used to produce a
* completion handler, which will be called when the operation completed.
@@ -519,7 +522,8 @@ public:
* \par Error codes
* The list of all possible error codes that this operation can finish with:\n
* - `boost::system::errc::errc_t::success`\n
* - `boost::asio::error::try_again` -- why?
* - `boost::asio::operation_aborted`\n
* - `boost::asio::no_recovery`\n
*/
template <typename CompletionToken>
decltype(auto) async_disconnect(
@@ -555,7 +559,8 @@ public:
* \par Error codes
* The list of all possible error codes that this operation can finish with:\n
* - `boost::system::errc::errc_t::success`\n
* - `boost::asio::error::try_again` -- why?
* - `boost::asio::operation_aborted`\n
* - `boost::asio::no_recovery`\n
*/
template <typename CompletionToken>
decltype(auto) async_disconnect(CompletionToken&& token) {

View File

@@ -9,33 +9,33 @@
namespace async_mqtt5::prop {
constexpr std::integral_constant<uint8_t, 0x01> payload_format_indicator{};
constexpr std::integral_constant<uint8_t, 0x02> message_expiry_interval{};
constexpr std::integral_constant<uint8_t, 0x03> content_type{};
constexpr std::integral_constant<uint8_t, 0x08> response_topic{};
constexpr std::integral_constant<uint8_t, 0x09> correlation_data{};
constexpr std::integral_constant<uint8_t, 0x0b> subscription_identifier{};
constexpr std::integral_constant<uint8_t, 0x11> session_expiry_interval{};
constexpr std::integral_constant<uint8_t, 0x12> assigned_client_identifier{};
constexpr std::integral_constant<uint8_t, 0x13> server_keep_alive{};
constexpr std::integral_constant<uint8_t, 0x15> authentication_method{};
constexpr std::integral_constant<uint8_t, 0x16> authentication_data{};
constexpr std::integral_constant<uint8_t, 0x17> request_problem_information{};
constexpr std::integral_constant<uint8_t, 0x18> will_delay_interval{};
constexpr std::integral_constant<uint8_t, 0x19> request_response_information{};
constexpr std::integral_constant<uint8_t, 0x1a> response_information{};
constexpr std::integral_constant<uint8_t, 0x1c> server_reference{};
constexpr std::integral_constant<uint8_t, 0x1f> reason_string{};
constexpr std::integral_constant<uint8_t, 0x21> receive_maximum{};
constexpr std::integral_constant<uint8_t, 0x22> topic_alias_maximum{};
constexpr std::integral_constant<uint8_t, 0x23> topic_alias{};
constexpr std::integral_constant<uint8_t, 0x24> maximum_qos{};
constexpr std::integral_constant<uint8_t, 0x25> retain_available{};
constexpr std::integral_constant<uint8_t, 0x26> user_property{};
constexpr std::integral_constant<uint8_t, 0x27> maximum_packet_size{};
constexpr std::integral_constant<uint8_t, 0x28> wildcard_subscription_available{};
constexpr std::integral_constant<uint8_t, 0x29> subscription_identifier_available{};
constexpr std::integral_constant<uint8_t, 0x2a> shared_subscription_available{};
constexpr std::integral_constant<uint8_t, 0x01> payload_format_indicator {};
constexpr std::integral_constant<uint8_t, 0x02> message_expiry_interval {};
constexpr std::integral_constant<uint8_t, 0x03> content_type {};
constexpr std::integral_constant<uint8_t, 0x08> response_topic {};
constexpr std::integral_constant<uint8_t, 0x09> correlation_data {};
constexpr std::integral_constant<uint8_t, 0x0b> subscription_identifier {};
constexpr std::integral_constant<uint8_t, 0x11> session_expiry_interval {};
constexpr std::integral_constant<uint8_t, 0x12> assigned_client_identifier {};
constexpr std::integral_constant<uint8_t, 0x13> server_keep_alive {};
constexpr std::integral_constant<uint8_t, 0x15> authentication_method {};
constexpr std::integral_constant<uint8_t, 0x16> authentication_data {};
constexpr std::integral_constant<uint8_t, 0x17> request_problem_information {};
constexpr std::integral_constant<uint8_t, 0x18> will_delay_interval {};
constexpr std::integral_constant<uint8_t, 0x19> request_response_information {};
constexpr std::integral_constant<uint8_t, 0x1a> response_information {};
constexpr std::integral_constant<uint8_t, 0x1c> server_reference {};
constexpr std::integral_constant<uint8_t, 0x1f> reason_string {};
constexpr std::integral_constant<uint8_t, 0x21> receive_maximum {};
constexpr std::integral_constant<uint8_t, 0x22> topic_alias_maximum {};
constexpr std::integral_constant<uint8_t, 0x23> topic_alias {};
constexpr std::integral_constant<uint8_t, 0x24> maximum_qos {};
constexpr std::integral_constant<uint8_t, 0x25> retain_available {};
constexpr std::integral_constant<uint8_t, 0x26> user_property {};
constexpr std::integral_constant<uint8_t, 0x27> maximum_packet_size {};
constexpr std::integral_constant<uint8_t, 0x28> wildcard_subscription_available {};
constexpr std::integral_constant<uint8_t, 0x29> subscription_identifier_available {};
constexpr std::integral_constant<uint8_t, 0x2a> shared_subscription_available {};
template <std::integral_constant p>
struct property_traits;

View File

@@ -6,12 +6,11 @@
#include <boost/system/error_code.hpp>
#include <async_mqtt5/error.hpp>
#include <async_mqtt5/property_types.hpp>
namespace async_mqtt5 {
/// An alias for `boost::system::error_code`;
/** An alias for `boost::system::error_code`; */
using error_code = boost::system::error_code;
struct authority_path {
@@ -25,14 +24,14 @@ struct authority_path {
* to the receiver.
*/
enum class qos_e : std::uint8_t {
/// The message arrives at the receiver either once or not at all.
/** The message arrives at the receiver either once or not at all. */
at_most_once = 0b00,
/// Ensures the message arrives at the receiver at least once.
/** Ensures the message arrives at the receiver at least once. */
at_least_once = 0b01,
/// All messages arrive at the receiver exactly once without
/// loss or duplication of the messages.
/** All messages arrive at the receiver exactly once without
loss or duplication of the messages. */
exactly_once = 0b10
};
@@ -43,16 +42,16 @@ enum class qos_e : std::uint8_t {
* store the current message.
*/
enum class retain_e : std::uint8_t {
/// The Server will replace any existing retained message for this Topic
/// with this message.
/** The Server will replace any existing retained message for this Topic
with this message. */
yes = 0b1,
/// The Server will not store this message and will not remove or replace
/// any existing retained message.
/** The Server will not store this message and will not remove or replace
any existing retained message. */
no = 0b0
};
// TODO: should this be moved to internal types?
enum class dup_e : std::uint8_t {
yes = 0b1, no = 0b0
};
@@ -62,7 +61,9 @@ enum class dup_e : std::uint8_t {
* \brief Represents the Options associated with each Subscription.
*/
struct subscribe_options {
/**
*
* \brief Representation of the No Local Subscribe Option.
*
* \details A Subscribe Option indicating whether or not Application Messages
@@ -70,10 +71,10 @@ struct subscribe_options {
* publishing connection.
*/
enum class no_local_e : std::uint8_t {
/// Application Messages can be forwarded to a connection with equal ClientID.
/** Application Messages can be forwarded to a connection with equal ClientID. */
no = 0b0,
/// Application Messages MUST NOT be forwarded to a connection with equal ClientID.
/** Application Messages MUST NOT be forwarded to a connection with equal ClientID. */
yes = 0b1
};
@@ -84,10 +85,10 @@ struct subscribe_options {
* using this subscription keep the \ref retain_e flag they were published with.
*/
enum class retain_as_published_e : std::uint8_t {
/// Application Messages have the \ref retain_e flag set to 0.
/** Application Messages have the \ref retain_e flag set to 0. */
dont = 0b0,
/// Application Messages keep the \ref retain_e flag they were published with.
/** Application Messages keep the \ref retain_e flag they were published with. */
retain = 0b1
};
@@ -98,17 +99,16 @@ struct subscribe_options {
* when the subscription is established.
*/
enum class retain_handling_e : std::uint8_t {
/// Send retained messages at the time of subscribe.
/** Send retained messages at the time of subscribe. */
send = 0b00,
/// Send retained message only if the subscription does not currently exist.
/** Send retained message only if the subscription does not currently exist. */
new_subscription_only = 0b01,
/// Do not send retained messages at the time of subscribe.
not_send = 0b10
/** Do not send retained messages at the time of subscribe. */
not_send = 0b100
};
//TODO: figure out how to properly link qos_e to link to its page
/// Maximum \ref qos_e level at which the Server can send Application Messages to the Client.
qos_e max_qos = qos_e::exactly_once;
@@ -131,7 +131,7 @@ struct subscribe_topic {
/// An UTF-8 Encoded String indicating the Topics to which the Client wants to subscribe.
std::string topic_filter;
/// \ref subscribe_options associated with the subscription.
/// The \ref subscribe_options associated with the subscription.
subscribe_options sub_opts;
};
@@ -295,14 +295,35 @@ class will_props : public prop::properties<
prop::user_property
>{};
/**
* \brief Represents the Will Message.
*
* \details A Will Message is an Application Message that
* the Broker should publish after the Network Connection is closed
* in cases where the Network Connection is not closed normally.
*/
class will : public will_props {
std::string _topic;
std::string _message;
qos_e _qos; retain_e _retain;
public:
/**
* \brief Constructs an empty Will Message.
*/
will() = default;
/**
* \brief Construct a Will Message.
*
* \param topic Topic, identification of the information channel to which
* the Will Message will be published.
* \param message The message that will be published.
* \param qos The \ref qos_e level used when publishing the Will Message.
* \param retain The \ref retain_e flag specifying if the Will Message
* is to be retained when it is published.
*/
will(
std::string topic, std::string message,
qos_e qos = qos_e::at_most_once, retain_e retain = retain_e::no
@@ -311,6 +332,17 @@ public:
_qos(qos), _retain(retain)
{}
/**
* \brief Construct a Will Message.
*
* \param topic Topic name, identification of the information channel to which
* the Will Message will be published.
* \param message The message that will be published.
* \param qos The \ref qos_e level used when publishing the Will Message.
* \param retain The \ref retain_e flag specifying if the Will Message
* is to be retained when it is published.
* \param props Will properties.
*/
will(
std::string topic, std::string message,
qos_e qos, retain_e retain, will_props props
@@ -321,21 +353,34 @@ public:
{}
// just to make sure that we don't accidentally make a copy
/// Copy constructor.
will(const will&) = delete;
/// Move constructor.
will(will&&) noexcept = default;
/// Copy assignment operator.
will& operator=(const will&) = delete;
/// Move assignment operator.
will& operator=(will&&) noexcept = default;
/// Get the Topic Name.
constexpr std::string_view topic() const {
return _topic;
}
/// Get the Application Message.
constexpr std::string_view message() const {
return _message;
}
/// Get the \ref qos_e.
constexpr qos_e qos() const {
return _qos;
}
/// Get the \ref retain_e.
constexpr retain_e retain() const {
return _retain;
}