forked from boostorg/mqtt5
Improved CONNECT & CONNACK property client functions
Summary: related to T13427 Reviewers: ivica Reviewed By: ivica Subscribers: miljen, iljazovic Differential Revision: https://repo.mireo.local/D27218
This commit is contained in:
@ -89,7 +89,7 @@ public:
|
||||
_read_buff.cbegin(), _data_span.first()
|
||||
);
|
||||
_read_buff.resize(
|
||||
_svc.connect_prop(prop::maximum_packet_size).value_or(max_recv_size)
|
||||
_svc.connect_property(prop::maximum_packet_size).value_or(max_recv_size)
|
||||
);
|
||||
_data_span = {
|
||||
_read_buff.cbegin(),
|
||||
@ -157,7 +157,7 @@ public:
|
||||
}
|
||||
|
||||
auto recv_size = static_cast<size_t>(
|
||||
_svc.connect_prop(prop::maximum_packet_size).value_or(max_recv_size)
|
||||
_svc.connect_property(prop::maximum_packet_size).value_or(max_recv_size)
|
||||
);
|
||||
if (*varlen > recv_size - std::distance(_data_span.first(), first))
|
||||
return complete(client::error::malformed_packet, 0, {}, {});
|
||||
|
@ -147,7 +147,7 @@ public:
|
||||
// all the packets that require resending.
|
||||
_write_in_progress = true;
|
||||
|
||||
auto new_limit = _svc._stream_context.connack_prop(prop::receive_maximum);
|
||||
auto new_limit = _svc._stream_context.connack_property(prop::receive_maximum);
|
||||
_limit = new_limit.value_or(MAX_LIMIT);
|
||||
_quota = _limit;
|
||||
|
||||
|
@ -62,20 +62,25 @@ public:
|
||||
}
|
||||
|
||||
template <typename Prop>
|
||||
const auto& connack_prop(Prop p) const {
|
||||
const auto& connack_property(Prop p) const {
|
||||
return _mqtt_context.ca_props[p];
|
||||
}
|
||||
|
||||
const auto& connack_props() const {
|
||||
const auto& connack_properties() const {
|
||||
return _mqtt_context.ca_props;
|
||||
}
|
||||
|
||||
template <typename Prop>
|
||||
const auto& connect_prop(Prop p) const {
|
||||
const auto& connect_property(Prop p) const {
|
||||
return _mqtt_context.co_props[p];
|
||||
}
|
||||
|
||||
void connect_props(connect_props props) {
|
||||
template <typename Prop>
|
||||
auto& connect_property(Prop p) {
|
||||
return _mqtt_context.co_props[p];
|
||||
}
|
||||
|
||||
void connect_propertiess(connect_props props) {
|
||||
_mqtt_context.co_props = std::move(props);
|
||||
}
|
||||
|
||||
@ -123,20 +128,25 @@ public:
|
||||
}
|
||||
|
||||
template <typename Prop>
|
||||
const auto& connack_prop(Prop p) const {
|
||||
const auto& connack_property(Prop p) const {
|
||||
return _mqtt_context.ca_props[p];
|
||||
}
|
||||
|
||||
const auto& connack_props() const {
|
||||
const auto& connack_properties() const {
|
||||
return _mqtt_context.ca_props;
|
||||
}
|
||||
|
||||
template <typename Prop>
|
||||
const auto& connect_prop(Prop p) const {
|
||||
const auto& connect_property(Prop p) const {
|
||||
return _mqtt_context.co_props[p];
|
||||
}
|
||||
|
||||
void connect_props(connect_props props) {
|
||||
template <typename Prop>
|
||||
auto& connect_property(Prop p) {
|
||||
return _mqtt_context.co_props[p];
|
||||
}
|
||||
|
||||
void connect_properties(connect_props props) {
|
||||
_mqtt_context.co_props = std::move(props);
|
||||
}
|
||||
|
||||
@ -267,22 +277,27 @@ public:
|
||||
}
|
||||
|
||||
template <typename Prop>
|
||||
const auto& connect_prop(Prop p) const {
|
||||
return _stream_context.connect_prop(p);
|
||||
}
|
||||
|
||||
void connect_props(connect_props props) {
|
||||
if (!is_open())
|
||||
_stream_context.connect_props(std::move(props));
|
||||
const auto& connect_property(Prop p) const {
|
||||
return _stream_context.connect_property(p);
|
||||
}
|
||||
|
||||
template <typename Prop>
|
||||
const auto& connack_prop(Prop p) const {
|
||||
return _stream_context.connack_prop(p);
|
||||
auto& connect_property(Prop p) {
|
||||
return _stream_context.connect_property(p);
|
||||
}
|
||||
|
||||
const auto& connack_props() const {
|
||||
return _stream_context.connack_props();
|
||||
void connect_properties(connect_props props) {
|
||||
if (!is_open())
|
||||
_stream_context.connect_properties(std::move(props));
|
||||
}
|
||||
|
||||
template <typename Prop>
|
||||
const auto& connack_property(Prop p) const {
|
||||
return _stream_context.connack_property(p);
|
||||
}
|
||||
|
||||
const auto& connack_properties() const {
|
||||
return _stream_context.connack_properties();
|
||||
}
|
||||
|
||||
void run() {
|
||||
|
@ -72,7 +72,7 @@ public:
|
||||
);
|
||||
|
||||
auto max_packet_size = static_cast<size_t>(
|
||||
_svc_ptr->connack_prop(prop::maximum_packet_size)
|
||||
_svc_ptr->connack_property(prop::maximum_packet_size)
|
||||
.value_or(default_max_send_size)
|
||||
);
|
||||
if (disconnect.size() > max_packet_size)
|
||||
|
@ -121,7 +121,7 @@ public:
|
||||
);
|
||||
|
||||
auto max_packet_size = static_cast<size_t>(
|
||||
_svc_ptr->connack_prop(prop::maximum_packet_size)
|
||||
_svc_ptr->connack_property(prop::maximum_packet_size)
|
||||
.value_or(default_max_send_size)
|
||||
);
|
||||
if (publish.size() > max_packet_size)
|
||||
@ -355,9 +355,9 @@ private:
|
||||
if (validate_topic_name(topic) != validation_result::valid)
|
||||
return client::error::invalid_topic;
|
||||
|
||||
auto max_qos = _svc_ptr->connack_prop(prop::maximum_qos)
|
||||
auto max_qos = _svc_ptr->connack_property(prop::maximum_qos)
|
||||
.value_or(default_maximum_qos);
|
||||
auto retain_available = _svc_ptr->connack_prop(prop::retain_available)
|
||||
auto retain_available = _svc_ptr->connack_property(prop::retain_available)
|
||||
.value_or(default_retain_available);
|
||||
|
||||
if (uint8_t(qos_type) > max_qos)
|
||||
@ -382,7 +382,7 @@ private:
|
||||
|
||||
auto topic_alias = props[prop::topic_alias];
|
||||
if (topic_alias) {
|
||||
auto topic_alias_max = _svc_ptr->connack_prop(prop::topic_alias_maximum)
|
||||
auto topic_alias_max = _svc_ptr->connack_property(prop::topic_alias_maximum)
|
||||
.value_or(default_topic_alias_max);
|
||||
|
||||
if (topic_alias_max == 0 || *topic_alias > topic_alias_max)
|
||||
|
@ -81,7 +81,7 @@ public:
|
||||
);
|
||||
|
||||
auto max_packet_size = static_cast<size_t>(
|
||||
_svc_ptr->connack_prop(prop::maximum_packet_size)
|
||||
_svc_ptr->connack_property(prop::maximum_packet_size)
|
||||
.value_or(default_max_send_size)
|
||||
);
|
||||
if (subscribe.size() > max_packet_size)
|
||||
@ -169,10 +169,10 @@ private:
|
||||
}
|
||||
|
||||
error_code validate_topic(const subscribe_topic& topic) const {
|
||||
auto wildcard_available = _svc_ptr->connack_prop(
|
||||
auto wildcard_available = _svc_ptr->connack_property(
|
||||
prop::wildcard_subscription_available
|
||||
).value_or(1);
|
||||
auto shared_available = _svc_ptr->connack_prop(
|
||||
auto shared_available = _svc_ptr->connack_property(
|
||||
prop::shared_subscription_available
|
||||
).value_or(1);
|
||||
|
||||
@ -208,7 +208,7 @@ private:
|
||||
if (!sub_id.has_value())
|
||||
return error_code {};
|
||||
|
||||
auto sub_id_available = _svc_ptr->connack_prop(
|
||||
auto sub_id_available = _svc_ptr->connack_property(
|
||||
prop::subscription_identifier_available
|
||||
).value_or(1);
|
||||
|
||||
|
@ -76,7 +76,7 @@ public:
|
||||
);
|
||||
|
||||
auto max_packet_size = static_cast<size_t>(
|
||||
_svc_ptr->connack_prop(prop::maximum_packet_size)
|
||||
_svc_ptr->connack_property(prop::maximum_packet_size)
|
||||
.value_or(default_max_send_size)
|
||||
);
|
||||
if (unsubscribe.size() > max_packet_size)
|
||||
|
@ -274,8 +274,35 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Assign \__CONNECT_PROPS\__ that will be sent in a \__CONNECT\__ packet.
|
||||
* \param props \__CONNECT_PROPS\__ sent in a \__CONNECT\__ packet.
|
||||
* \see See \__CONNECT_PROPS\__ for all eligible properties.
|
||||
*/
|
||||
mqtt_client& connect_properties(connect_props props) {
|
||||
_svc_ptr->connect_props(std::move(props));
|
||||
_svc_ptr->connect_properties(std::move(props));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Assign a property that will be sent in a \__CONNECT\__ packet.
|
||||
* \param prop The \__CONNECT_PROPS\__ property to set.
|
||||
* \param value Value that will be assigned to the property.
|
||||
*
|
||||
* \par Example
|
||||
* \code
|
||||
* client.connect_property(prop::session_expiry_interval, 40); // ok
|
||||
* client.connect_property(prop::reason_string, "reason"); // does not compile, not a CONNECT prop!
|
||||
* \endcode
|
||||
*
|
||||
* \see See \__CONNECT_PROPS\__ for all eligible properties.
|
||||
*/
|
||||
template <prop::property_type p>
|
||||
mqtt_client& connect_property(
|
||||
std::integral_constant<prop::property_type, p> prop,
|
||||
prop::value_type_t<p> value
|
||||
) {
|
||||
_svc_ptr->connect_property(prop) = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -296,21 +323,30 @@ public:
|
||||
* For all properties, the return type will be `std::optional` of their respective value type.
|
||||
* For `async_mqtt5::prop::user_property`, the return type is `std::vector<std::string>`.
|
||||
*
|
||||
* \param prop The \__CONNACK\__ property value to retrieve.
|
||||
* \param prop The \__CONNACK_PROPS\__ property value to retrieve.
|
||||
*
|
||||
* \par Example
|
||||
* \code
|
||||
* std::optional<std::string> auth_method = client.connection_property(async_mqtt5::prop::authentication_method); // ok
|
||||
* std::optional<std::string> c_type = client.connection_property(async_mqtt5::prop::content_type); // does not compile!
|
||||
* std::optional<std::string> auth_method = client.connack_property(async_mqtt5::prop::authentication_method); // ok
|
||||
* std::optional<std::string> c_type = client.connack_property(async_mqtt5::prop::content_type); // does not compile, not a CONNAK prop!
|
||||
* \endcode
|
||||
*
|
||||
* \see See \__CONNACK_PROPS\__ for all eligible properties.
|
||||
*/
|
||||
template <prop::property_type p>
|
||||
const auto& connection_property(
|
||||
std::integral_constant<prop::property_type, p> prop
|
||||
const auto& connack_property(
|
||||
std::integral_constant<prop::property_type, p> prop
|
||||
) const {
|
||||
return _svc_ptr->connack_prop(prop);
|
||||
return _svc_ptr->connack_property(prop);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieves the \__CONNACK_PROPS\__ from the last \__CONNACK\__ packet received.
|
||||
*
|
||||
* \see See \__CONNACK_PROPS\__ for all eligible properties.
|
||||
*/
|
||||
const connack_props& connack_properties() const {
|
||||
return _svc_ptr->connack_properties();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -56,6 +56,7 @@ inline std::string_view code_to_str(control_code_e code) {
|
||||
case control_code_e::disconnect: return "DISCONNECT";
|
||||
case control_code_e::pingreq: return "PINGREQ";
|
||||
case control_code_e::pingresp: return "PINGRESP";
|
||||
default: return "NO PACKET";
|
||||
}
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
@ -51,19 +51,11 @@ public:
|
||||
}
|
||||
|
||||
template <typename Prop>
|
||||
decltype(auto) connack_prop(Prop p) {
|
||||
return std::as_const(_test_props[p]);
|
||||
const auto& connack_property(Prop p) const {
|
||||
return _test_props[p];
|
||||
}
|
||||
|
||||
template <typename Prop0, typename ...Props>
|
||||
decltype(auto) connack_props(Prop0 p0, Props ...props) {
|
||||
return std::make_tuple(
|
||||
std::as_const(_test_props[p0]),
|
||||
std::as_const(_test_props[props])...
|
||||
);
|
||||
}
|
||||
|
||||
const auto& connack_props() {
|
||||
const auto& connack_properties() {
|
||||
return _test_props;
|
||||
}
|
||||
|
||||
|
@ -443,7 +443,6 @@ BOOST_AUTO_TEST_CASE(throttling) {
|
||||
|
||||
test::msg_exchange broker_side;
|
||||
error_code success {};
|
||||
error_code fail = asio::error::not_connected;
|
||||
|
||||
broker_side
|
||||
.expect(connect)
|
||||
@ -546,7 +545,6 @@ BOOST_AUTO_TEST_CASE(cancel_multiple_ops) {
|
||||
|
||||
test::msg_exchange broker_side;
|
||||
error_code success{};
|
||||
error_code fail = asio::error::not_connected;
|
||||
|
||||
broker_side
|
||||
.expect(connect)
|
||||
|
@ -1,11 +1,16 @@
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/ssl/stream.hpp>
|
||||
#include <boost/asio/io_context.hpp>
|
||||
|
||||
#include <boost/beast/websocket/stream.hpp>
|
||||
|
||||
#include <boost/type_traits/remove_cv_ref.hpp>
|
||||
|
||||
#include <async_mqtt5/detail/any_authenticator.hpp>
|
||||
#include <async_mqtt5/detail/async_traits.hpp>
|
||||
|
||||
@ -43,7 +48,7 @@ class bad_authenticator {
|
||||
public:
|
||||
bad_authenticator() = default;
|
||||
|
||||
void async_auth(std::string data) {}
|
||||
void async_auth(std::string /* data */) {}
|
||||
|
||||
std::string_view method() const {
|
||||
return "method";
|
||||
@ -93,9 +98,28 @@ BOOST_AUTO_TEST_CASE(client_functions) {
|
||||
mqtt_client<tcp_layer> tcp_client(ioc, "");
|
||||
tcp_client.authenticator(good_authenticator());
|
||||
|
||||
std::optional<std::string> data = tcp_client.connection_property(
|
||||
prop::authentication_data
|
||||
);
|
||||
connack_props ca_props;
|
||||
ca_props.visit([&tcp_client](const auto& p, auto&) -> bool {
|
||||
using ptype = boost::remove_cv_ref_t<decltype(p)>;
|
||||
prop::value_type_t<ptype::value> value = tcp_client.connack_property(p);
|
||||
return true;
|
||||
});
|
||||
|
||||
connack_props ret_ca_props = tcp_client.connack_properties();
|
||||
|
||||
connect_props co_props;
|
||||
co_props[prop::maximum_packet_size] = 1234;
|
||||
tcp_client.connect_properties(std::move(co_props));
|
||||
|
||||
tcp_client.connect_property(prop::session_expiry_interval, 40);
|
||||
tcp_client.connect_property(prop::receive_maximum, int16_t(10123));
|
||||
tcp_client.connect_property(prop::maximum_packet_size, 103);
|
||||
tcp_client.connect_property(prop::topic_alias_maximum, uint16_t(12345));
|
||||
tcp_client.connect_property(prop::request_response_information, uint8_t(1));
|
||||
tcp_client.connect_property(prop::request_problem_information, uint8_t(0));
|
||||
tcp_client.connect_property(prop::user_property, std::vector<std::string> { "prop", "prop" });
|
||||
tcp_client.connect_property(prop::authentication_method, "method");
|
||||
tcp_client.connect_property(prop::authentication_data, "data");
|
||||
|
||||
asio::ssl::context ctx(asio::ssl::context::tls_client);
|
||||
mqtt_client<
|
||||
|
@ -55,7 +55,7 @@ BOOST_AUTO_TEST_CASE(test_wildcard_subscriptions_not_supported) {
|
||||
auto svc_ptr = std::make_shared<client_service_type>(
|
||||
ioc.get_executor(), std::move(props)
|
||||
);
|
||||
BOOST_ASSERT(svc_ptr->connack_prop(prop::wildcard_subscription_available) == 0);
|
||||
BOOST_ASSERT(svc_ptr->connack_property(prop::wildcard_subscription_available) == 0);
|
||||
|
||||
for (const auto& topic: wildcard_topics) {
|
||||
auto handler = [&handlers_called](error_code ec, auto, auto) {
|
||||
@ -87,7 +87,7 @@ BOOST_AUTO_TEST_CASE(test_shared_subscriptions_not_supported) {
|
||||
auto svc_ptr = std::make_shared<client_service_type>(
|
||||
ioc.get_executor(), std::move(props)
|
||||
);
|
||||
BOOST_ASSERT(svc_ptr->connack_prop(prop::shared_subscription_available) == 0);
|
||||
BOOST_ASSERT(svc_ptr->connack_property(prop::shared_subscription_available) == 0);
|
||||
|
||||
auto handler = [&handlers_called](error_code ec, auto, auto) {
|
||||
++handlers_called;
|
||||
@ -117,7 +117,7 @@ BOOST_AUTO_TEST_CASE(test_large_subscription_id) {
|
||||
auto svc_ptr = std::make_shared<client_service_type>(
|
||||
ioc.get_executor(), std::move(props)
|
||||
);
|
||||
BOOST_ASSERT(svc_ptr->connack_prop(prop::subscription_identifier_available) == 1);
|
||||
BOOST_ASSERT(svc_ptr->connack_property(prop::subscription_identifier_available) == 1);
|
||||
|
||||
auto handler = [&handlers_called](error_code ec, auto, auto) {
|
||||
++handlers_called;
|
||||
@ -150,7 +150,7 @@ BOOST_AUTO_TEST_CASE(test_subscription_ids_not_supported) {
|
||||
auto svc_ptr = std::make_shared<client_service_type>(
|
||||
ioc.get_executor(), std::move(props)
|
||||
);
|
||||
BOOST_ASSERT(svc_ptr->connack_prop(prop::subscription_identifier_available) == 0);
|
||||
BOOST_ASSERT(svc_ptr->connack_property(prop::subscription_identifier_available) == 0);
|
||||
|
||||
auto handler = [&handlers_called](error_code ec, auto, auto) {
|
||||
++handlers_called;
|
||||
|
Reference in New Issue
Block a user