forked from boostorg/mqtt5
[mqtt-client] user can only async_disconnect with rcs < 0x80, fix async_disconnect ecs
Summary: resolves T12974 Reviewers: ivica Reviewed By: ivica Subscribers: miljen, iljazovic Maniphest Tasks: T12974 Differential Revision: https://repo.mireo.local/D26294
This commit is contained in:
@@ -21,7 +21,7 @@ public:
|
||||
using executor_type = asio::any_io_executor;
|
||||
private:
|
||||
using queued_op_t = asio::any_completion_handler<
|
||||
void (boost::system::error_code)
|
||||
void (error_code)
|
||||
>;
|
||||
using queue_t = ring_buffer<queued_op_t>;
|
||||
|
||||
@@ -57,7 +57,7 @@ private:
|
||||
return asio::get_associated_cancellation_slot(_handler);
|
||||
}
|
||||
|
||||
void operator()(boost::system::error_code ec) {
|
||||
void operator()(error_code ec) {
|
||||
std::move(_handler)(ec);
|
||||
}
|
||||
};
|
||||
|
@@ -20,9 +20,15 @@ enum class disconnect_rc_e : std::uint8_t {
|
||||
|
||||
/** The Client wishes to disconnect but requires that
|
||||
the Server also publishes its Will Message. */
|
||||
disconnect_with_will_message = 0x04
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
enum class disconnect_rc_e : std::uint8_t {
|
||||
normal_disconnection = 0x00,
|
||||
disconnect_with_will_message = 0x04,
|
||||
|
||||
// TODO: these reason codes should not be available to the user, only the client
|
||||
unspecified_error = 0x80,
|
||||
malformed_packet = 0x81,
|
||||
protocol_error = 0x82,
|
||||
@@ -37,6 +43,9 @@ enum class disconnect_rc_e : std::uint8_t {
|
||||
payload_format_invalid = 0x99
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace client {
|
||||
/**
|
||||
* \brief MQTT client error codes.
|
||||
@@ -44,23 +53,14 @@ namespace client {
|
||||
* \details Represents error that occur on the client side.
|
||||
*/
|
||||
enum class error : int {
|
||||
/** [unused] A fatal error occurred. */
|
||||
fatal_error = 100,
|
||||
|
||||
/// \cond INTERNAL
|
||||
/** Malformed packet has been detected. */
|
||||
malformed_packet,
|
||||
malformed_packet = 100,
|
||||
/// \endcond
|
||||
|
||||
/** There are no more available Packet Identifiers to use. */
|
||||
pid_overrun,
|
||||
|
||||
/** [unused] The Client has reconnected. */
|
||||
reconnected,
|
||||
|
||||
/** [unused] The Client has been disconnected. */
|
||||
disconnected,
|
||||
|
||||
// publish
|
||||
/** The Server does not support the specified \ref qos_e. */
|
||||
qos_not_supported,
|
||||
@@ -77,16 +77,10 @@ inline std::string client_error_to_string(error err) {
|
||||
using enum error;
|
||||
|
||||
switch (err) {
|
||||
case fatal_error:
|
||||
return "A fatal error occurred";
|
||||
case malformed_packet:
|
||||
return "Malformed packet has been detected";
|
||||
case pid_overrun:
|
||||
return "There are no more available Packet Identifiers to use.";
|
||||
case reconnected:
|
||||
return "The Client has reconnected";
|
||||
case disconnected:
|
||||
return "The Client has been disconnected";
|
||||
case qos_not_supported:
|
||||
return "The Server does not support the specified QoS";
|
||||
case retain_not_available:
|
||||
|
@@ -80,14 +80,12 @@ public:
|
||||
// The connection must be closed even
|
||||
// if we failed to send the DISCONNECT packet
|
||||
// with Reason Code of 0x80 or greater.
|
||||
// TODO: what about rc < 0x80?
|
||||
|
||||
if (
|
||||
ec == asio::error::operation_aborted ||
|
||||
ec == asio::error::no_recovery
|
||||
)
|
||||
// TODO: do we need two different errors here?
|
||||
return complete(ec);
|
||||
return complete(asio::error::operation_aborted);
|
||||
|
||||
if (_context.terminal) {
|
||||
_svc_ptr->cancel();
|
||||
@@ -95,7 +93,7 @@ public:
|
||||
}
|
||||
|
||||
if (ec == asio::error::try_again)
|
||||
return complete(ec);
|
||||
return complete(error_code {});
|
||||
|
||||
_svc_ptr->close_stream();
|
||||
_svc_ptr->open_stream();
|
||||
|
@@ -140,7 +140,8 @@ public:
|
||||
* \details All outstanding operations will complete
|
||||
* with `boost::asio::error::operation_aborted`.
|
||||
*
|
||||
* \attention The Client cannot be used before calling \ref mqtt_client::run again.
|
||||
* \attention This function has terminal effects and will close the Client.
|
||||
* The Client cannot be used before calling \ref mqtt_client::run again.
|
||||
*/
|
||||
void cancel() {
|
||||
get_executor().execute([svc_ptr = _svc_ptr]() {
|
||||
@@ -394,9 +395,9 @@ public:
|
||||
* \brief Send an \__UNSUBSCRIBE\__ packet to Broker to unsubscribe from one
|
||||
* or more Topics.
|
||||
*
|
||||
* \note The Client MAY receive \__PUBLISH\__ packets with Application
|
||||
* Messages from Topics the Client just unsubscribed to if
|
||||
* they were buffered for delivery on the Broker side beforehand.
|
||||
* \note The Client may still receive residual Application Messages
|
||||
* through the \ref mqtt_client::async_receive function
|
||||
* from Topics the Client just unsubscribed to.
|
||||
*
|
||||
* \param topics List of Topics to unsubscribe from.
|
||||
* \param props An instance of \__UNSUBSCRIBE_PROPS\__.
|
||||
@@ -450,9 +451,9 @@ public:
|
||||
* \brief Send an \__UNSUBSCRIBE\__ packet to Broker to unsubscribe
|
||||
* from one Topic.
|
||||
*
|
||||
* \note The Client MAY receive \__PUBLISH\__ packets with Application
|
||||
* Messages from Topics the Client just unsubscribed to if
|
||||
* they were buffered for delivery on the Broker side beforehand.
|
||||
* \note The Client may still receive residual Application Messages
|
||||
* through the \ref mqtt_client::async_receive function
|
||||
* from Topics the Client just unsubscribed to.
|
||||
*
|
||||
* \param topic Topic to unsubscribe from.
|
||||
* \param props An instance of \__UNSUBSCRIBE_PROPS\__.
|
||||
@@ -539,7 +540,8 @@ public:
|
||||
* \details Send a \__DISCONNECT\__ packet to the Broker with a Reason Code
|
||||
* describing the reason for disconnection.
|
||||
*
|
||||
* \attention This function will close the Client. See \ref mqtt_client::cancel.
|
||||
* \attention This function has terminal effects and will close the Client.
|
||||
* See \ref mqtt_client::cancel.
|
||||
*
|
||||
* \param reason_code Reason Code to notify
|
||||
* the Broker of the reason for disconnection.
|
||||
@@ -559,7 +561,6 @@ public:
|
||||
* The list of all possible error codes that this operation can finish with:\n
|
||||
* - `boost::system::errc::errc_t::success`\n
|
||||
* - `boost::asio::error::operation_aborted`\n
|
||||
* - `boost::asio::no_recovery`\n
|
||||
*
|
||||
* Refer to the section on \__ERROR_HANDLING\__ to find the underlying causes for each error code.
|
||||
*/
|
||||
@@ -569,7 +570,8 @@ public:
|
||||
CompletionToken&& token
|
||||
) {
|
||||
return detail::async_disconnect(
|
||||
reason_code, props, true, _svc_ptr,
|
||||
detail::disconnect_rc_e(static_cast<uint8_t>(reason_code)),
|
||||
props, true, _svc_ptr,
|
||||
std::forward<CompletionToken>(token)
|
||||
);
|
||||
}
|
||||
@@ -581,7 +583,8 @@ public:
|
||||
* \ref reason_codes::normal_disconnection describing
|
||||
* the reason for disconnection.
|
||||
*
|
||||
* \attention This function will close the Client. See \ref mqtt_client::cancel.
|
||||
* \attention This function has terminal effects and will close the Client.
|
||||
* See \ref mqtt_client::cancel.
|
||||
*
|
||||
* \param token Completion token that will be used to produce a
|
||||
* completion handler, which will be called when the operation completed.
|
||||
@@ -598,7 +601,6 @@ public:
|
||||
* The list of all possible error codes that this operation can finish with:\n
|
||||
* - `boost::system::errc::errc_t::success`\n
|
||||
* - `boost::asio::error::operation_aborted`\n
|
||||
* - `boost::asio::no_recovery`\n
|
||||
*
|
||||
* Refer to the section on \__ERROR_HANDLING\__ to find the underlying causes for each error code.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user