diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 955a6178b..435230338 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -2,6 +2,13 @@ = History +== 10.0.0 +=== breaking changes +* Re-organized include files. +* Removed non bulk read to meet Sans-I/O interface. +* Supported I/O independent (aka Sans-I/O) library. +* underlying_handshake functionality is updated from free function to member function. + == 9.1.0 * Added invalid combination checking of sharename and nl(no local). #372 * Fixed receive maximum processing. #371 diff --git a/CMakeLists.txt b/CMakeLists.txt index a2345e6c6..1e4aae20f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ # http://www.boost.org/LICENSE_1_0.txt) cmake_minimum_required (VERSION 3.13.0) -project(async_mqtt_iface VERSION 9.1.0) +project(async_mqtt_iface VERSION 10.0.0) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -20,6 +20,7 @@ option(ASYNC_MQTT_BUILD_TOOLS "Enable building tools (broker, bench, etc.." OFF) option(ASYNC_MQTT_BUILD_EXAMPLES "Enable building example applications" OFF) option(ASYNC_MQTT_BUILD_EXAMPLES_SEPARATE "Enable building separate library build example applications(It requires much memory)" OFF) option(ASYNC_MQTT_BUILD_LIB "Enable building separate compilation library" OFF) +option(ASYNC_MQTT_MRDOCS "For Mr.Docs document generation" OFF) # Not implemented yet option(ASYNC_MQTT_USE_STR_CHECK "Enable UTF8 String check" OFF) @@ -157,7 +158,7 @@ if(DOXYGEN_FOUND) COMMAND ${CMAKE_COMMAND} -E echo "FILE_PATTERNS = *.hpp" >> ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile COMMAND ${CMAKE_COMMAND} -E echo "OUTPUT_DIRECTORY = doc" >> ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile COMMAND ${CMAKE_COMMAND} -E echo "PROJECT_NAME = async_mqtt" >> ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile - COMMAND ${CMAKE_COMMAND} -E echo "PROJECT_NUMBER = 9.1.0" >> ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile + COMMAND ${CMAKE_COMMAND} -E echo "PROJECT_NUMBER = 10.0.0" >> ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile COMMAND ${CMAKE_COMMAND} -E echo "RECURSIVE = YES" >> ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile COMMAND ${CMAKE_COMMAND} -E echo "PREDEFINED = GENERATING_DOCUMENTATION ASYNC_MQTT_USE_TLS ASYNC_MQTT_USE_WS ASYNC_MQTT_USE_LOG" >> ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile COMMAND ${CMAKE_COMMAND} -E echo "INPUT = ${CMAKE_CURRENT_SOURCE_DIR}/include/async_mqtt" >> ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile diff --git a/README.md b/README.md index ae70bfa0b..7fced2752 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,24 @@ # async_mqtt -Asynchronous MQTT communication library. +- I/O independent (as known as Sans-I/O) MQTT protocol library for C++17. +- Asynchronous MQTT communication library using the MQTT protocol library and Boost.Asio. -Version 9.1.0 [![Actions Status](https://github.com/redboltz/async_mqtt/workflows/CI/badge.svg)](https://github.com/redboltz/async_mqtt/actions)[![codecov](https://codecov.io/gh/redboltz/async_mqtt/branch/main/graph/badge.svg)](https://codecov.io/gh/redboltz/async_mqtt) +Version 10.0.0 [![Actions Status](https://github.com/redboltz/async_mqtt/workflows/CI/badge.svg)](https://github.com/redboltz/async_mqtt/actions)[![codecov](https://codecov.io/gh/redboltz/async_mqtt/branch/main/graph/badge.svg)](https://codecov.io/gh/redboltz/async_mqtt) -This is Boost.Asio oriented asynchronous MQTT communication library. You can use async_mqtt to develop not only your MQTT client application but also your server (e.g. broker). -Based on https://github.com/redboltz/mqtt_cpp experience, there are many improvements. See overview. - -Document is https://github.com/redboltz/async_mqtt/blob/doc/README.adoc - -# Overview +## Document [Latest document](https://redboltz.github.io/async_mqtt/doc/latest/index.html) +## I/O independent protocol library +- connection + - Protocol state machine for MQTT connection. + - All APIs are implemented as synchronous member functions. + - State machine events are implemented as pure virtual functions. +- rv_connection + - Inherits connection. + - State machine events are implemented as the return value of APIs. + - The type of return value is vector of event_variant. + ## Boost.Asio style asynchronous APIs support ### [Completion Token](https://www.boost.org/doc/html/boost_asio/overview/model/completion_tokens.html) is supported diff --git a/doc/build_antora.sh b/doc/build_antora.sh old mode 100644 new mode 100755 diff --git a/doc/copy_example.sh b/doc/copy_example.sh old mode 100644 new mode 100755 diff --git a/doc/modules/ROOT/pages/reference.adoc b/doc/modules/ROOT/pages/reference.adoc index 470a4ba82..0a71a9ac5 100644 --- a/doc/modules/ROOT/pages/reference.adoc +++ b/doc/modules/ROOT/pages/reference.adoc @@ -1,17 +1,47 @@ [#reference] = Reference -[width=100%] +== I/O independent (a.k.a Sans-I/O) MQTT protocol machine + +[%header,width=100%,cols="1,1,1"] |=== -1+| *MQTT Connections* | *Predefined Layers* | *MQTT packets* | *Errors* +|MQTT Protocol +|Timer +|Error -| **Class Templates** +| -xref:reference:async_mqtt/client.adoc[`client`] +*Classes* -xref:reference:async_mqtt/endpoint.adoc[`endpoint`] +*Protocol machines* -xref:reference:async_mqtt/basic_endpoint.adoc[`basic_endpoint`] +xref:reference:async_mqtt/connection.adoc[`connection`] + +xref:reference:async_mqtt/basic_connection.adoc[`basic_connection`] + +xref:reference:async_mqtt/rv_connection.adoc[`rv_connection`] + +xref:reference:async_mqtt/basic_rv_connection.adoc[`basic_rv_connection`] + +**Events** + +xref:reference:async_mqtt/event_variant.adoc[`event_variant`] + +xref:reference:async_mqtt/event/basic_send.adoc[`basic_send`] + +xref:reference:async_mqtt/event/send.adoc[`send`] + +xref:reference:async_mqtt/event/basic_packet_received.adoc[`basic_packet_received`] + +xref:reference:async_mqtt/event/packet_received.adoc[`packet_received`] + +xref:reference:async_mqtt/event/close.adoc[`close`] + +xref:reference:async_mqtt/event/basic_packet_id_released.adoc[`basic_packet_id_released`] + +xref:reference:async_mqtt/event/packet_id_released.adoc[`packet_id_released`] + +xref:reference:async_mqtt/event/timer.adoc[`timer`] **Enums** @@ -19,124 +49,228 @@ xref:reference:async_mqtt/protocol_version.adoc[`protocol_version`] xref:reference:async_mqtt/role.adoc[`role`] +| + +**Enums** + +xref:reference:async_mqtt/timer_kind.adoc[`timer_kind`] + +xref:reference:async_mqtt/timer_op.adoc[`timer_op`] + **Functions** -xref:reference:async_mqtt/setup_log.adoc[`setup_log`] +xref:reference:async_mqtt/timer_kind_to_string.adoc[`timer_kind_to_string`] -xref:reference:async_mqtt/logger.adoc[`log`] +xref:reference:async_mqtt/timer_op_to_string.adoc[`timer_op_to_string`] -| **Types** +| -xref:reference:async_mqtt/protocol/mqtt.adoc[`mqtt`] +**Types** -xref:reference:async_mqtt/protocol/mqtts.adoc[`mqtts`] +xref:reference:async_mqtt/error_code.adoc[`error_code`] -xref:reference:async_mqtt/protocol/ws.adoc[`ws`] +**Enums** -xref:reference:async_mqtt/protocol/wss.adoc[`wss`] +**common** -**Class Templates** +xref:reference:async_mqtt/mqtt_error.adoc[`mqtt_error`] -xref:reference:async_mqtt/layer_customize-03.adoc[`layer_customize(TCP)`] +**v3.1.1** -xref:reference:async_mqtt/layer_customize-08.adoc[`layer_customize(TLS)`] +xref:reference:async_mqtt/connect_return_code.adoc[`connect_return_code`] -xref:reference:async_mqtt/layer_customize-02.adoc[`layer_customize(WS)`] +xref:reference:async_mqtt/suback_return_code.adoc[`suback_return_code`] + +**v5** + +xref:reference:async_mqtt/connect_reason_code.adoc[`connect_reason_code`] + +xref:reference:async_mqtt/disconnect_reason_code.adoc[`disconnect_reason_code`] +xref:reference:async_mqtt/suback_reason_code.adoc[`suback_reason_code`] -**Function Templates** +xref:reference:async_mqtt/unsuback_reason_code.adoc[`unsuback_reason_code`] -xref:reference:async_mqtt/async_underlying_handshake-05.adoc[`async_underlying_handshake(TCP)`] -xref:reference:async_mqtt/async_underlying_handshake-09.adoc[`async_underlying_handshake(TLS)`] -xref:reference:async_mqtt/async_underlying_handshake-06.adoc[`async_underlying_handshake(WS)`] -xref:reference:async_mqtt/async_underlying_handshake-0b.adoc[`async_underlying_handshake(WS with path)`] +xref:reference:async_mqtt/puback_reason_code.adoc[`puback_reason_code`] -| **Class Templates** +xref:reference:async_mqtt/pubrec_reason_code.adoc[`pubrec_reason_code`] -**common** +xref:reference:async_mqtt/pubrel_reason_code.adoc[`pubrel_reason_code`] + +xref:reference:async_mqtt/pubcomp_reason_code.adoc[`pubcomp_reason_code`] + +xref:reference:async_mqtt/auth_reason_code.adoc[`auth_reason_code`] + +|=== + + +[%header,width=100%,cols="1,1,1,1"] +|=== +4+|MQTT packets + +| + +**Classes(1 of 4)** + +**variants** xref:reference:async_mqtt/packet_variant.adoc[`packet_variant`] + xref:reference:async_mqtt/basic_packet_variant.adoc[`basic_packet_variant`] **v3.1.1** xref:reference:async_mqtt/v3_1_1/connect_packet.adoc[`connect_packet`] + xref:reference:async_mqtt/v3_1_1/connack_packet.adoc[`connack_packet`] + xref:reference:async_mqtt/v3_1_1/disconnect_packet.adoc[`disconnect_packet`] + xref:reference:async_mqtt/v3_1_1/subscribe_packet.adoc[`subscribe_packet`] + xref:reference:async_mqtt/v3_1_1/basic_subscribe_packet.adoc[`basic_subscribe_packet`] + xref:reference:async_mqtt/v3_1_1/suback_packet.adoc[`suback_packet`] + xref:reference:async_mqtt/v3_1_1/basic_suback_packet.adoc[`basic_suback_packet`] + xref:reference:async_mqtt/v3_1_1/unsubscribe_packet.adoc[`unsubscribe_packet`] + xref:reference:async_mqtt/v3_1_1/basic_unsubscribe_packet.adoc[`basic_unsubscribe_packet`] + xref:reference:async_mqtt/v3_1_1/unsuback_packet.adoc[`unsuback_packet`] + xref:reference:async_mqtt/v3_1_1/basic_unsuback_packet.adoc[`basic_unsuback_packet`] + +| + +**Classes(2 of 4)** + xref:reference:async_mqtt/v3_1_1/publish_packet.adoc[`publish_packet`] + xref:reference:async_mqtt/v3_1_1/basic_publish_packet.adoc[`basic_publish_packet`] + xref:reference:async_mqtt/v3_1_1/puback_packet.adoc[`puback_packet`] + xref:reference:async_mqtt/v3_1_1/basic_puback_packet.adoc[`basic_puback_packet`] + xref:reference:async_mqtt/v3_1_1/pubrec_packet.adoc[`pubrec_packet`] + xref:reference:async_mqtt/v3_1_1/basic_pubrec_packet.adoc[`basic_pubrec_packet`] + xref:reference:async_mqtt/v3_1_1/pubrel_packet.adoc[`pubrel_packet`] + xref:reference:async_mqtt/v3_1_1/basic_pubrel_packet.adoc[`basic_pubrel_packet`] + xref:reference:async_mqtt/v3_1_1/pubcomp_packet.adoc[`pubcomp_packet`] + xref:reference:async_mqtt/v3_1_1/basic_pubcomp_packet.adoc[`basic_pubcomp_packet`] + xref:reference:async_mqtt/v3_1_1/pingreq_packet.adoc[`pingreq_packet`] + xref:reference:async_mqtt/v3_1_1/pingresp_packet.adoc[`pungresp_packet`] +| + +**Classes(3 of 4)** + **v5** xref:reference:async_mqtt/v5/connect_packet.adoc[`connect_packet`] + xref:reference:async_mqtt/v5/connack_packet.adoc[`connack_packet`] + xref:reference:async_mqtt/v5/disconnect_packet.adoc[`disconnect_packet`] + xref:reference:async_mqtt/v5/subscribe_packet.adoc[`subscribe_packet`] + xref:reference:async_mqtt/v5/basic_subscribe_packet.adoc[`basic_subscribe_packet`] + xref:reference:async_mqtt/v5/suback_packet.adoc[`suback_packet`] + xref:reference:async_mqtt/v5/basic_suback_packet.adoc[`basic_suback_packet`] + xref:reference:async_mqtt/v5/unsubscribe_packet.adoc[`unsubscribe_packet`] + xref:reference:async_mqtt/v5/basic_unsubscribe_packet.adoc[`basic_unsubscribe_packet`] + xref:reference:async_mqtt/v5/unsuback_packet.adoc[`unsuback_packet`] + xref:reference:async_mqtt/v5/basic_unsuback_packet.adoc[`basic_unsuback_packet`] + +| + +**Classes(4 of 4)** + xref:reference:async_mqtt/v5/publish_packet.adoc[`publish_packet`] + xref:reference:async_mqtt/v5/basic_publish_packet.adoc[`basic_publish_packet`] + xref:reference:async_mqtt/v5/puback_packet.adoc[`puback_packet`] + xref:reference:async_mqtt/v5/basic_puback_packet.adoc[`basic_puback_packet`] + xref:reference:async_mqtt/v5/pubrec_packet.adoc[`pubrec_packet`] + xref:reference:async_mqtt/v5/basic_pubrec_packet.adoc[`basic_pubrec_packet`] + xref:reference:async_mqtt/v5/pubrel_packet.adoc[`pubrel_packet`] + xref:reference:async_mqtt/v5/basic_pubrel_packet.adoc[`basic_pubrel_packet`] + xref:reference:async_mqtt/v5/pubcomp_packet.adoc[`pubcomp_packet`] + xref:reference:async_mqtt/v5/basic_pubcomp_packet.adoc[`basic_pubcomp_packet`] + xref:reference:async_mqtt/v5/pingreq_packet.adoc[`pingreq_packet`] + xref:reference:async_mqtt/v5/pingresp_packet.adoc[`pungresp_packet`] + xref:reference:async_mqtt/v5/auth_packet.adoc[`auth_packet`] +|=== -| **Types** -xref:reference:async_mqtt/error_code.adoc[`error_code`] +== Boost.Asio binding of the MQTT protocol machine -**Enums** +[width=100%] +|=== +1+| *MQTT Connections* | *Predefined Layers* -**common** +| -xref:reference:async_mqtt/mqtt_error.adoc[`mqtt_error`] +**Classes** -**v3.1.1** +xref:reference:async_mqtt/client.adoc[`client`] -xref:reference:async_mqtt/connect_return_code.adoc[`connect_return_code`] -xref:reference:async_mqtt/suback_return_code.adoc[`suback_return_code`] +xref:reference:async_mqtt/endpoint.adoc[`endpoint`] -**v5** +xref:reference:async_mqtt/basic_endpoint.adoc[`basic_endpoint`] -xref:reference:async_mqtt/connect_reason_code.adoc[`connect_reason_code`] -xref:reference:async_mqtt/disconnect_reason_code.adoc[`disconnect_reason_code`] -xref:reference:async_mqtt/suback_reason_code.adoc[`suback_reason_code`] -xref:reference:async_mqtt/unsuback_reason_code.adoc[`unsuback_reason_code`] -xref:reference:async_mqtt/puback_reason_code.adoc[`puback_reason_code`] -xref:reference:async_mqtt/pubrec_reason_code.adoc[`pubrec_reason_code`] -xref:reference:async_mqtt/pubrel_reason_code.adoc[`pubrel_reason_code`] -xref:reference:async_mqtt/pubcomp_reason_code.adoc[`pubcomp_reason_code`] -xref:reference:async_mqtt/auth_reason_code.adoc[`auth_reason_code`] +**Functions** + +xref:reference:async_mqtt/setup_log.adoc[`setup_log`] + +xref:reference:async_mqtt/logger.adoc[`log`] + +| + +**Types** + +xref:reference:async_mqtt/protocol/mqtt.adoc[`mqtt`] + +xref:reference:async_mqtt/protocol/mqtts.adoc[`mqtts`] + +xref:reference:async_mqtt/protocol/ws.adoc[`ws`] + +xref:reference:async_mqtt/protocol/wss.adoc[`wss`] + +**Classes** + +xref:reference:async_mqtt/layer_customize-03.adoc[`layer_customize(TCP)`] + +xref:reference:async_mqtt/layer_customize-08.adoc[`layer_customize(TLS)`] + +xref:reference:async_mqtt/layer_customize-02.adoc[`layer_customize(WS)`] |=== diff --git a/doc/mrdocs.yml b/doc/mrdocs.yml index 1eb4aa6b1..7bb237cfd 100644 --- a/doc/mrdocs.yml +++ b/doc/mrdocs.yml @@ -40,4 +40,4 @@ base-url: https://www.github.com/redboltz/async_mqtt/blob/main/include/ verbose: true multipage: true -cmake: '-D CMAKE_CXX_STANDARD=17 -D ASYNC_MQTT_USE_TLS=ON -D ASYNC_MQTT_USE_WS=ON -D ASYNC_MQTT_USE_LOG=ON -D ASYNC_MQTT_BUILD_TOOLS=ON"' +cmake: '-D CMAKE_CXX_STANDARD=17 -D ASYNC_MQTT_USE_TLS=ON -D ASYNC_MQTT_USE_WS=ON -D ASYNC_MQTT_USE_LOG=ON -D ASYNC_MQTT_BUILD_TOOLS=ON -D ASYNC_MQTT_MRDOCS=ON' diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 7bb31c1e1..80cdfc5c9 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -18,8 +18,12 @@ if("cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES) ep_cpp20coro_mqtt_client.cpp ) if(ASYNC_MQTT_BUILD_EXAMPLE_SEPARATE) - add_subdirectory(separate_client) - add_subdirectory(separate_endpoint) + if(ASYNC_MQTT_BUILD_LIB) + add_subdirectory(separate_client) + add_subdirectory(separate_endpoint) + else() + message(WARNING "ASYNC_MQTT_BUILD_LIB is required for ASYNC_MQTT_BUILD_EXAMPLE_SEPARATE") + endif() endif() endif() diff --git a/example/cl_cpp17_mqtt_pub.cpp b/example/cl_cpp17_mqtt_pub.cpp index 2a397a323..05a3f3563 100644 --- a/example/cl_cpp17_mqtt_pub.cpp +++ b/example/cl_cpp17_mqtt_pub.cpp @@ -27,8 +27,7 @@ struct app { app(as::any_io_executor exe, std::string_view host, std::string_view port) : cli_{exe} { - am::async_underlying_handshake( - cli_.next_layer(), + cli_.async_underlying_handshake( host, port, [this](auto&&... args) { @@ -124,7 +123,7 @@ struct app { int main(int argc, char* argv[]) { am::setup_log( - am::severity_level::warning, + am::severity_level::trace, true // log colored ); if (argc != 3) { diff --git a/example/cl_cpp17_mqtt_sub.cpp b/example/cl_cpp17_mqtt_sub.cpp index c15f41543..c1d86961e 100644 --- a/example/cl_cpp17_mqtt_sub.cpp +++ b/example/cl_cpp17_mqtt_sub.cpp @@ -32,8 +32,7 @@ struct app { private: void connect() { - am::async_underlying_handshake( - cli_.next_layer(), + cli_.async_underlying_handshake( host_, port_, [this](auto&&... args) { @@ -130,15 +129,15 @@ struct app { void handle_recv( am::error_code ec, - am::packet_variant pv + std::optional pv_opt ) { std::cout << "recv:" << ec.message() << std::endl; if (ec) { reconnect(); return; } - BOOST_ASSERT(pv); - std::cout << pv << std::endl; + BOOST_ASSERT(pv_opt); + std::cout << *pv_opt << std::endl; // next receive cli_.async_recv( [this](auto&&... args) { diff --git a/example/cl_cpp20coro_mqtt.cpp b/example/cl_cpp20coro_mqtt.cpp index 06b7a6043..89230e8d3 100644 --- a/example/cl_cpp20coro_mqtt.cpp +++ b/example/cl_cpp20coro_mqtt.cpp @@ -29,7 +29,7 @@ proc( try { // all underlying layer handshaking // (Resolve hostname, TCP handshake) - co_await am::async_underlying_handshake(amcl.next_layer(), host, port, as::use_awaitable); + co_await amcl.async_underlying_handshake(host, port, as::use_awaitable); std::cout << "mqtt undlerlying handshaked" << std::endl; @@ -116,8 +116,9 @@ proc( // recv (coroutine) for (int i = 0; i != 2; ++i) { - auto pv = co_await amcl.async_recv(as::use_awaitable); - pv.visit( + auto pv_opt = co_await amcl.async_recv(as::use_awaitable); + BOOST_ASSERT(pv_opt); + pv_opt->visit( am::overload{ [&](client_t::publish_packet& p) { std::cout << p << std::endl; @@ -134,9 +135,11 @@ proc( } // recv (callback) before sending amcl.async_recv( - [] (am::error_code ec, am::packet_variant pv) { + [] (am::error_code ec, std::optional pv_opt) { std::cout << ec.message() << std::endl; - pv.visit( + if (ec) return; + BOOST_ASSERT(pv_opt); + pv_opt->visit( am::overload{ [&](client_t::publish_packet& p) { std::cout << p << std::endl; diff --git a/example/cl_cpp20coro_mqtt_pub.cpp b/example/cl_cpp20coro_mqtt_pub.cpp index 3206072fa..26e4d74b5 100644 --- a/example/cl_cpp20coro_mqtt_pub.cpp +++ b/example/cl_cpp20coro_mqtt_pub.cpp @@ -38,7 +38,7 @@ proc( try { // all underlying layer handshaking // (Resolve hostname, TCP handshake) - co_await am::async_underlying_handshake(amcl.next_layer(), host, port); + co_await amcl.async_underlying_handshake(host, port); std::cout << "mqtt undlerlying handshaked" << std::endl; // MQTT connect and receive loop start diff --git a/example/cl_cpp20coro_mqtt_sub.cpp b/example/cl_cpp20coro_mqtt_sub.cpp index 95125fc34..ad53af022 100644 --- a/example/cl_cpp20coro_mqtt_sub.cpp +++ b/example/cl_cpp20coro_mqtt_sub.cpp @@ -41,7 +41,7 @@ proc( try { // all underlying layer handshaking // (Resolve hostname, TCP handshake) - co_await am::async_underlying_handshake(amcl.next_layer(), host, port); + co_await amcl.async_underlying_handshake(host, port); std::cout << "mqtt undlerlying handshaked" << std::endl; // MQTT connect and receive loop start @@ -74,8 +74,9 @@ proc( // recv (coroutine) while (true) { - auto pv = co_await amcl.async_recv(as::use_awaitable); - pv.visit( + auto pv_opt = co_await amcl.async_recv(as::use_awaitable); + BOOST_ASSERT(pv_opt); + pv_opt->visit( am::overload{ [&](awaitable_client::publish_packet& p) { std::cout << p << std::endl; diff --git a/example/custom_logger.cpp b/example/custom_logger.cpp index 74e506008..22e0ed5c4 100644 --- a/example/custom_logger.cpp +++ b/example/custom_logger.cpp @@ -87,8 +87,7 @@ struct app { app(as::any_io_executor exe, std::string_view host, std::string_view port) : cli_{exe} { - am::async_underlying_handshake( - cli_.next_layer(), + cli_.async_underlying_handshake( host, port, [this](auto&&... args) { diff --git a/example/ep_cb_mqtt_client.cpp b/example/ep_cb_mqtt_client.cpp index 294715f77..e40cb1fb4 100644 --- a/example/ep_cb_mqtt_client.cpp +++ b/example/ep_cb_mqtt_client.cpp @@ -33,8 +33,7 @@ struct app { std::cout << "start" << std::endl; // Handshake undlerying layer (Name resolution and TCP handshaking) - am::async_underlying_handshake( - amep_.next_layer(), + amep_.async_underlying_handshake( host_, port_, [this] @@ -82,13 +81,13 @@ struct app { // Recv MQTT CONNACK amep_.async_recv( [this] - (am::error_code const& ec, am::packet_variant pv) { - handle_recv_connack(ec, am::force_move(pv)); + (am::error_code const& ec, std::optional pv_opt) { + handle_recv_connack(ec, am::force_move(pv_opt)); } ); } - void handle_recv_connack(am::error_code const& ec, am::packet_variant pv) { + void handle_recv_connack(am::error_code const& ec, std::optional pv_opt) { if (ec) { std::cout << "MQTT CONNACK recv error:" @@ -96,7 +95,8 @@ struct app { << std::endl; } else { - pv.visit( + BOOST_ASSERT(pv_opt); + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { std::cout @@ -129,13 +129,13 @@ struct app { // Recv MQTT SUBACK amep_.async_recv( [this] - (am::error_code const& ec, am::packet_variant pv) { - handle_recv_suback(ec, am::force_move(pv)); + (am::error_code const& ec, std::optional pv_opt) { + handle_recv_suback(ec, am::force_move(pv_opt)); } ); } - void handle_recv_suback(am::error_code const& ec, am::packet_variant pv) { + void handle_recv_suback(am::error_code const& ec, std::optional pv_opt) { if (ec) { std::cout << "MQTT SUBACK recv error:" @@ -143,7 +143,8 @@ struct app { << std::endl; } else { - pv.visit( + BOOST_ASSERT(pv_opt); + pv_opt->visit( am::overload { [&](am::v3_1_1::suback_packet const& p) { std::cout @@ -182,13 +183,13 @@ struct app { // Recv MQTT PUBACK or (echobacked) PUBLISH amep_.async_recv( [this] - (am::error_code const& ec, am::packet_variant pv) { - handle_recv_puback_or_publish(ec, am::force_move(pv)); + (am::error_code const& ec, std::optional pv_opt) { + handle_recv_puback_or_publish(ec, am::force_move(pv_opt)); } ); } - void handle_recv_puback_or_publish(am::error_code const& ec, am::packet_variant pv) { + void handle_recv_puback_or_publish(am::error_code const& ec, std::optional pv_opt) { if (ec) { std::cout << "MQTT recv error:" @@ -196,7 +197,8 @@ struct app { << std::endl; } else { - pv.visit( + BOOST_ASSERT(pv_opt); + pv_opt->visit( am::overload { [&](am::v3_1_1::publish_packet const& p) { std::cout @@ -221,8 +223,8 @@ struct app { if (++count_ < 2) { amep_.async_recv( [this] - (am::error_code const& ec, am::packet_variant pv) { - handle_recv_puback_or_publish(ec, am::force_move(pv)); + (am::error_code const& ec, std::optional pv_opt) { + handle_recv_puback_or_publish(ec, am::force_move(pv_opt)); } ); } diff --git a/example/ep_cpp20coro_mqtt_client.cpp b/example/ep_cpp20coro_mqtt_client.cpp index b0c285a87..001aa0cc7 100644 --- a/example/ep_cpp20coro_mqtt_client.cpp +++ b/example/ep_cpp20coro_mqtt_client.cpp @@ -25,7 +25,7 @@ proc( try { // Handshake undlerying layer (Name resolution and TCP handshaking) - co_await am::async_underlying_handshake(amep.next_layer(), host, port, as::use_awaitable); + co_await amep.async_underlying_handshake(host, port, as::use_awaitable); std::cout << "Underlying layer handshaked" << std::endl; // prepare will message if you need. @@ -53,8 +53,8 @@ proc( ); // Recv MQTT CONNACK - if (am::packet_variant pv = co_await amep.async_recv(as::use_awaitable)) { - pv.visit( + if (std::optional pv_opt = co_await amep.async_recv(as::use_awaitable)) { + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { std::cout @@ -80,8 +80,8 @@ proc( ); // Recv MQTT SUBACK - if (am::packet_variant pv = co_await amep.async_recv(as::use_awaitable)) { - pv.visit( + if (std::optional pv_opt = co_await amep.async_recv(as::use_awaitable)) { + pv_opt->visit( am::overload { [&](am::v3_1_1::suback_packet const& p) { std::cout @@ -111,8 +111,8 @@ proc( // Recv MQTT PUBLISH and PUBACK (order depends on broker) for (std::size_t count = 0; count != 2; ++count) { - if (am::packet_variant pv = co_await amep.async_recv(as::use_awaitable)) { - pv.visit( + if (std::optional pv_opt = co_await amep.async_recv(as::use_awaitable)) { + pv_opt->visit( am::overload { [&](am::v3_1_1::publish_packet const& p) { std::cout diff --git a/example/ep_future_mqtt_client.cpp b/example/ep_future_mqtt_client.cpp index 7ba9fbe52..7c301d8b6 100644 --- a/example/ep_future_mqtt_client.cpp +++ b/example/ep_future_mqtt_client.cpp @@ -54,7 +54,11 @@ int main(int argc, char* argv[]) { std::string host{argv[1]}; std::string port{argv[2]}; // Handshake undlerying layer (Name resolution and TCP handshaking) - am::async_underlying_handshake(amep.next_layer(), host, port, as::use_future).get(); + amep.async_underlying_handshake( + host, + port, + as::use_future + ).get(); std::cout << "Underlying layer handshaked" << std::endl; // prepare will message if you need. @@ -87,9 +91,9 @@ int main(int argc, char* argv[]) { // Recv MQTT CONNACK { auto fut = amep.async_recv(as::use_future); - auto pv = fut.get(); // get am::packet_variant, throw if error_code is not success - if (pv) { - pv.visit( + auto pv_opt = fut.get(); // get std::optional, throw if error_code is not success + if (pv_opt) { + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { std::cout @@ -100,7 +104,6 @@ int main(int argc, char* argv[]) { [](auto const&) {} } ); - std::cout << am::hex_dump(pv) << std::endl; } } @@ -121,9 +124,9 @@ int main(int argc, char* argv[]) { // Recv MQTT SUBACK { auto fut = amep.async_recv(as::use_future); - auto pv = fut.get(); // get am::packet_variant, throw if error_code is not success - if (pv) { - pv.visit( + auto pv_opt = fut.get(); // get std::optional, throw if error_code is not success + if (pv_opt) { + pv_opt->visit( am::overload { [&](am::v3_1_1::suback_packet const& p) { std::cout @@ -161,9 +164,9 @@ int main(int argc, char* argv[]) { { for (std::size_t count = 0; count != 2; ++count) { auto fut = amep.async_recv(as::use_future); - auto pv = fut.get(); // get am::packet_variant, throw if error_code is not success - if (pv) { - pv.visit( + auto pv_opt = fut.get(); // get std::optional, throw if error_code is not success + if (pv_opt) { + pv_opt->visit( am::overload { [&](am::v3_1_1::publish_packet const& p) { std::cout diff --git a/example/ep_slcoro_mqtt_client.cpp b/example/ep_slcoro_mqtt_client.cpp index 251b820b4..9e83edbd2 100644 --- a/example/ep_slcoro_mqtt_client.cpp +++ b/example/ep_slcoro_mqtt_client.cpp @@ -35,26 +35,25 @@ struct app { } // forwarding callbacks void operator()() const { - proc({}, am::packet_variant{}); + proc({}, std::nullopt); } void operator()(am::error_code const& ec) const { - proc(ec, am::packet_variant{}); + proc(ec, std::nullopt); } - void operator()(am::error_code const& ec, am::packet_variant pv) const { - proc(ec, am::force_move(pv)); + void operator()(am::error_code const& ec, std::optional pv_opt) const { + proc(ec, am::force_move(pv_opt)); } private: void proc( am::error_code const& ec, - am::packet_variant pv + std::optional pv_opt ) const { reenter (coro_) { std::cout << "start" << std::endl; // Handshake undlerying layer (Name resolution and TCP handshaking) - yield am::async_underlying_handshake( - app_.amep_.next_layer(), + yield app_.amep_.async_underlying_handshake( app_.host_, app_.port_, *this @@ -90,8 +89,8 @@ struct app { std::cout << "MQTT CONNACK recv error:" << ec.message() << std::endl; return; } - BOOST_ASSERT(pv); - pv.visit( + BOOST_ASSERT(pv_opt); + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { std::cout @@ -121,8 +120,8 @@ struct app { std::cout << "MQTT SUBACK recv error:" << ec.message() << std::endl; return; } - BOOST_ASSERT(pv); - pv.visit( + BOOST_ASSERT(pv_opt); + pv_opt->visit( am::overload { [&](am::v3_1_1::suback_packet const& p) { std::cout @@ -159,8 +158,8 @@ struct app { std::cout << "MQTT recv error:" << ec.message() << std::endl; return; } - BOOST_ASSERT(pv); - pv.visit( + BOOST_ASSERT(pv_opt); + pv_opt->visit( am::overload { [&](am::v3_1_1::publish_packet const& p) { std::cout diff --git a/example/ep_slcoro_mqtts_client.cpp b/example/ep_slcoro_mqtts_client.cpp index 72b58664a..5d7153ae5 100644 --- a/example/ep_slcoro_mqtts_client.cpp +++ b/example/ep_slcoro_mqtts_client.cpp @@ -40,26 +40,25 @@ struct app { } // forwarding callbacks void operator()() const { - proc({}, am::packet_variant{}); + proc({}, std::nullopt); } void operator()(am::error_code const& ec) const { - proc(ec, am::packet_variant{}); + proc(ec, std::nullopt); } - void operator()(am::error_code const& ec, am::packet_variant pv) const { - proc(ec, am::force_move(pv)); + void operator()(am::error_code const& ec, std::optional pv_opt) const { + proc(ec, am::force_move(pv_opt)); } private: void proc( am::error_code const& ec, - am::packet_variant pv + std::optional pv_opt ) const { reenter (coro_) { std::cout << "start" << std::endl; // Handshake undlerying layer (Name resolution and TCP, TLS handshaking) - yield am::async_underlying_handshake( - app_.amep_.next_layer(), + yield app_.amep_.async_underlying_handshake( app_.host_, app_.port_, *this @@ -98,8 +97,8 @@ struct app { << std::endl; return; } - BOOST_ASSERT(pv); - pv.visit( + BOOST_ASSERT(pv_opt); + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { std::cout @@ -132,8 +131,8 @@ struct app { << std::endl; return; } - BOOST_ASSERT(pv); - pv.visit( + BOOST_ASSERT(pv_opt); + pv_opt->visit( am::overload { [&](am::v3_1_1::suback_packet const& p) { std::cout @@ -173,8 +172,8 @@ struct app { << std::endl; return; } - BOOST_ASSERT(pv); - pv.visit( + BOOST_ASSERT(pv_opt); + pv_opt->visit( am::overload { [&](am::v3_1_1::publish_packet const& p) { std::cout diff --git a/example/ep_slcoro_ws_client.cpp b/example/ep_slcoro_ws_client.cpp index 637842550..a70c9dd11 100644 --- a/example/ep_slcoro_ws_client.cpp +++ b/example/ep_slcoro_ws_client.cpp @@ -36,26 +36,25 @@ struct app { } // forwarding callbacks void operator()() const { - proc({}, am::packet_variant{}); + proc({}, std::nullopt); } void operator()(am::error_code const& ec) const { - proc(ec, am::packet_variant{}); + proc(ec, std::nullopt); } - void operator()(am::error_code const& ec, am::packet_variant pv) const { - proc(ec, am::force_move(pv)); + void operator()(am::error_code const& ec, std::optional pv_opt) const { + proc(ec, am::force_move(pv_opt)); } private: void proc( am::error_code const& ec, - am::packet_variant pv + std::optional pv_opt ) const { reenter (coro_) { std::cout << "start" << std::endl; // Handshake undlerying layer (Name resolution and TCP, Websocket handshaking) - yield am::async_underlying_handshake( - app_.amep_.next_layer(), + yield app_.amep_.async_underlying_handshake( app_.host_, app_.port_, *this @@ -91,8 +90,8 @@ struct app { std::cout << "MQTT CONNACK recv error:" << ec.message() << std::endl; return; } - BOOST_ASSERT(pv); - pv.visit( + BOOST_ASSERT(pv_opt); + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { std::cout @@ -122,8 +121,8 @@ struct app { std::cout << "MQTT SUBACK recv error:" << ec.message() << std::endl; return; } - BOOST_ASSERT(pv); - pv.visit( + BOOST_ASSERT(pv_opt); + pv_opt->visit( am::overload { [&](am::v3_1_1::suback_packet const& p) { std::cout @@ -159,8 +158,8 @@ struct app { std::cout << "MQTT recv error:" << ec.message() << std::endl; return; } - BOOST_ASSERT(pv); - pv.visit( + BOOST_ASSERT(pv_opt); + pv_opt->visit( am::overload { [&](am::v3_1_1::publish_packet const& p) { std::cout diff --git a/example/ep_slcoro_wss_client.cpp b/example/ep_slcoro_wss_client.cpp index d03b712ce..a0423b856 100644 --- a/example/ep_slcoro_wss_client.cpp +++ b/example/ep_slcoro_wss_client.cpp @@ -37,26 +37,25 @@ struct app { } // forwarding callbacks void operator()() const { - proc({}, am::packet_variant{}); + proc({}, std::nullopt); } void operator()(am::error_code const& ec) const { - proc(ec, am::packet_variant{}); + proc(ec, std::nullopt); } - void operator()(am::error_code const& ec, am::packet_variant pv) const { - proc(ec, am::force_move(pv)); + void operator()(am::error_code const& ec, std::optional pv_opt) const { + proc(ec, am::force_move(pv_opt)); } private: void proc( boost::system::error_code const& ec, - am::packet_variant pv + std::optional pv_opt ) const { reenter (coro_) { std::cout << "start" << std::endl; // Handshake undlerying layer (Name resolution and TCP, TLS, Websocket handshaking) - yield am::async_underlying_handshake( - app_.amep_.next_layer(), + yield app_.amep_.async_underlying_handshake( app_.host_, app_.port_, *this @@ -92,8 +91,8 @@ struct app { std::cout << "MQTT CONNACK recv error:" << ec.message() << std::endl; return; } - BOOST_ASSERT(pv); - pv.visit( + BOOST_ASSERT(pv_opt); + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { std::cout @@ -123,8 +122,8 @@ struct app { std::cout << "MQTT SUBACK recv error:" << ec.message() << std::endl; return; } - BOOST_ASSERT(pv); - pv.visit( + BOOST_ASSERT(pv_opt); + pv_opt->visit( am::overload { [&](am::v3_1_1::suback_packet const& p) { std::cout @@ -161,8 +160,8 @@ struct app { std::cout << "MQTT recv error:" << ec.message() << std::endl; return; } - BOOST_ASSERT(pv); - pv.visit( + BOOST_ASSERT(pv_opt); + pv_opt->visit( am::overload { [&](am::v3_1_1::publish_packet const& p) { std::cout diff --git a/example/footprint.cpp b/example/footprint.cpp index 8dfb3d800..f0aebd577 100644 --- a/example/footprint.cpp +++ b/example/footprint.cpp @@ -22,8 +22,7 @@ int main() { auto exe = co_await as::this_coro::executor; // Resolve hostname - auto [ec_und] = co_await am::async_underlying_handshake( - amcl.next_layer(), + auto [ec_und] = co_await amcl.async_underlying_handshake( "127.0.0.1", "1883", as::as_tuple(as::deferred) @@ -74,7 +73,7 @@ int main() { ); if (ec_pub0) co_return; - auto [ec_recv, pv] = co_await amcl.async_recv( + auto [ec_recv, pv_opt] = co_await amcl.async_recv( as::as_tuple(as::deferred) ); diff --git a/example/separate_client/CMakeLists.txt b/example/separate_client/CMakeLists.txt index 0f228c228..741b72620 100644 --- a/example/separate_client/CMakeLists.txt +++ b/example/separate_client/CMakeLists.txt @@ -2,16 +2,16 @@ project(separate_client) add_executable( separate_client - async_mqtt.cpp main.cpp ) +add_dependencies(separate_client async_mqtt_asio_bind async_mqtt_protocol) # Without this setting added, azure pipelines completely fails to find the boost libraries. No idea why. if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) endif() -target_link_libraries(separate_client PRIVATE async_mqtt_iface) +target_link_libraries(separate_client PRIVATE async_mqtt_iface async_mqtt_asio_bind async_mqtt_protocol) target_compile_definitions(separate_client PRIVATE ASYNC_MQTT_SEPARATE_COMPILATION) if(ASYNC_MQTT_USE_LOG) diff --git a/example/separate_client/async_mqtt.cpp b/example/separate_client/async_mqtt.cpp deleted file mode 100644 index d307daba5..000000000 --- a/example/separate_client/async_mqtt.cpp +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/example/separate_client/main.cpp b/example/separate_client/main.cpp index 06b7a6043..803ad7f4b 100644 --- a/example/separate_client/main.cpp +++ b/example/separate_client/main.cpp @@ -29,7 +29,7 @@ proc( try { // all underlying layer handshaking // (Resolve hostname, TCP handshake) - co_await am::async_underlying_handshake(amcl.next_layer(), host, port, as::use_awaitable); + co_await amcl.async_underlying_handshake(host, port, as::use_awaitable); std::cout << "mqtt undlerlying handshaked" << std::endl; @@ -116,8 +116,9 @@ proc( // recv (coroutine) for (int i = 0; i != 2; ++i) { - auto pv = co_await amcl.async_recv(as::use_awaitable); - pv.visit( + auto pv_opt = co_await amcl.async_recv(as::use_awaitable); + BOOST_ASSERT(pv_opt); + pv_opt->visit( am::overload{ [&](client_t::publish_packet& p) { std::cout << p << std::endl; @@ -134,9 +135,10 @@ proc( } // recv (callback) before sending amcl.async_recv( - [] (am::error_code ec, am::packet_variant pv) { + [] (am::error_code ec, std::optional pv_opt) { std::cout << ec.message() << std::endl; - pv.visit( + BOOST_ASSERT(pv_opt); + pv_opt->visit( am::overload{ [&](client_t::publish_packet& p) { std::cout << p << std::endl; diff --git a/example/separate_endpoint/CMakeLists.txt b/example/separate_endpoint/CMakeLists.txt index a40c3362d..3fe18770a 100644 --- a/example/separate_endpoint/CMakeLists.txt +++ b/example/separate_endpoint/CMakeLists.txt @@ -2,16 +2,16 @@ project(separate_endpoint) add_executable( separate_endpoint - async_mqtt.cpp main.cpp ) +add_dependencies(separate_endpoint async_mqtt_asio_bind async_mqtt_protocol) # Without this setting added, azure pipelines completely fails to find the boost libraries. No idea why. if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) endif() -target_link_libraries(separate_endpoint PRIVATE async_mqtt_iface) +target_link_libraries(separate_endpoint PRIVATE async_mqtt_iface async_mqtt_asio_bind async_mqtt_protocol) target_compile_definitions(separate_endpoint PRIVATE ASYNC_MQTT_SEPARATE_COMPILATION) if(ASYNC_MQTT_USE_LOG) diff --git a/example/separate_endpoint/async_mqtt.cpp b/example/separate_endpoint/async_mqtt.cpp deleted file mode 100644 index d307daba5..000000000 --- a/example/separate_endpoint/async_mqtt.cpp +++ /dev/null @@ -1 +0,0 @@ -#include diff --git a/example/separate_endpoint/main.cpp b/example/separate_endpoint/main.cpp index b0c285a87..001aa0cc7 100644 --- a/example/separate_endpoint/main.cpp +++ b/example/separate_endpoint/main.cpp @@ -25,7 +25,7 @@ proc( try { // Handshake undlerying layer (Name resolution and TCP handshaking) - co_await am::async_underlying_handshake(amep.next_layer(), host, port, as::use_awaitable); + co_await amep.async_underlying_handshake(host, port, as::use_awaitable); std::cout << "Underlying layer handshaked" << std::endl; // prepare will message if you need. @@ -53,8 +53,8 @@ proc( ); // Recv MQTT CONNACK - if (am::packet_variant pv = co_await amep.async_recv(as::use_awaitable)) { - pv.visit( + if (std::optional pv_opt = co_await amep.async_recv(as::use_awaitable)) { + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { std::cout @@ -80,8 +80,8 @@ proc( ); // Recv MQTT SUBACK - if (am::packet_variant pv = co_await amep.async_recv(as::use_awaitable)) { - pv.visit( + if (std::optional pv_opt = co_await amep.async_recv(as::use_awaitable)) { + pv_opt->visit( am::overload { [&](am::v3_1_1::suback_packet const& p) { std::cout @@ -111,8 +111,8 @@ proc( // Recv MQTT PUBLISH and PUBACK (order depends on broker) for (std::size_t count = 0; count != 2; ++count) { - if (am::packet_variant pv = co_await amep.async_recv(as::use_awaitable)) { - pv.visit( + if (std::optional pv_opt = co_await amep.async_recv(as::use_awaitable)) { + pv_opt->visit( am::overload { [&](am::v3_1_1::publish_packet const& p) { std::cout diff --git a/include/async_mqtt/all.hpp b/include/async_mqtt/all.hpp index 05f9ba5ca..62a848b9e 100644 --- a/include/async_mqtt/all.hpp +++ b/include/async_mqtt/all.hpp @@ -7,63 +7,62 @@ #if !defined(ASYNC_MQTT_ALL_HPP) #define ASYNC_MQTT_ALL_HPP -#include #include #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -74,15 +73,10 @@ #include #include #include -#include #include #include #include #include -#include -#include -#include -#include #include #include #include diff --git a/include/async_mqtt/client.hpp b/include/async_mqtt/client.hpp index 487b1641e..6a3194525 100644 --- a/include/async_mqtt/client.hpp +++ b/include/async_mqtt/client.hpp @@ -7,7 +7,17 @@ #if !defined(ASYNC_MQTT_CLIENT_HPP) #define ASYNC_MQTT_CLIENT_HPP -#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include /** * @defgroup client client (High level MQTT client) @@ -28,13 +38,13 @@ class client { using endpoint_type = basic_endpoint; /// @brief type of the given NextLayer - using next_layer_type = typename endpoint_type::next_layer_type; + using next_layer_type = NextLayer; /// @brief lowest_layer_type of the given NextLayer - using lowest_layer_type = typename endpoint_type::lowest_layer_type; + using lowest_layer_type = detail::lowest_layer_type; /// @brief executor_type of the given NextLayer - using executor_type = typename endpoint_type::executor_type; + using executor_type = typename next_layer_type::executor_type; /// @brief connect packet type /// @@ -120,6 +130,11 @@ class client { /// if Version is v5 the type is @ref v5::disconnect_packet. ASYNC_MQTT_PACKET_TYPE(Version, disconnect) + /// @brief auth packet type + /// + /// type alias of v5::auth_packet + using auth_packet = v5::auth_packet; + /** * @brief publish completion handler parameter class */ @@ -546,15 +561,15 @@ class client { * @li Default Completion Token is supported * * #### Signature - * void(@ref error_code, @ref packet_variant) + * void(@ref error_code, std::optional<@ref packet_variant_type>) * - * ##### error_code - * - * @li If receive error happens, error_code is set as error, otherwise + * ##### error_code and packet_variant_type + * @li If an error occurs at an underlying layer while receiving a packet, + * underlying error is set. e.g. system, asio, beast, ... + * std::optional<@ref packet_variant_type> is set to std::nullopt. + * @li If there are no errors during receiving the packet, * errc::success is set. - * - * ##### packet_variant - * If the error_code is errc::success, one of the following packet is set to the packet_variant: + * std::optional<@ref packet_variant_type> is set to one of the following @ref basic_packet_variant: * @li @ref v3_1_1::publish_packet, if Version is v3_1_1 and PUBLISH packet is received. * @li @ref v5::publish_packet, if Version is v5 and PUBLISH packet is received. * @li @ref v5::disconnect_packet, if Version is v5 and DISCONNECT packet is received. @@ -651,6 +666,17 @@ class client { */ void set_pingresp_recv_timeout(std::chrono::milliseconds duration); + /** + * @brief Sets the delay duration for closing the stream after sending the DISCONNECT packet. + * If the timer expires, the underlying layer stream will begin closing. + * \n This function should be called before async_start() call. + * @note By default, no delay is set. + * @param duration If set to zero, the timer is not activated, and the close process starts immediately. + * Otherwise, the close process begins after the specified duration has elapsed. + * The minimum resolution is in milliseconds. + */ + void set_close_delay_after_disconnect_sent(std::chrono::milliseconds duration); + /** * @brief Set bulk write mode. * If true, then concatenate multiple packets' const buffer sequence @@ -663,16 +689,23 @@ class client { void set_bulk_write(bool val); /** - * @brief Set the bulk read buffer size. + * @brief Set read buffer size. * If bulk read is enabled, the `val` parameter specifies the size of the internal - * `async_read_some()` buffer. - * Enabling bulk read can improve throughput but may increase latency. - * Disabling bulk read can reduce latency but may lower throughput. - * By default, bulk read is disabled. + * prepared `async_read_some()` streambuf. + * By default, read buffer size is 65535. * * @param val If set to 0, bulk read is disabled. Otherwise, it specifies the buffer size. */ - void set_bulk_read_buffer_size(std::size_t val); + void set_read_buffer_size(std::size_t val); + + // TBD doc later + template < + typename... Args + > + auto + async_underlying_handshake( + Args&&... args + ); /** * @brief acuire unique packet_id. @@ -898,7 +931,8 @@ class client { } // namespace async_mqtt -#include +#include +#include #include #include #include diff --git a/include/async_mqtt/client_fwd.hpp b/include/async_mqtt/client_fwd.hpp index 8d063d730..f30c2af64 100644 --- a/include/async_mqtt/client_fwd.hpp +++ b/include/async_mqtt/client_fwd.hpp @@ -9,8 +9,8 @@ #include // for std::size_t -#include -#include +#include +#include namespace async_mqtt { diff --git a/include/async_mqtt/detail/client_impl.hpp b/include/async_mqtt/detail/client_impl.hpp deleted file mode 100644 index d4d43bdd3..000000000 --- a/include/async_mqtt/detail/client_impl.hpp +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright Takatoshi Kondo 2024 -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#if !defined(ASYNC_MQTT_DETAIL_CLIENT_IMPL_HPP) -#define ASYNC_MQTT_DETAIL_CLIENT_IMPL_HPP - -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -namespace async_mqtt::detail { - -namespace as = boost::asio; - -template -class client_impl { - using this_type = client_impl; - using this_type_sp = std::shared_ptr; - using client_type = client; - -public: - using endpoint_type = basic_endpoint; - using next_layer_type = typename endpoint_type::next_layer_type; - using lowest_layer_type = typename endpoint_type::lowest_layer_type; - using executor_type = typename endpoint_type::executor_type; - - template - explicit - client_impl( - Args&&... args - ); - client_impl(this_type const&) = delete; - client_impl(this_type&&) = delete; - ~client_impl() = default; - - this_type& operator=(this_type const&) = delete; - this_type& operator=(this_type&&) = delete; - - template - auto async_start(Args&&... args); - - template - auto async_subscribe(Args&&... args); - - template - auto async_unsubscribe(Args&&... args); - - template - auto async_publish(Args&&... args); - - template - auto async_disconnect(Args&&... args); - - template - auto async_auth(Args&&... args); - - template < - typename CompletionToken = as::default_completion_token_t - > - auto - async_close( - CompletionToken&& token = as::default_completion_token_t{} - ); - - template < - typename CompletionToken = as::default_completion_token_t - > - auto - async_recv( - CompletionToken&& token = as::default_completion_token_t{} - ); - - as::any_io_executor get_executor(); - next_layer_type const& next_layer() const; - next_layer_type& next_layer(); - lowest_layer_type const& lowest_layer() const; - lowest_layer_type& lowest_layer(); - endpoint_type const& get_endpoint() const; - endpoint_type& get_endpoint(); - - void set_auto_map_topic_alias_send(bool val); - void set_auto_replace_topic_alias_send(bool val); - void set_pingresp_recv_timeout(std::chrono::milliseconds duration); - void set_bulk_write(bool val); - void set_bulk_read_buffer_size(std::size_t val); - - template < - typename CompletionToken = as::default_completion_token_t - > - auto - async_acquire_unique_packet_id( - CompletionToken&& token = as::default_completion_token_t{} - ); - - template < - typename CompletionToken = as::default_completion_token_t - > - auto - async_acquire_unique_packet_id_wait_until( - CompletionToken&& token = as::default_completion_token_t{} - ); - - template < - typename CompletionToken = as::default_completion_token_t - > - auto - async_register_packet_id( - packet_id_type packet_id, - CompletionToken&& token = as::default_completion_token_t{} - ); - - template < - typename CompletionToken = as::default_completion_token_t - > - auto - async_release_packet_id( - packet_id_type packet_id, - CompletionToken&& token = as::default_completion_token_t{} - ); - - std::optional acquire_unique_packet_id(); - bool register_packet_id(packet_id_type packet_id); - void release_packet_id(packet_id_type packet_id); - - template - struct rebind_executor { - using other = client_impl< - Version, - typename NextLayer::template rebind_executor::other - >; - }; - -private: - friend class client; - - template - explicit - client_impl( - client_impl&& other - ); - - template < - typename CompletionToken = as::default_completion_token_t - > - static - auto - async_start_impl( - this_type_sp impl, - error_code ec, - std::optional packet, - CompletionToken&& token = as::default_completion_token_t{} - ); - - template < - typename CompletionToken = as::default_completion_token_t - > - static - auto - async_subscribe_impl( - this_type_sp impl, - error_code ec, - std::optional packet, - CompletionToken&& token = as::default_completion_token_t{} - ); - - template < - typename CompletionToken = as::default_completion_token_t - > - static - auto - async_unsubscribe_impl( - this_type_sp impl, - error_code ec, - std::optional packet, - CompletionToken&& token = as::default_completion_token_t{} - ); - - template < - typename CompletionToken = as::default_completion_token_t - > - static - auto - async_publish_impl( - this_type_sp impl, - error_code ec, - std::optional packet, - CompletionToken&& token = as::default_completion_token_t{} - ); - - template < - typename CompletionToken = as::default_completion_token_t - > - static - auto - async_disconnect_impl( - this_type_sp impl, - error_code ec, - std::optional packet, - CompletionToken&& token = as::default_completion_token_t{} - ); - - template < - typename CompletionToken = as::default_completion_token_t - > - static - auto - async_auth_impl( - this_type_sp impl, - error_code ec, - std::optional packet, - CompletionToken&& token = as::default_completion_token_t{} - ); - - static void recv_loop(this_type_sp impl); - - // async operations - struct start_op; - struct subscribe_op; - struct unsubscribe_op; - struct publish_op; - struct disconnect_op; - struct auth_op; - struct recv_op; - - // internal types - struct pid_tim_pv_res_col; - struct recv_type; - - endpoint_type ep_; - pid_tim_pv_res_col pid_tim_pv_res_col_; - std::deque recv_queue_; - bool recv_queue_inserted_ = false; - as::steady_timer tim_notify_publish_recv_; -}; - -} // namespace async_mqtt::detail - -#endif // ASYNC_MQTT_DETAIL_CLIENT_IMPL_HPP diff --git a/include/async_mqtt/detail/client_impl_fwd.hpp b/include/async_mqtt/detail/client_impl_fwd.hpp new file mode 100644 index 000000000..a99b11777 --- /dev/null +++ b/include/async_mqtt/detail/client_impl_fwd.hpp @@ -0,0 +1,19 @@ +// Copyright Takatoshi Kondo 2024 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_DETAIL_CLIENT_IMPL_FWD_HPP) +#define ASYNC_MQTT_DETAIL_CLIENT_IMPL_FWD_HPP + +#include + +namespace async_mqtt::detail { + +template +class client_impl; + +} // namespace async_mqtt::detail + +#endif // ASYNC_MQTT_DETAIL_CLIENT_IMPL_FWD_HPP diff --git a/include/async_mqtt/detail/client_packet_type_getter.hpp b/include/async_mqtt/detail/client_packet_type_getter.hpp index f1aa5d6ea..44130b4b0 100644 --- a/include/async_mqtt/detail/client_packet_type_getter.hpp +++ b/include/async_mqtt/detail/client_packet_type_getter.hpp @@ -9,8 +9,8 @@ #include -#include -#include +#include +#include namespace async_mqtt::detail { diff --git a/include/async_mqtt/detail/endpoint_impl.hpp b/include/async_mqtt/detail/endpoint_impl.hpp deleted file mode 100644 index 56c3d75be..000000000 --- a/include/async_mqtt/detail/endpoint_impl.hpp +++ /dev/null @@ -1,255 +0,0 @@ -// Copyright Takatoshi Kondo 2022 -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#if !defined(ASYNC_MQTT_DETAIL_ENDPOINT_IMPL_HPP) -#define ASYNC_MQTT_DETAIL_ENDPOINT_IMPL_HPP - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace async_mqtt::detail { - -template -class basic_endpoint_impl { - enum class connection_status { - connecting, - connected, - disconnecting, - closing, - closed - }; - - using this_type = basic_endpoint_impl; - using this_type_sp = std::shared_ptr; - using this_type_wp = std::weak_ptr; - using stream_type = - stream< - NextLayer - >; - -public: - using next_layer_type = typename stream_type::next_layer_type; - using lowest_layer_type = typename stream_type::lowest_layer_type; - using executor_type = typename next_layer_type::executor_type; - using packet_variant_type = basic_packet_variant; - - template - explicit - basic_endpoint_impl( - protocol_version ver, - Args&&... args - ); - - ~basic_endpoint_impl() = default; - basic_endpoint_impl(this_type const&) = delete; - basic_endpoint_impl(this_type&&) = delete; - - this_type& operator=(this_type const&) = delete; - this_type& operator=(this_type&&) = delete; - - as::any_io_executor get_executor(); - next_layer_type const& next_layer() const; - next_layer_type& next_layer(); - lowest_layer_type const& lowest_layer() const; - lowest_layer_type& lowest_layer(); - - void set_auto_pub_response(bool val); - void set_auto_ping_response(bool val); - void set_auto_map_topic_alias_send(bool val); - void set_auto_replace_topic_alias_send(bool val); - void set_pingresp_recv_timeout(std::chrono::milliseconds duration); - void set_bulk_write(bool val); - void set_bulk_read_buffer_size(std::size_t val); - - // sync funcs - - std::optional::type> acquire_unique_packet_id(); - bool register_packet_id(typename basic_packet_id_type::type packet_id); - void release_packet_id(typename basic_packet_id_type::type packet_id); - std::set::type> get_qos2_publish_handled_pids() const; - void restore_qos2_publish_handled_pids(std::set::type> pids); - void restore_packets( - std::vector> pvs - ); - std::vector> get_stored_packets() const; - protocol_version get_protocol_version() const; - bool is_publish_processing(typename basic_packet_id_type::type pid) const; - void regulate_for_store( - v5::basic_publish_packet& packet, - error_code& ec - ) const; - static void set_pingreq_send_interval( - this_type_sp ep, - std::chrono::milliseconds duration - ); - - template - struct rebind_executor { - using other = basic_endpoint< - Role, - PacketIdBytes, - typename NextLayer::template rebind_executor::other - >; - }; - -private: // compose operation impl - - template - explicit - basic_endpoint_impl( - basic_endpoint_impl&& other - ); - - static constexpr bool can_send_as_client(role r); - static constexpr bool can_send_as_server(role r); - static std::optional get_topic_alias(properties const& props); - - struct acquire_unique_packet_id_op; - struct acquire_unique_packet_id_wait_until_op; - struct register_packet_id_op; - struct release_packet_id_op; - template struct send_op; - struct recv_op; - struct close_op; - struct restore_packets_op; - struct get_stored_packets_op; - struct regulate_for_store_op; - struct add_retry_op; - -private: - - template < - typename Packet, - typename CompletionToken = as::default_completion_token_t - > - static - auto - async_send( - this_type_sp impl, - Packet packet, - bool from_queue, - CompletionToken&& token = as::default_completion_token_t{} - ); - - template < - typename Packet, - typename CompletionToken = as::default_completion_token_t - > - static - auto - async_send( - this_type_sp impl, - Packet packet, - CompletionToken&& token = as::default_completion_token_t{} - ); - - template < - typename CompletionToken = as::default_completion_token_t - > - static - auto - async_close( - this_type_sp impl, - CompletionToken&& token = as::default_completion_token_t{} - ); - - template < - typename CompletionToken = as::default_completion_token_t - > - static - auto - async_add_retry( - this_type_sp impl, - CompletionToken&& token = as::default_completion_token_t{} - ); - - bool enqueue_publish(v5::basic_publish_packet& packet); - static void send_stored(this_type_sp ep); - void initialize(); - - static void reset_pingreq_send_timer(this_type_sp ep); - static void reset_pingreq_recv_timer(this_type_sp ep); - static void reset_pingresp_recv_timer(this_type_sp ep); - - void notify_retry_one(); - void complete_retry_one(); - void notify_retry_all(); - bool has_retry() const; - - void clear_pid_man(); - void release_pid(typename basic_packet_id_type::type pid); - -private: - - friend class basic_endpoint; - protocol_version protocol_version_; - stream_type stream_; - packet_id_manager::type> pid_man_; - std::set::type> pid_suback_; - std::set::type> pid_unsuback_; - std::set::type> pid_puback_; - std::set::type> pid_pubrec_; - std::set::type> pid_pubcomp_; - - bool need_store_ = false; - store store_; - - bool auto_pub_response_ = false; - bool auto_ping_response_ = false; - - bool auto_map_topic_alias_send_ = false; - bool auto_replace_topic_alias_send_ = false; - std::optional topic_alias_send_; - std::optional topic_alias_recv_; - - receive_maximum_type publish_send_max_{receive_maximum_max}; - receive_maximum_type publish_recv_max_{receive_maximum_max}; - receive_maximum_type publish_send_count_{0}; - - std::set::type> publish_recv_; - std::deque> publish_queue_; - - ioc_queue close_queue_; - - std::uint32_t maximum_packet_size_send_{packet_size_no_limit}; - std::uint32_t maximum_packet_size_recv_{packet_size_no_limit}; - - connection_status status_{connection_status::closed}; - - std::optional pingreq_send_interval_ms_; - std::optional pingreq_recv_timeout_ms_; - std::optional pingresp_recv_timeout_ms_; - - as::steady_timer tim_pingreq_send_; - as::steady_timer tim_pingreq_recv_; - as::steady_timer tim_pingresp_recv_; - - std::set::type> qos2_publish_handled_; - - std::set::type> qos2_publish_processing_; - - struct tim_cancelled; - std::deque tim_retry_acq_pid_queue_; - bool packet_id_released_ = false; -}; - -} // namespace async_mqtt::detail - -#endif // ASYNC_MQTT_DETAIL_ENDPOINT_IMPL_HPP diff --git a/include/async_mqtt/detail/endpoint_impl_fwd.hpp b/include/async_mqtt/detail/endpoint_impl_fwd.hpp new file mode 100644 index 000000000..a25da1ae7 --- /dev/null +++ b/include/async_mqtt/detail/endpoint_impl_fwd.hpp @@ -0,0 +1,20 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_DETAIL_ENDPOINT_IMPL_FWD_HPP) +#define ASYNC_MQTT_DETAIL_ENDPOINT_IMPL_FWD_HPP + +#include // for std::size_t +#include + +namespace async_mqtt::detail { + +template +class basic_endpoint_impl; + +} // namespace async_mqtt::detail + +#endif // ASYNC_MQTT_DETAIL_ENDPOINT_IMPL_FWD_HPP diff --git a/include/async_mqtt/detail/instantiate_helper.hpp b/include/async_mqtt/detail/instantiate_helper.hpp index cdf21eb87..7b23c8bf4 100644 --- a/include/async_mqtt/detail/instantiate_helper.hpp +++ b/include/async_mqtt/detail/instantiate_helper.hpp @@ -18,10 +18,10 @@ #include #include -#include +#include #if !defined(ASYNC_MQTT_PP_ROLE) -#define ASYNC_MQTT_PP_ROLE (role::client)(role::server)(role::any) +#define ASYNC_MQTT_PP_ROLE (async_mqtt::role::client)(async_mqtt::role::server)(async_mqtt::role::any) #endif // !defined(ASYNC_MQTT_PP_ROLE) #if !defined(ASYNC_MQTT_PP_SIZE) @@ -34,12 +34,12 @@ # if defined(ASYNC_MQTT_USE_WS) #include -#define ASYNC_MQTT_PP_PROTOCOL (protocol::mqtt)(protocol::mqtts)(protocol::ws)(protocol::wss) +#define ASYNC_MQTT_PP_PROTOCOL (async_mqtt::protocol::mqtt)(async_mqtt::protocol::mqtts)(async_mqtt::protocol::ws)(async_mqtt::protocol::wss) # else // defined(ASYNC_MQTT_USE_WS) #include -#define ASYNC_MQTT_PP_PROTOCOL (protocol::mqtt)(protocol::mqtts) +#define ASYNC_MQTT_PP_PROTOCOL (async_mqtt::protocol::mqtt)(async_mqtt::protocol::mqtts) # endif // defined(ASYNC_MQTT_USE_WS) @@ -48,12 +48,12 @@ # if defined(ASYNC_MQTT_USE_WS) #include -#define ASYNC_MQTT_PP_PROTOCOL (protocol::mqtt)(protocol::ws) +#define ASYNC_MQTT_PP_PROTOCOL (async_mqtt::protocol::mqtt)(async_mqtt::protocol::ws) # else // defined(ASYNC_MQTT_USE_WS) #include -#define ASYNC_MQTT_PP_PROTOCOL (protocol::mqtt) +#define ASYNC_MQTT_PP_PROTOCOL (async_mqtt::protocol::mqtt) # endif // defined(ASYNC_MQTT_USE_WS) #endif // defined(ASYNC_MQTT_USE_TLS) @@ -61,45 +61,46 @@ #endif // !defined(ASYNC_MQTT_PP_PROTOCOL) #define ASYNC_MQTT_PP_PACKET \ - (v3_1_1::connect_packet) \ - (v3_1_1::connack_packet) \ - (v3_1_1::pingreq_packet) \ - (v3_1_1::pingresp_packet) \ - (v3_1_1::disconnect_packet) \ - (v5::connect_packet) \ - (v5::connack_packet) \ - (v5::pingreq_packet) \ - (v5::pingresp_packet) \ - (v5::disconnect_packet) \ - (v5::auth_packet) \ + (async_mqtt::v3_1_1::connect_packet) \ + (async_mqtt::v3_1_1::connack_packet) \ + (async_mqtt::v3_1_1::pingreq_packet) \ + (async_mqtt::v3_1_1::pingresp_packet) \ + (async_mqtt::v3_1_1::disconnect_packet) \ + (async_mqtt::v5::connect_packet) \ + (async_mqtt::v5::connack_packet) \ + (async_mqtt::v5::pingreq_packet) \ + (async_mqtt::v5::pingresp_packet) \ + (async_mqtt::v5::disconnect_packet) \ + (async_mqtt::v5::auth_packet) #define ASYNC_MQTT_PP_BASIC_PACKET \ - (v3_1_1::basic_publish_packet) \ - (v3_1_1::basic_puback_packet) \ - (v3_1_1::basic_pubrec_packet) \ - (v3_1_1::basic_pubrel_packet) \ - (v3_1_1::basic_pubcomp_packet) \ - (v3_1_1::basic_subscribe_packet) \ - (v3_1_1::basic_suback_packet) \ - (v3_1_1::basic_unsubscribe_packet) \ - (v3_1_1::basic_unsuback_packet) \ - (v5::basic_publish_packet) \ - (v5::basic_puback_packet) \ - (v5::basic_pubrec_packet) \ - (v5::basic_pubrel_packet) \ - (v5::basic_pubcomp_packet) \ - (v5::basic_subscribe_packet) \ - (v5::basic_suback_packet) \ - (v5::basic_unsubscribe_packet) \ - (v5::basic_unsuback_packet) \ - (basic_packet_variant) + (async_mqtt::v3_1_1::basic_publish_packet) \ + (async_mqtt::v3_1_1::basic_puback_packet) \ + (async_mqtt::v3_1_1::basic_pubrec_packet) \ + (async_mqtt::v3_1_1::basic_pubrel_packet) \ + (async_mqtt::v3_1_1::basic_pubcomp_packet) \ + (async_mqtt::v3_1_1::basic_subscribe_packet) \ + (async_mqtt::v3_1_1::basic_suback_packet) \ + (async_mqtt::v3_1_1::basic_unsubscribe_packet) \ + (async_mqtt::v3_1_1::basic_unsuback_packet) \ + (async_mqtt::v5::basic_publish_packet) \ + (async_mqtt::v5::basic_puback_packet) \ + (async_mqtt::v5::basic_pubrec_packet) \ + (async_mqtt::v5::basic_pubrel_packet) \ + (async_mqtt::v5::basic_pubcomp_packet) \ + (async_mqtt::v5::basic_subscribe_packet) \ + (async_mqtt::v5::basic_suback_packet) \ + (async_mqtt::v5::basic_unsubscribe_packet) \ + (async_mqtt::v5::basic_unsuback_packet) \ + (async_mqtt::basic_packet_variant) \ + (async_mqtt::basic_store_packet_variant) \ #define ASYNC_MQTT_PP_BASIC_PACKET_INSTANTIATE(name, n) name #if !defined(ASYNC_MQTT_PP_VERSION) #define ASYNC_MQTT_PP_VERSION \ - (protocol_version::v3_1_1) \ - (protocol_version::v5) + (async_mqtt::protocol_version::v3_1_1) \ + (async_mqtt::protocol_version::v5) #endif // !defined(ASYNC_MQTT_PP_VERSION) #endif // ASYNC_MQTT_DETAIL_INSTANTIATE_HELPER_HPP diff --git a/include/async_mqtt/detail/stream_layer.hpp b/include/async_mqtt/detail/stream_layer.hpp new file mode 100644 index 000000000..e74440d73 --- /dev/null +++ b/include/async_mqtt/detail/stream_layer.hpp @@ -0,0 +1,67 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_DETAIL_STREAM_LAYER_HPP) +#define ASYNC_MQTT_DETAIL_STREAM_LAYER_HPP + +#include + +namespace async_mqtt::detail { + +template +std::false_type has_next_layer_impl(void*); + +template +auto has_next_layer_impl(decltype(nullptr)) -> + decltype(std::declval().next_layer(), std::true_type{}); + +template +using has_next_layer = decltype(has_next_layer_impl(nullptr)); + + +template::value> +struct lowest_layer_type_impl { + using type = typename std::remove_reference::type; +}; + +template +struct lowest_layer_type_impl { + using type = typename lowest_layer_type_impl< + decltype(std::declval().next_layer())>::type; +}; + +template +using lowest_layer_type = typename lowest_layer_type_impl::type; + +template +T& +get_lowest_layer_impl(T& t, std::false_type) noexcept { + return t; +} + +template +lowest_layer_type& +get_lowest_layer_impl(T& t, std::true_type) noexcept { + return + get_lowest_layer_impl( + t.next_layer(), + has_next_layer::type>{} + ); +} + +template +lowest_layer_type& get_lowest_layer(T& t) noexcept { + return + detail::get_lowest_layer_impl( + t, + has_next_layer{} + ); +} + +} // namespace async_mqtt::detail + + +#endif // ASYNC_MQTT_DETAIL_STREAM_LAYER_HPP diff --git a/include/async_mqtt/endpoint.hpp b/include/async_mqtt/endpoint.hpp index 64cabdeae..63c4a7129 100644 --- a/include/async_mqtt/endpoint.hpp +++ b/include/async_mqtt/endpoint.hpp @@ -7,7 +7,14 @@ #if !defined(ASYNC_MQTT_ENDPOINT_HPP) #define ASYNC_MQTT_ENDPOINT_HPP -#include +#include +#include + +#include +#include +#include +#include +#include /** * @defgroup connection MQTT connection @@ -20,29 +27,16 @@ namespace async_mqtt { -/** - * @ingroup endpoint - * @brief receive packet filter - */ -enum class filter { - match, ///< matched control_packet_type is target - except ///< no matched control_packet_type is target -}; - template class basic_endpoint { using this_type = basic_endpoint; using impl_type = detail::basic_endpoint_impl; - using stream_type = - stream< - NextLayer - >; public: /// @brief type of the given NextLayer - using next_layer_type = typename stream_type::next_layer_type; + using next_layer_type = NextLayer; /// @brief lowest_layer_type of the given NextLayer - using lowest_layer_type = typename stream_type::lowest_layer_type; + using lowest_layer_type = detail::lowest_layer_type; /// @brief executor_type of the given NextLayer using executor_type = typename next_layer_type::executor_type; @@ -121,6 +115,20 @@ class basic_endpoint { */ lowest_layer_type& lowest_layer(); + /** + * @brief notify underlying layer accepted to the endpoint + * \n This function should be called when the underlying server connection is accepted + */ + void underlying_accepted(); + + /** + * @brief set offline publish support + * \n This function should be called before async_send() call. + * @note By default offline publish is not supported. + * @param val if true, offline publish is supported, otherwise not supported + */ + void set_offline_publish(bool val); + /** * @brief auto publish response setter. Should be called before async_send()/async_recv() call. * @note By default not automatically sending. @@ -165,6 +173,27 @@ class basic_endpoint { */ void set_pingresp_recv_timeout(std::chrono::milliseconds duration); + /** + * @brief Set delay value for closing the stream after sending DISCONNECT packet. + * If the timer is fired, then the underlying layer stream starts closing. + * \n This function should be called before async_send() call. + * @note By default timeout is not set. + * @param duration if zero, timer is not set so close process starts immediately; + * otherwise after duration passed, close process will start. + * The minimum resolution is in milliseconds. + */ + + /** + * @brief Sets the delay duration for closing the stream after sending the DISCONNECT packet. + * If the timer expires, the underlying layer stream will begin closing. + * \n This function must be called before the `async_send()` function. + * @note By default, no delay is set. + * @param duration If set to zero, the timer is not activated, and the close process starts immediately. + * Otherwise, the close process begins after the specified duration has elapsed. + * The minimum resolution is in milliseconds. + */ + void set_close_delay_after_disconnect_sent(std::chrono::milliseconds duration); + /** * @brief Set bulk write mode. * If true, then concatenate multiple packets' const buffer sequence @@ -177,20 +206,27 @@ class basic_endpoint { void set_bulk_write(bool val); /** - * @brief Set the bulk read buffer size. - * If bulk read is enabled, the `val` parameter specifies the size of the internal - * `async_read_some()` buffer. - * Enabling bulk read can improve throughput but may increase latency. - * Disabling bulk read can reduce latency but may lower throughput. - * By default, bulk read is disabled. + * @brief Set the read buffer size. + * If bulk read is enabled, the `val` parameter specifies the size of the internal streambuf. + * The default size is 65535. + * \n This function should be called before async_recv() call. * - * @param val If set to 0, bulk read is disabled. Otherwise, it specifies the buffer size. + * @param val buffer size. */ - void set_bulk_read_buffer_size(std::size_t val); + void set_read_buffer_size(std::size_t val); // async functions + // TBD doc later + template < + typename... Args + > + auto + async_underlying_handshake( + Args&&... args + ); + /** * @brief acuire unique packet_id. * @param token see Signature @@ -362,15 +398,15 @@ class basic_endpoint { * @li Default Completion Token is supported * * #### Signature - * void(@ref error_code, @ref packet_variant_type) + * void(@ref error_code, std::optional<@ref packet_variant_type>) * * ##### error_code and packet_variant_type * @li If an error occurs at an underlying layer while receiving a packet, * underlying error is set. e.g. system, asio, beast, ... - * @ref packet_variant_type is set to std::monostate + * std::optional<@ref packet_variant_type> is set to std::nullopt. * @li If there are no errors during receiving the packet, * errc::success is set. - * @ref packet_variant_type is set to @ref basic_packet_variant. + * std::optional<@ref packet_variant_type> is set to @ref basic_packet_variant. * * ### Per-Operation Cancellation * @@ -401,15 +437,15 @@ class basic_endpoint { * @li Default Completion Token is supported * * #### Signature - * void(@ref error_code, @ref packet_variant_type) + * void(@ref error_code, std::optional<@ref packet_variant_type>) * * ##### error_code and packet_variant_type * @li If an error occurs at an underlying layer while receiving a packet, * underlying error is set. e.g. system, asio, beast, ... - * @ref packet_variant_type is set to std::monostate + * std::optional<@ref packet_variant_type> is set to std::nullopt. * @li If there are no errors during receiving the packet, * errc::success is set. - * @ref packet_variant_type is set to @ref basic_packet_variant. + * std::optional<@ref packet_variant_type> is set to @ref basic_packet_variant. * * ### Per-Operation Cancellation * @@ -442,15 +478,15 @@ class basic_endpoint { * @li Default Completion Token is supported * * #### Signature - * void(@ref error_code, @ref packet_variant_type) + * void(@ref error_code, std::optional<@ref packet_variant_type>) * * ##### error_code and packet_variant_type * @li If an error occurs at an underlying layer while receiving a packet, * underlying error is set. e.g. system, asio, beast, ... - * @ref packet_variant_type is set to std::monostate + * std::optional<@ref packet_variant_type> is set to std::nullopt. * @li If there are no errors during receiving the packet, * errc::success is set. - * @ref packet_variant_type is set to @ref basic_packet_variant. + * std::optional<@ref packet_variant_type> is set to @ref basic_packet_variant. * * ### Per-Operation Cancellation * @@ -663,11 +699,14 @@ class basic_endpoint { ) const; /** - * @brief Set PINGREQ packet sending interval. - * @note By default, PINGREQ packet sending interval is set the same value as - * CONNECT packet keep alive seconds. - * This function overrides it. - * @param duration if zero, timer is not set; otherwise duration is set. + * @brief Set the PINGREQ packet sending interval. + * + * @note By default, the PINGREQ packet sending interval is set to the same value as the + * CONNECT packet's keep-alive duration in seconds. If the CONNACK packet includes + * the Server Keep Alive property, its value (in seconds) is used instead. + * This function overrides the default value. + * + * @param duration If set to zero, the timer is disabled; otherwise, the specified duration is used. * The minimum resolution is in milliseconds. */ void set_pingreq_send_interval(std::chrono::milliseconds duration); @@ -702,7 +741,8 @@ class basic_endpoint { } // namespace async_mqtt -#include +#include +#include #include #include #include @@ -713,6 +753,5 @@ class basic_endpoint { #include #include #include -#include #endif // ASYNC_MQTT_ENDPOINT_HPP diff --git a/include/async_mqtt/endpoint_fwd.hpp b/include/async_mqtt/endpoint_fwd.hpp index 02a427548..8adbf2a42 100644 --- a/include/async_mqtt/endpoint_fwd.hpp +++ b/include/async_mqtt/endpoint_fwd.hpp @@ -9,7 +9,7 @@ #include // for std::size_t -#include +#include namespace async_mqtt { diff --git a/include/async_mqtt/filter.hpp b/include/async_mqtt/filter.hpp new file mode 100644 index 000000000..30459c485 --- /dev/null +++ b/include/async_mqtt/filter.hpp @@ -0,0 +1,23 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_FILTER_HPP) +#define ASYNC_MQTT_FILTER_HPP + +namespace async_mqtt { + +/** + * @ingroup endpoint + * @brief receive packet filter + */ +enum class filter { + match, ///< matched control_packet_type is target + except ///< no matched control_packet_type is target +}; + +} // namespace async_mqtt + +#endif // ASYNC_MQTT_FILTER_HPP diff --git a/include/async_mqtt/impl/client_acquire_unique_packet_id.hpp b/include/async_mqtt/impl/client_acquire_unique_packet_id.hpp index c20ae3afe..20d7a508c 100644 --- a/include/async_mqtt/impl/client_acquire_unique_packet_id.hpp +++ b/include/async_mqtt/impl/client_acquire_unique_packet_id.hpp @@ -8,31 +8,10 @@ #define ASYNC_MQTT_IMPL_CLIENT_ACQUIRE_UNIQUE_PACKET_ID_HPP #include +#include namespace async_mqtt { -namespace detail { - -template -template -auto -client_impl::async_acquire_unique_packet_id( - CompletionToken&& token -) { - return ep_.async_acquire_unique_packet_id(std::forward(token)); -} - -// sync version - -template -inline -std::optional -client_impl::acquire_unique_packet_id() { - return ep_.acquire_unique_packet_id(); -} - -} // namespace detail - template template auto @@ -40,7 +19,23 @@ client::async_acquire_unique_packet_id( CompletionToken&& token ) { BOOST_ASSERT(impl_); - return impl_->async_acquire_unique_packet_id(std::forward(token)); + return + as::async_initiate< + CompletionToken, + void(error_code, packet_id_type) + >( + []( + auto handler, + std::shared_ptr impl + ) { + impl_type::async_acquire_unique_packet_id( + force_move(impl), + force_move(handler) + ); + }, + token, + impl_ + ); } // sync version @@ -55,4 +50,8 @@ client::acquire_unique_packet_id() { } // namespace async_mqtt +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + #endif // ASYNC_MQTT_IMPL_CLIENT_ACQUIRE_UNIQUE_PACKET_ID_HPP diff --git a/include/async_mqtt/impl/client_acquire_unique_packet_id.ipp b/include/async_mqtt/impl/client_acquire_unique_packet_id.ipp new file mode 100644 index 000000000..afb12abb2 --- /dev/null +++ b/include/async_mqtt/impl/client_acquire_unique_packet_id.ipp @@ -0,0 +1,41 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_CLIENT_ACQUIRE_UNIQUE_PACKET_ID_IPP) +#define ASYNC_MQTT_IMPL_CLIENT_ACQUIRE_UNIQUE_PACKET_ID_IPP + +#include +#include +#include + +namespace async_mqtt::detail { + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +client_impl::async_acquire_unique_packet_id( + this_type_sp impl, + as::any_completion_handler< + void(error_code, packet_id_type) + > handler +) { + impl->ep_.async_acquire_unique_packet_id(force_move(handler)); +} + +// sync version + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +std::optional +client_impl::acquire_unique_packet_id() { + return ep_.acquire_unique_packet_id(); +} + +} // namespace async_mqtt::detail + +#include + +#endif // ASYNC_MQTT_IMPL_CLIENT_ACQUIRE_UNIQUE_PACKET_ID_IPP diff --git a/include/async_mqtt/impl/client_acquire_unique_packet_id_wait_until.hpp b/include/async_mqtt/impl/client_acquire_unique_packet_id_wait_until.hpp index 984f38fa8..44ea7e336 100644 --- a/include/async_mqtt/impl/client_acquire_unique_packet_id_wait_until.hpp +++ b/include/async_mqtt/impl/client_acquire_unique_packet_id_wait_until.hpp @@ -8,22 +8,10 @@ #define ASYNC_MQTT_IMPL_CLIENT_ACQUIRE_UNIQUE_PACKET_ID_WAIT_UNTIL_HPP #include +#include namespace async_mqtt { -namespace detail { - -template -template -auto -client_impl::async_acquire_unique_packet_id_wait_until( - CompletionToken&& token -) { - return ep_.async_acquire_unique_packet_id_wait_until(std::forward(token)); -} - -} // namespace detail - template template auto @@ -31,9 +19,29 @@ client::async_acquire_unique_packet_id_wait_until( CompletionToken&& token ) { BOOST_ASSERT(impl_); - return impl_->async_acquire_unique_packet_id_wait_until(std::forward(token)); + return + as::async_initiate< + CompletionToken, + void(error_code, packet_id_type) + >( + []( + auto handler, + std::shared_ptr impl + ) { + impl_type::async_acquire_unique_packet_id_wait_until( + force_move(impl), + force_move(handler) + ); + }, + token, + impl_ + ); } } // namespace async_mqtt +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + #endif // ASYNC_MQTT_IMPL_CLIENT_ACQUIRE_UNIQUE_PACKET_ID_WAIT_UNTIL_HPP diff --git a/include/async_mqtt/impl/client_acquire_unique_packet_id_wait_until.ipp b/include/async_mqtt/impl/client_acquire_unique_packet_id_wait_until.ipp new file mode 100644 index 000000000..8148b6ec0 --- /dev/null +++ b/include/async_mqtt/impl/client_acquire_unique_packet_id_wait_until.ipp @@ -0,0 +1,32 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_CLIENT_ACQUIRE_UNIQUE_PACKET_ID_WAIT_UNTIL_IPP) +#define ASYNC_MQTT_IMPL_CLIENT_ACQUIRE_UNIQUE_PACKET_ID_WAIT_UNTIL_IPP + +#include +#include +#include + +namespace async_mqtt::detail { + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +client_impl::async_acquire_unique_packet_id_wait_until( + this_type_sp impl, + as::any_completion_handler< + void(error_code, packet_id_type) + > handler +) { + impl->ep_.async_acquire_unique_packet_id_wait_until(force_move(handler)); +} + +} // namespace async_mqtt::detail + +#include + +#endif // ASYNC_MQTT_IMPL_CLIENT_ACQUIRE_UNIQUE_PACKET_ID_WAIT_UNTIL_IPP diff --git a/include/async_mqtt/impl/client_auth.hpp b/include/async_mqtt/impl/client_auth.hpp index 9df1294f7..f391350a3 100644 --- a/include/async_mqtt/impl/client_auth.hpp +++ b/include/async_mqtt/impl/client_auth.hpp @@ -13,8 +13,9 @@ #include #include +#include #include -#include +#include namespace async_mqtt { @@ -22,45 +23,13 @@ namespace hana = boost::hana; namespace detail { -template -struct client_impl:: -auth_op { - this_type_sp cl; - error_code ec; - std::optional packet; - - template - void operator()( - Self& self - ) { - auto& a_cl{*cl}; - if (ec) { - self.complete(ec); - return; - } - auto a_packet{force_move(*packet)}; - a_cl.ep_.async_send( - force_move(a_packet), - force_move(self) - ); - } - - template - void operator()( - Self& self, - error_code const& ec - ) { - self.complete(ec); - } -}; - template template auto -client_impl::async_auth_impl( +client_impl::async_auth( this_type_sp impl, error_code ec, - std::optional packet, + std::optional packet, CompletionToken&& token ) { BOOST_ASSERT(impl); @@ -71,17 +40,27 @@ client_impl::async_auth_impl( } auto exe = impl->get_executor(); return - as::async_compose< + as::async_initiate< CompletionToken, void(error_code) >( - auth_op{ - force_move(impl), - ec, - force_move(packet) + []( + auto handler, + this_type_sp impl, + error_code ec, + std::optional packet + ) { + async_auth_impl( + force_move(impl), + ec, + force_move(packet), + force_move(handler) + ); }, token, - exe + force_move(impl), + ec, + force_move(packet) ); } @@ -92,16 +71,16 @@ template auto client::async_auth(Args&&... args) { BOOST_ASSERT(impl_); - if constexpr (std::is_constructible_v(args))...>) { + if constexpr (std::is_constructible_v(args))...>) { try { - return impl_type::async_auth_impl( + return impl_type::async_auth( impl_, error_code{}, - v5::auth_packet{std::forward(args)...} + auth_packet{std::forward(args)...} ); } catch (system_error const& se) { - return impl_type::async_auth_impl( + return impl_type::async_auth( impl_, se.code(), std::nullopt @@ -109,33 +88,33 @@ client::async_auth(Args&&... args) { } } else { - auto t = hana::tuple(std::forward(args)...); - auto rest = hana::drop_back(std::move(t), hana::size_c<1>); - auto&& back = hana::back(t); + auto all = hana::tuple(std::forward(args)...); + auto back = hana::back(all); + auto rest = hana::drop_back(all, hana::size_c<1>); return hana::unpack( std::move(rest), [&](auto&&... rest_args) { static_assert( std::is_constructible_v< - v5::auth_packet, + auth_packet, decltype(rest_args)... >, "v5::auth_packet is not constructible" ); try { - return impl_type::async_auth_impl( + return impl_type::async_auth( impl_, error_code{}, - v5::auth_packet{std::forward(rest_args)...}, - std::forward(back) + auth_packet{std::forward(rest_args)...}, + force_move(back) ); } catch (system_error const& se) { - return impl_type::async_auth_impl( + return impl_type::async_auth( impl_, se.code(), std::nullopt, - std::forward(back) + force_move(back) ); } } @@ -145,4 +124,8 @@ client::async_auth(Args&&... args) { } // namespace async_mqtt +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + #endif // ASYNC_MQTT_IMPL_CLIENT_AUTH_HPP diff --git a/include/async_mqtt/impl/client_auth.ipp b/include/async_mqtt/impl/client_auth.ipp new file mode 100644 index 000000000..e5134cfb0 --- /dev/null +++ b/include/async_mqtt/impl/client_auth.ipp @@ -0,0 +1,88 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_CLIENT_AUTH_IPP) +#define ASYNC_MQTT_IMPL_CLIENT_AUTH_IPP + +#include +#include +#include +#include +#include + +namespace async_mqtt::detail { + +template +struct client_impl:: +auth_op { + this_type_sp cl; + error_code ec; + std::optional packet; + + template + void operator()( + Self& self + ) { + auto& a_cl{*cl}; + if (ec) { + self.complete(ec); + return; + } + auto a_packet{force_move(*packet)}; + a_cl.ep_.async_send( + force_move(a_packet), + force_move(self) + ); + } + + template + void operator()( + Self& self, + error_code const& ec + ) { + self.complete(ec); + } +}; + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +client_impl::async_auth_impl( + this_type_sp impl, + error_code ec, + std::optional packet, + as::any_completion_handler< + void(error_code) + > handler +) { + BOOST_ASSERT(impl); + if (packet) { + ASYNC_MQTT_LOG("mqtt_api", info) + << ASYNC_MQTT_ADD_VALUE(address, impl.get()) + << *packet; + } + auto exe = impl->get_executor(); + as::async_compose< + as::any_completion_handler< + void(error_code) + >, + void(error_code) + >( + auth_op{ + force_move(impl), + ec, + force_move(packet) + }, + handler, + exe + ); +} + +} // namespace async_mqtt::detail + +#include + +#endif // ASYNC_MQTT_IMPL_CLIENT_AUTH_IPP diff --git a/include/async_mqtt/impl/client_close.hpp b/include/async_mqtt/impl/client_close.hpp index 856e737cf..4e1f2d3c3 100644 --- a/include/async_mqtt/impl/client_close.hpp +++ b/include/async_mqtt/impl/client_close.hpp @@ -8,22 +8,10 @@ #define ASYNC_MQTT_IMPL_CLIENT_CLOSE_HPP #include +#include namespace async_mqtt { -namespace detail { - -template -template -auto -client_impl::async_close( - CompletionToken&& token -) { - return ep_.async_close(std::forward(token)); -} - -} // namespace detail - template template auto @@ -31,9 +19,29 @@ client::async_close( CompletionToken&& token ) { BOOST_ASSERT(impl_); - return impl_->async_close(std::forward(token)); + return + as::async_initiate< + CompletionToken, + void() + >( + []( + auto handler, + std::shared_ptr impl + ) { + impl_type::async_close( + force_move(impl), + force_move(handler) + ); + }, + token, + impl_ + ); } } // namespace async_mqtt +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + #endif // ASYNC_MQTT_IMPL_CLIENT_CLOSE_HPP diff --git a/include/async_mqtt/impl/client_close.ipp b/include/async_mqtt/impl/client_close.ipp new file mode 100644 index 000000000..33a395cbf --- /dev/null +++ b/include/async_mqtt/impl/client_close.ipp @@ -0,0 +1,32 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_CLIENT_CLOSE_IPP) +#define ASYNC_MQTT_IMPL_CLIENT_CLOSE_IPP + +#include +#include +#include + +namespace async_mqtt::detail { + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +client_impl::async_close( + this_type_sp impl, + as::any_completion_handler< + void() + > handler +) { + impl->ep_.async_close(force_move(handler)); +} + +} // namespace async_mqtt::detail + +#include + +#endif // ASYNC_MQTT_IMPL_CLIENT_CLOSE_IPP diff --git a/include/async_mqtt/impl/client_disconnect.hpp b/include/async_mqtt/impl/client_disconnect.hpp index 377e68fcd..10b2daaaa 100644 --- a/include/async_mqtt/impl/client_disconnect.hpp +++ b/include/async_mqtt/impl/client_disconnect.hpp @@ -13,6 +13,7 @@ #include #include +#include #include namespace async_mqtt { @@ -21,42 +22,10 @@ namespace hana = boost::hana; namespace detail { -template -struct client_impl:: -disconnect_op { - this_type_sp cl; - error_code ec; - std::optional packet; - - template - void operator()( - Self& self - ) { - auto& a_cl{*cl}; - if (ec) { - self.complete(ec); - return; - } - auto a_packet{force_move(*packet)}; - a_cl.ep_.async_send( - force_move(a_packet), - force_move(self) - ); - } - - template - void operator()( - Self& self, - error_code const& ec - ) { - self.complete(ec); - } -}; - template template auto -client_impl::async_disconnect_impl( +client_impl::async_disconnect( this_type_sp impl, error_code ec, std::optional packet, @@ -70,17 +39,27 @@ client_impl::async_disconnect_impl( } auto exe = impl->get_executor(); return - as::async_compose< + as::async_initiate< CompletionToken, void(error_code) >( - disconnect_op{ - force_move(impl), - ec, - force_move(packet) + []( + auto handler, + this_type_sp impl, + error_code ec, + std::optional packet + ) { + async_disconnect_impl( + force_move(impl), + ec, + force_move(packet), + force_move(handler) + ); }, token, - exe + force_move(impl), + ec, + force_move(packet) ); } @@ -93,14 +72,14 @@ client::async_disconnect(Args&&... args) { BOOST_ASSERT(impl_); if constexpr (std::is_constructible_v(args))...>) { try { - return impl_type::async_disconnect_impl( + return impl_type::async_disconnect( impl_, error_code{}, disconnect_packet{std::forward(args)...} ); } catch (system_error const& se) { - return impl_type::async_disconnect_impl( + return impl_type::async_disconnect( impl_, se.code(), std::nullopt @@ -108,9 +87,9 @@ client::async_disconnect(Args&&... args) { } } else { - auto t = hana::tuple(std::forward(args)...); - auto rest = hana::drop_back(std::move(t), hana::size_c<1>); - auto&& back = hana::back(t); + auto all = hana::tuple(std::forward(args)...); + auto back = hana::back(all); + auto rest = hana::drop_back(all, hana::size_c<1>); return hana::unpack( std::move(rest), [&](auto&&... rest_args) { @@ -122,19 +101,19 @@ client::async_disconnect(Args&&... args) { "disconnect_packet is not constructible" ); try { - return impl_type::async_disconnect_impl( + return impl_type::async_disconnect( impl_, error_code{}, disconnect_packet{std::forward(rest_args)...}, - std::forward(back) + force_move(back) ); } catch (system_error const& se) { - return impl_type::async_disconnect_impl( + return impl_type::async_disconnect( impl_, se.code(), std::nullopt, - std::forward(back) + force_move(back) ); } } @@ -144,4 +123,8 @@ client::async_disconnect(Args&&... args) { } // namespace async_mqtt +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + #endif // ASYNC_MQTT_IMPL_CLIENT_DISCONNECT_HPP diff --git a/include/async_mqtt/impl/client_disconnect.ipp b/include/async_mqtt/impl/client_disconnect.ipp new file mode 100644 index 000000000..9988fdf86 --- /dev/null +++ b/include/async_mqtt/impl/client_disconnect.ipp @@ -0,0 +1,82 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_CLIENT_DISCONNECT_IPP) +#define ASYNC_MQTT_IMPL_CLIENT_DISCONNECT_IPP + +#include +#include +#include +#include + +namespace async_mqtt::detail { + +template +struct client_impl:: +disconnect_op { + this_type_sp cl; + error_code ec; + std::optional packet; + + template + void operator()( + Self& self + ) { + auto& a_cl{*cl}; + if (ec) { + self.complete(ec); + return; + } + auto a_packet{force_move(*packet)}; + a_cl.ep_.async_send( + force_move(a_packet), + force_move(self) + ); + } + + template + void operator()( + Self& self, + error_code const& ec + ) { + self.complete(ec); + } +}; + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +client_impl::async_disconnect_impl( + this_type_sp impl, + error_code ec, + std::optional packet, + as::any_completion_handler< + void(error_code) + > handler +) { + BOOST_ASSERT(impl); + auto exe = impl->get_executor(); + as::async_compose< + as::any_completion_handler< + void(error_code) + >, + void(error_code) + >( + disconnect_op{ + force_move(impl), + ec, + force_move(packet) + }, + handler, + exe + ); +} + +} // namespace async_mqtt::detail + +#include + +#endif // ASYNC_MQTT_IMPL_CLIENT_DISCONNECT_IPP diff --git a/include/async_mqtt/impl/client_impl.hpp b/include/async_mqtt/impl/client_impl.hpp index 14e8c19c4..9e62b57da 100644 --- a/include/async_mqtt/impl/client_impl.hpp +++ b/include/async_mqtt/impl/client_impl.hpp @@ -4,317 +4,379 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_CLIENT_IMPL_HPP) -#define ASYNC_MQTT_CLIENT_IMPL_HPP +#if !defined(ASYNC_MQTT_IMPL_CLIENT_IMPL_HPP) +#define ASYNC_MQTT_IMPL_CLIENT_IMPL_HPP + +#include +#include #include #include #include +#include +#include +#include -#include +#include +#include +#include #include +#include +#include +#include + +namespace async_mqtt::detail { -namespace async_mqtt { +namespace as = boost::asio; namespace mi = boost::multi_index; -namespace detail { +template +class client_impl { + using this_type = client_impl; + using this_type_sp = std::shared_ptr; + using client_type = client; + +public: + using endpoint_type = basic_endpoint; + using next_layer_type = NextLayer; + using lowest_layer_type = detail::lowest_layer_type; + using executor_type = typename next_layer_type::executor_type; + + template + explicit + client_impl( + Args&&... args + ); + client_impl(this_type const&) = delete; + client_impl(this_type&&) = delete; + ~client_impl() = default; + + this_type& operator=(this_type const&) = delete; + this_type& operator=(this_type&&) = delete; + + template < + typename... Args + > + auto + async_underlying_handshake( + Args&&... args + ); + + as::any_io_executor get_executor(); + next_layer_type const& next_layer() const; + next_layer_type& next_layer(); + lowest_layer_type const& lowest_layer() const; + lowest_layer_type& lowest_layer(); + endpoint_type const& get_endpoint() const; + endpoint_type& get_endpoint(); + + void set_auto_map_topic_alias_send(bool val); + void set_auto_replace_topic_alias_send(bool val); + void set_pingresp_recv_timeout(std::chrono::milliseconds duration); + void set_close_delay_after_disconnect_sent(std::chrono::milliseconds duration); + void set_bulk_write(bool val); + void set_read_buffer_size(std::size_t val); + + std::optional acquire_unique_packet_id(); + bool register_packet_id(packet_id_type packet_id); + void release_packet_id(packet_id_type packet_id); + + template + struct rebind_executor { + using other = client_impl< + Version, + typename NextLayer::template rebind_executor::other + >; + }; -// classes +private: + friend class client; + + template + explicit + client_impl( + client_impl&& other + ); + + static + void + async_acquire_unique_packet_id( + this_type_sp impl, + as::any_completion_handler< + void(error_code, packet_id_type) + > handler + ); + + static + void + async_acquire_unique_packet_id_wait_until( + this_type_sp impl, + as::any_completion_handler< + void(error_code, packet_id_type) + > handler + ); + + static + void + async_register_packet_id( + this_type_sp impl, + packet_id_type packet_id, + as::any_completion_handler< + void(error_code) + > handler + ); + + static + void + async_release_packet_id( + this_type_sp impl, + packet_id_type packet_id, + as::any_completion_handler< + void() + > handler + ); + + template < + typename CompletionToken = as::default_completion_token_t + > + static + auto + async_start( + this_type_sp impl, + error_code ec, + std::optional packet, + CompletionToken&& token = as::default_completion_token_t{} + ); + + static + void + async_start_impl( + this_type_sp impl, + error_code ec, + std::optional packet, + as::any_completion_handler< + void(error_code, std::optional) + > handler + ); + + template < + typename CompletionToken = as::default_completion_token_t + > + static + auto + async_subscribe( + this_type_sp impl, + error_code ec, + std::optional packet, + CompletionToken&& token = as::default_completion_token_t{} + ); + + static + void + async_subscribe_impl( + this_type_sp impl, + error_code ec, + std::optional packet, + as::any_completion_handler< + void(error_code, std::optional) + > handler + ); + + template < + typename CompletionToken = as::default_completion_token_t + > + static + auto + async_unsubscribe( + this_type_sp impl, + error_code ec, + std::optional packet, + CompletionToken&& token = as::default_completion_token_t{} + ); + + static + void + async_unsubscribe_impl( + this_type_sp impl, + error_code ec, + std::optional packet, + as::any_completion_handler< + void(error_code, std::optional) + > handler + ); + + template < + typename CompletionToken = as::default_completion_token_t + > + static + auto + async_publish( + this_type_sp impl, + error_code ec, + std::optional packet, + CompletionToken&& token = as::default_completion_token_t{} + ); + + static + void + async_publish_impl( + this_type_sp impl, + error_code ec, + std::optional packet, + as::any_completion_handler< + void(error_code, typename client_type::pubres_type) + > handler + ); + + template < + typename CompletionToken = as::default_completion_token_t + > + static + auto + async_disconnect( + this_type_sp impl, + error_code ec, + std::optional packet, + CompletionToken&& token = as::default_completion_token_t{} + ); + + static + void + async_disconnect_impl( + this_type_sp impl, + error_code ec, + std::optional packet, + as::any_completion_handler< + void(error_code) + > handler + ); + + template < + typename CompletionToken = as::default_completion_token_t + > + static + auto + async_auth( + this_type_sp impl, + error_code ec, + std::optional packet, + CompletionToken&& token = as::default_completion_token_t{} + ); + + static + void + async_auth_impl( + this_type_sp impl, + error_code ec, + std::optional packet, + as::any_completion_handler< + void(error_code) + > handler + ); + + static + void + async_recv( + this_type_sp impl, + as::any_completion_handler< + void(error_code, std::optional) + > handler + ); + + static + void + async_close( + this_type_sp impl, + as::any_completion_handler< + void() + > handler + ); + + + static void recv_loop(this_type_sp impl); + + // async operations + struct start_op; + struct subscribe_op; + struct unsubscribe_op; + struct publish_op; + struct disconnect_op; + struct auth_op; + struct recv_op; + + // internal types + struct pid_tim_pv_res_col { + struct elem_type { + explicit elem_type( + packet_id_type pid, + std::shared_ptr tim + ): pid{pid}, + tim{force_move(tim)} + { + } + explicit elem_type( + std::shared_ptr tim + ): tim{force_move(tim)} + { + } + + packet_id_type pid = 0; + std::shared_ptr tim; + std::optional pv; + typename client_type::pubres_type res; + }; + + struct tag_pid {}; + struct tag_tim {}; + + auto& get_pid_idx() { + return elems.template get(); + } + auto& get_tim_idx() { + return elems.template get(); + } + void clear() { + for (auto& elem : elems) { + const_cast(*elem.tim).cancel(); + } + elems.clear(); + } + using mi_elem_type = mi::multi_index_container< + elem_type, + mi::indexed_by< + mi::ordered_unique< + mi::tag, + mi::key<&elem_type::pid> + >, + mi::ordered_unique< + mi::tag, + mi::key<&elem_type::tim> + > + > + >; + mi_elem_type elems; + }; -template -struct client_impl::pid_tim_pv_res_col { - struct elem_type { - explicit elem_type( - packet_id_type pid, - std::shared_ptr tim - ): pid{pid}, - tim{force_move(tim)} + struct recv_type { + explicit recv_type(packet_variant packet) + :pv{force_move(packet)} { } - explicit elem_type( - std::shared_ptr tim - ): tim{force_move(tim)} + explicit recv_type(error_code ec) + :ec{ec} { } - - packet_id_type pid = 0; - std::shared_ptr tim; + error_code ec = error_code{}; std::optional pv; - typename client_type::pubres_type res; }; - struct tag_pid {}; - struct tag_tim {}; - - auto& get_pid_idx() { - return elems.template get(); - } - auto& get_tim_idx() { - return elems.template get(); - } - using mi_elem_type = mi::multi_index_container< - elem_type, - mi::indexed_by< - mi::ordered_unique< - mi::tag, - mi::key<&elem_type::pid> - >, - mi::ordered_unique< - mi::tag, - mi::key<&elem_type::tim> - > - > - >; - mi_elem_type elems; -}; - -template -struct client_impl::recv_type { - explicit recv_type(packet_variant packet) - :pv{force_move(packet)} - { - } - explicit recv_type(error_code ec) - :ec{ec} - { - } - error_code ec = error_code{}; - packet_variant pv; + endpoint_type ep_; + pid_tim_pv_res_col pid_tim_pv_res_col_; + std::deque recv_queue_; + bool recv_queue_inserted_ = false; + as::steady_timer tim_notify_publish_recv_; }; +} // namespace async_mqtt::detail -// member functions - -template -template -client_impl::client_impl( - Args&&... args -): ep_{Version, std::forward(args)...}, - tim_notify_publish_recv_{ep_.get_executor()} -{ - ep_.set_auto_pub_response(true); - ep_.set_auto_ping_response(true); -} - -template -template -client_impl::client_impl( - client_impl&& other -): ep_{Version, force_move(other.next_layer())}, - tim_notify_publish_recv_{ep_.get_executor()} -{ - ep_.set_auto_pub_response(true); - ep_.set_auto_ping_response(true); -} - -template -inline -as::any_io_executor -client_impl::get_executor() { - return ep_.get_executor(); -} - -template -inline -typename client_impl::next_layer_type const& -client_impl::next_layer() const { - return ep_.next_layer(); -} - -template -inline -typename client_impl::next_layer_type& -client_impl::next_layer() { - return ep_.next_layer(); -} - -template -inline -typename client_impl::lowest_layer_type const& -client_impl::lowest_layer() const { - return ep_.lowest_layer(); -} - -template -inline -typename client_impl::lowest_layer_type& -client_impl::lowest_layer() { - return ep_.lowest_layer(); -} - -template -inline -typename client_impl::endpoint_type const& -client_impl::get_endpoint() const { - return ep_; -} - -template -inline -typename client_impl::endpoint_type& -client_impl::get_endpoint() { - return ep_; -} - -template -inline -void -client_impl::set_auto_map_topic_alias_send(bool val) { - ep_.set_auto_map_topic_alias_send(val); -} - -template -inline -void -client_impl::set_auto_replace_topic_alias_send(bool val) { - ep_.set_auto_replace_topic_alias_send(val); -} - -template -inline -void -client_impl::set_pingresp_recv_timeout( - std::chrono::milliseconds duration -) { - ep_.set_pingresp_recv_timeout(duration); -} - -template -inline -void -client_impl::set_bulk_write(bool val) { - ep_.set_bulk_write(val); -} - -template -inline -void -client_impl::set_bulk_read_buffer_size(std::size_t val) { - ep_.set_bulk_read_buffer_size(val); -} - -} // namespace detail - -// member functions - -template -template -client::client( - Args&&... args -): impl_{std::make_shared(std::forward(args)...)} -{ -} - -template -template -client::client( - client&& other -): impl_{force_move(other.impl_)} -{ -} - -template -inline -as::any_io_executor -client::get_executor() { - BOOST_ASSERT(impl_); - return impl_->get_executor(); -} - -template -inline -typename client::next_layer_type const& -client::next_layer() const { - BOOST_ASSERT(impl_); - return impl_->next_layer(); -} - -template -inline -typename client::next_layer_type& -client::next_layer() { - BOOST_ASSERT(impl_); - return impl_->next_layer(); -} - -template -inline -typename client::lowest_layer_type const& -client::lowest_layer() const { - BOOST_ASSERT(impl_); - return impl_->lowest_layer(); -} - -template -inline -typename client::lowest_layer_type& -client::lowest_layer() { - BOOST_ASSERT(impl_); - return impl_->lowest_layer(); -} - -template -inline -typename client::endpoint_type const& -client::get_endpoint() const { - BOOST_ASSERT(impl_); - return impl_->get_endpoint(); -} - -template -inline -typename client::endpoint_type& -client::get_endpoint() { - BOOST_ASSERT(impl_); - return impl_->get_endpoint(); -} - -template -inline -void -client::set_auto_map_topic_alias_send(bool val) { - BOOST_ASSERT(impl_); - impl_->set_auto_map_topic_alias_send(val); -} - -template -inline -void -client::set_auto_replace_topic_alias_send(bool val) { - BOOST_ASSERT(impl_); - impl_->set_auto_replace_topic_alias_send(val); -} - -template -inline -void -client::set_pingresp_recv_timeout( - std::chrono::milliseconds duration -) { - BOOST_ASSERT(impl_); - impl_->set_pingresp_recv_timeout(duration); -} - -template -inline -void -client::set_bulk_write(bool val) { - BOOST_ASSERT(impl_); - impl_->set_bulk_write(val); -} - -template -inline -void -client::set_bulk_read_buffer_size(std::size_t val) { - BOOST_ASSERT(impl_); - impl_->set_bulk_read_buffer_size(val); -} - -} // namespace async_mqtt - -#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include -#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) - -#endif // ASYNC_MQTT_CLIENT_IMPL_HPP +#endif // ASYNC_MQTT_IMPL_CLIENT_IMPL_HPP diff --git a/include/async_mqtt/impl/client_instantiate.hpp b/include/async_mqtt/impl/client_instantiate.hpp new file mode 100644 index 000000000..a0694e128 --- /dev/null +++ b/include/async_mqtt/impl/client_instantiate.hpp @@ -0,0 +1,39 @@ +// Copyright Takatoshi Kondo 2024 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_CLIENT_INSTANTIATE_HPP) +#define ASYNC_MQTT_IMPL_CLIENT_INSTANTIATE_HPP + +#if defined(ASYNC_MQTT_SEPARATE_COMPILATION) + +#include + +#define ASYNC_MQTT_INSTANTIATE_EACH(a_version, a_protocol) \ +namespace async_mqtt { \ +namespace detail { \ +template \ +class client_impl; \ +} \ +template \ +class client; \ +} // namespace async_mqtt + +#define ASYNC_MQTT_PP_GENERATE(r, product) \ + BOOST_PP_EXPAND( \ + ASYNC_MQTT_INSTANTIATE_EACH \ + BOOST_PP_SEQ_TO_TUPLE( \ + product \ + ) \ + ) + +BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_VERSION)(ASYNC_MQTT_PP_PROTOCOL)) + +#undef ASYNC_MQTT_PP_GENERATE +#undef ASYNC_MQTT_INSTANTIATE_EACH + +#endif // defined(ASYNC_MQTT_SEPARATE_COMPILATION) + +#endif // ASYNC_MQTT_IMPL_CLIENT_INSTANTIATE_HPP diff --git a/include/async_mqtt/impl/client_misc.hpp b/include/async_mqtt/impl/client_misc.hpp new file mode 100644 index 000000000..2256382e8 --- /dev/null +++ b/include/async_mqtt/impl/client_misc.hpp @@ -0,0 +1,271 @@ +// Copyright Takatoshi Kondo 2024 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_CLIENT_MISC_HPP) +#define ASYNC_MQTT_IMPL_CLIENT_MISC_HPP + +#include +#include + +namespace async_mqtt { +namespace mi = boost::multi_index; + +namespace detail { + +// member functions + +template +template +client_impl::client_impl( + Args&&... args +): ep_{Version, std::forward(args)...}, + tim_notify_publish_recv_{ep_.get_executor()} +{ + ep_.set_auto_pub_response(true); + ep_.set_auto_ping_response(true); +} + +template +template +client_impl::client_impl( + client_impl&& other +): ep_{Version, force_move(other.next_layer())}, + tim_notify_publish_recv_{ep_.get_executor()} +{ + ep_.set_auto_pub_response(true); + ep_.set_auto_ping_response(true); +} + +template +inline +as::any_io_executor +client_impl::get_executor() { + return ep_.get_executor(); +} + +template +inline +typename client_impl::next_layer_type const& +client_impl::next_layer() const { + return ep_.next_layer(); +} + +template +inline +typename client_impl::next_layer_type& +client_impl::next_layer() { + return ep_.next_layer(); +} + +template +inline +typename client_impl::lowest_layer_type const& +client_impl::lowest_layer() const { + return ep_.lowest_layer(); +} + +template +inline +typename client_impl::lowest_layer_type& +client_impl::lowest_layer() { + return ep_.lowest_layer(); +} + +template +inline +typename client_impl::endpoint_type const& +client_impl::get_endpoint() const { + return ep_; +} + +template +inline +typename client_impl::endpoint_type& +client_impl::get_endpoint() { + return ep_; +} + +template +inline +void +client_impl::set_auto_map_topic_alias_send(bool val) { + ep_.set_auto_map_topic_alias_send(val); +} + +template +inline +void +client_impl::set_auto_replace_topic_alias_send(bool val) { + ep_.set_auto_replace_topic_alias_send(val); +} + +template +inline +void +client_impl::set_pingresp_recv_timeout( + std::chrono::milliseconds duration +) { + ep_.set_pingresp_recv_timeout(duration); +} + +template +inline +void +client_impl::set_close_delay_after_disconnect_sent( + std::chrono::milliseconds duration +) { + ep_.set_close_delay_after_disconnect_sent(duration); +} + +template +inline +void +client_impl::set_bulk_write(bool val) { + ep_.set_bulk_write(val); +} + +template +inline +void +client_impl::set_read_buffer_size(std::size_t val) { + ep_.set_read_buffer_size(val); +} + +} // namespace detail + +// member functions + +template +template +client::client( + Args&&... args +): impl_{std::make_shared(std::forward(args)...)} +{ +} + +template +template +client::client( + client&& other +): impl_{force_move(other.impl_)} +{ +} + +template +inline +as::any_io_executor +client::get_executor() { + BOOST_ASSERT(impl_); + return impl_->get_executor(); +} + +template +inline +typename client::next_layer_type const& +client::next_layer() const { + BOOST_ASSERT(impl_); + return impl_->next_layer(); +} + +template +inline +typename client::next_layer_type& +client::next_layer() { + BOOST_ASSERT(impl_); + return impl_->next_layer(); +} + +template +inline +typename client::lowest_layer_type const& +client::lowest_layer() const { + BOOST_ASSERT(impl_); + return impl_->lowest_layer(); +} + +template +inline +typename client::lowest_layer_type& +client::lowest_layer() { + BOOST_ASSERT(impl_); + return impl_->lowest_layer(); +} + +template +inline +typename client::endpoint_type const& +client::get_endpoint() const { + BOOST_ASSERT(impl_); + return impl_->get_endpoint(); +} + +template +inline +typename client::endpoint_type& +client::get_endpoint() { + BOOST_ASSERT(impl_); + return impl_->get_endpoint(); +} + +template +inline +void +client::set_auto_map_topic_alias_send(bool val) { + BOOST_ASSERT(impl_); + impl_->set_auto_map_topic_alias_send(val); +} + +template +inline +void +client::set_auto_replace_topic_alias_send(bool val) { + BOOST_ASSERT(impl_); + impl_->set_auto_replace_topic_alias_send(val); +} + +template +inline +void +client::set_pingresp_recv_timeout( + std::chrono::milliseconds duration +) { + BOOST_ASSERT(impl_); + impl_->set_pingresp_recv_timeout(duration); +} + +template +inline +void +client::set_close_delay_after_disconnect_sent( + std::chrono::milliseconds duration +) { + BOOST_ASSERT(impl_); + impl_->set_close_delay_after_disconnect_sent(duration); +} + +template +inline +void +client::set_bulk_write(bool val) { + BOOST_ASSERT(impl_); + impl_->set_bulk_write(val); +} + +template +inline +void +client::set_read_buffer_size(std::size_t val) { + BOOST_ASSERT(impl_); + impl_->set_read_buffer_size(val); +} + +} // namespace async_mqtt + +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + +#endif // ASYNC_MQTT_IMPL_CLIENT_MISC_HPP diff --git a/include/async_mqtt/impl/client_impl.ipp b/include/async_mqtt/impl/client_misc.ipp similarity index 84% rename from include/async_mqtt/impl/client_impl.ipp rename to include/async_mqtt/impl/client_misc.ipp index 9ec4f0eee..65bcda230 100644 --- a/include/async_mqtt/impl/client_impl.ipp +++ b/include/async_mqtt/impl/client_misc.ipp @@ -4,16 +4,15 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_CLIENT_IMPL_IPP) -#define ASYNC_MQTT_CLIENT_IMPL_IPP +#if !defined(ASYNC_MQTT_IMPL_CLIENT_MISC_IPP) +#define ASYNC_MQTT_IMPL_CLIENT_MISC_IPP #include #include #include #include -#include - +#include #include @@ -30,14 +29,16 @@ client_impl::recv_loop(this_type_sp impl) { auto& a_impl{*impl}; a_impl.ep_.async_recv( [impl = force_move(impl)] - (error_code const& ec, packet_variant pv) mutable { + (error_code const& ec, std::optional pv_opt) mutable { if (ec) { impl->recv_queue_.emplace_back(ec); impl->recv_queue_inserted_ = true; impl->tim_notify_publish_recv_.cancel(); + impl->pid_tim_pv_res_col_.clear(); return; } - pv.visit( + BOOST_ASSERT(pv_opt); + pv_opt->visit( overload { [&](typename client_type::connack_packet& p) { auto& idx = impl->pid_tim_pv_res_col_.get_pid_idx(); @@ -135,35 +136,6 @@ client::recv_loop() { } // namespace async_mqtt -#if defined(ASYNC_MQTT_SEPARATE_COMPILATION) - -#include - - -#define ASYNC_MQTT_INSTANTIATE_EACH(a_version, a_protocol) \ -namespace async_mqtt { \ -namespace detail { \ -template \ -class client_impl; \ -} \ -template \ -class client; \ -} // namespace async_mqtt - -#define ASYNC_MQTT_PP_GENERATE(r, product) \ - BOOST_PP_EXPAND( \ - ASYNC_MQTT_INSTANTIATE_EACH \ - BOOST_PP_SEQ_TO_TUPLE( \ - product \ - ) \ - ) - -BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_VERSION)(ASYNC_MQTT_PP_PROTOCOL)) - -#undef ASYNC_MQTT_PP_GENERATE -#undef ASYNC_MQTT_INSTANTIATE_EACH - -#endif // defined(ASYNC_MQTT_SEPARATE_COMPILATION) - +#include -#endif // ASYNC_MQTT_CLIENT_IMPL_IPP +#endif // ASYNC_MQTT_IMPL_CLIENT_MISC_IPP diff --git a/include/async_mqtt/impl/client_publish.hpp b/include/async_mqtt/impl/client_publish.hpp index 5c446c64e..95bf72692 100644 --- a/include/async_mqtt/impl/client_publish.hpp +++ b/include/async_mqtt/impl/client_publish.hpp @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -21,106 +22,10 @@ namespace hana = boost::hana; namespace detail { -template -struct client_impl:: -publish_op { - this_type_sp cl; - error_code ec; - std::optional packet; - - template - void operator()( - Self& self - ) { - auto& a_cl{*cl}; - if (ec) { - self.complete(ec, typename client_type::pubres_type{}); - return; - } - auto pid = packet->packet_id(); - auto a_packet{force_move(*packet)}; - a_cl.ep_.async_send( - force_move(a_packet), - as::append( - force_move(self), - pid - ) - ); - } - - template - void operator()( - Self& self, - error_code const& ec, - packet_id_type pid - ) { - auto& a_cl{*cl}; - if (ec) { - self.complete(ec, typename client_type::pubres_type{}); - return; - } - if (pid == 0) { - // QoS: at_most_once - self.complete(ec, typename client_type::pubres_type{}); - return; - } - auto tim = std::make_shared(a_cl.ep_.get_executor()); - tim->expires_at(std::chrono::steady_clock::time_point::max()); - a_cl.pid_tim_pv_res_col_.get_tim_idx().emplace(pid, tim); - tim->async_wait( - as::append( - force_move(self), - tim - ) - ); - } - - template - void operator()( - Self& self, - error_code /* ec */, - std::shared_ptr tim - ) { - auto& a_cl{*cl}; - auto& idx = a_cl.pid_tim_pv_res_col_.get_tim_idx(); - auto it = idx.find(tim); - if (it == idx.end()) { - self.complete( - make_error_code(as::error::operation_aborted), - typename client_type::pubres_type{} - ); - } - else { - auto res = it->res; - idx.erase(it); - auto ec = - [&] { - if constexpr(Version == protocol_version::v5) { - if (res.puback_opt) { - return make_error_code(res.puback_opt->code()); - } - else if (res.pubrec_opt) { - auto ec = make_error_code(res.pubrec_opt->code()); - if (ec) return ec; - if (res.pubcomp_opt) { - return make_error_code(res.pubcomp_opt->code()); - } - } - return make_error_code(disconnect_reason_code::protocol_error); - } - else { - return error_code{}; - } - }(); - self.complete(ec, force_move(res)); - } - } -}; - template template auto -client_impl::async_publish_impl( +client_impl::async_publish( this_type_sp impl, error_code ec, std::optional packet, @@ -134,17 +39,27 @@ client_impl::async_publish_impl( } auto exe = impl->get_executor(); return - as::async_compose< + as::async_initiate< CompletionToken, void(error_code, typename client_type::pubres_type) >( - publish_op{ - force_move(impl), - ec, - force_move(packet) + []( + auto handler, + this_type_sp impl, + error_code ec, + std::optional packet + ) { + async_publish_impl( + force_move(impl), + ec, + force_move(packet), + force_move(handler) + ); }, token, - exe + force_move(impl), + ec, + force_move(packet) ); } @@ -157,14 +72,14 @@ client::async_publish(Args&&... args) { BOOST_ASSERT(impl_); if constexpr (std::is_constructible_v(args))...>) { try { - return impl_type::async_publish_impl( + return impl_type::async_publish( impl_, error_code{}, publish_packet{std::forward(args)...} ); } catch (system_error const& se) { - return impl_type::async_publish_impl( + return impl_type::async_publish( impl_, se.code(), std::nullopt @@ -172,9 +87,9 @@ client::async_publish(Args&&... args) { } } else { - auto t = hana::tuple(std::forward(args)...); - auto rest = hana::drop_back(std::move(t), hana::size_c<1>); - auto&& back = hana::back(t); + auto all = hana::tuple(std::forward(args)...); + auto back = hana::back(all); + auto rest = hana::drop_back(all, hana::size_c<1>); return hana::unpack( std::move(rest), [&](auto&&... rest_args) { @@ -186,19 +101,19 @@ client::async_publish(Args&&... args) { "publish_packet is not constructible" ); try { - return impl_type::async_publish_impl( + return impl_type::async_publish( impl_, error_code{}, publish_packet{std::forward(rest_args)...}, - std::forward(back) + force_move(back) ); } catch (system_error const& se) { - return impl_type::async_publish_impl( + return impl_type::async_publish( impl_, se.code(), std::nullopt, - std::forward(back) + force_move(back) ); } } @@ -208,4 +123,8 @@ client::async_publish(Args&&... args) { } // namespace async_mqtt +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + #endif // ASYNC_MQTT_IMPL_CLIENT_PUBLISH_HPP diff --git a/include/async_mqtt/impl/client_publish.ipp b/include/async_mqtt/impl/client_publish.ipp new file mode 100644 index 000000000..9408e8926 --- /dev/null +++ b/include/async_mqtt/impl/client_publish.ipp @@ -0,0 +1,151 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_CLIENT_PUBLISH_IPP) +#define ASYNC_MQTT_IMPL_CLIENT_PUBLISH_IPP + +#include +#include +#include +#include + +namespace async_mqtt::detail { + +template +struct client_impl:: +publish_op { + this_type_sp cl; + error_code ec; + std::optional packet; + + template + void operator()( + Self& self + ) { + auto& a_cl{*cl}; + if (ec) { + self.complete(ec, typename client_type::pubres_type{}); + return; + } + auto pid = packet->packet_id(); + auto a_packet{force_move(*packet)}; + a_cl.ep_.async_send( + force_move(a_packet), + as::append( + force_move(self), + pid + ) + ); + } + + template + void operator()( + Self& self, + error_code const& ec, + packet_id_type pid + ) { + auto& a_cl{*cl}; + if (ec) { + self.complete(ec, typename client_type::pubres_type{}); + return; + } + if (pid == 0) { + // QoS: at_most_once + self.complete(ec, typename client_type::pubres_type{}); + return; + } + auto tim = std::make_shared(a_cl.ep_.get_executor()); + tim->expires_at(std::chrono::steady_clock::time_point::max()); + a_cl.pid_tim_pv_res_col_.get_tim_idx().emplace(pid, tim); + tim->async_wait( + as::append( + force_move(self), + tim + ) + ); + } + + template + void operator()( + Self& self, + error_code /* ec */, + std::shared_ptr tim + ) { + auto& a_cl{*cl}; + auto& idx = a_cl.pid_tim_pv_res_col_.get_tim_idx(); + auto it = idx.find(tim); + if (it == idx.end()) { + self.complete( + make_error_code(as::error::operation_aborted), + typename client_type::pubres_type{} + ); + } + else { + auto res = it->res; + idx.erase(it); + auto ec = + [&] { + if constexpr(Version == protocol_version::v5) { + if (res.puback_opt) { + return make_error_code(res.puback_opt->code()); + } + else if (res.pubrec_opt) { + auto ec = make_error_code(res.pubrec_opt->code()); + if (ec) return ec; + if (res.pubcomp_opt) { + return make_error_code(res.pubcomp_opt->code()); + } + } + return make_error_code(disconnect_reason_code::protocol_error); + } + else { + return error_code{}; + } + }(); + self.complete(ec, force_move(res)); + } + } +}; + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +client_impl::async_publish_impl( + this_type_sp impl, + error_code ec, + std::optional packet, + as::any_completion_handler< + void(error_code, typename client_type::pubres_type) + > handler +) { + BOOST_ASSERT(impl); + if (packet) { + ASYNC_MQTT_LOG("mqtt_api", info) + << ASYNC_MQTT_ADD_VALUE(address, impl.get()) + << *packet; + } + auto exe = impl->get_executor(); + as::async_compose< + as::any_completion_handler< + void(error_code, typename client_type::pubres_type) + >, + void(error_code, typename client_type::pubres_type) + >( + publish_op{ + force_move(impl), + ec, + force_move(packet) + }, + handler, + exe + ); +} + +} // namespace async_mqtt::detail + +#include + +#endif // ASYNC_MQTT_IMPL_CLIENT_PUBLISH_IPP diff --git a/include/async_mqtt/impl/client_recv.hpp b/include/async_mqtt/impl/client_recv.hpp index 7f00480e0..a21bbe456 100644 --- a/include/async_mqtt/impl/client_recv.hpp +++ b/include/async_mqtt/impl/client_recv.hpp @@ -9,83 +9,13 @@ #include -#include +#include #include +#include #include namespace async_mqtt { -namespace detail { - -template -struct client_impl:: -recv_op { - this_type_sp cl; - enum { dispatch, recv, complete } state = dispatch; - template - void operator()( - Self& self - ) { - auto& a_cl{*cl}; - if (state == dispatch) { - state = recv; - as::dispatch( - a_cl.ep_.get_executor(), - force_move(self) - ); - } - else { - BOOST_ASSERT(state == recv); - state = complete; - if (a_cl.recv_queue_.empty()) { - a_cl.recv_queue_inserted_ = false; - auto tim = std::make_shared( - a_cl.ep_.get_executor() - ); - a_cl.tim_notify_publish_recv_.expires_at( - std::chrono::steady_clock::time_point::max() - ); - a_cl.tim_notify_publish_recv_.async_wait( - force_move(self) - ); - } - else { - auto [ec, pv] = force_move(a_cl.recv_queue_.front()); - a_cl.recv_queue_.pop_front(); - self.complete( - ec, - force_move(pv) - ); - } - } - } - - template - void operator()( - Self& self, - error_code /* ec */ - ) { - BOOST_ASSERT(state == complete); - auto& a_cl{*cl}; - if (a_cl.recv_queue_inserted_) { - auto [ec, pv] = force_move(a_cl.recv_queue_.front()); - a_cl.recv_queue_.pop_front(); - self.complete( - ec, - force_move(pv) - ); - } - else { - self.complete( - make_error_code(as::error::operation_aborted), - packet_variant{} - ); - } - } -}; - -} // namespace detail - template template auto @@ -97,18 +27,28 @@ client::async_recv( << "recv"; BOOST_ASSERT(impl_); return - as::async_compose< + as::async_initiate< CompletionToken, - void(error_code, packet_variant) + void(error_code, std::optional) >( - typename impl_type::recv_op{ - impl_ + []( + auto handler, + std::shared_ptr impl + ) { + impl_type::async_recv( + force_move(impl), + force_move(handler) + ); }, token, - get_executor() + impl_ ); } } // namespace async_mqtt +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + #endif // ASYNC_MQTT_IMPL_CLIENT_RECV_HPP diff --git a/include/async_mqtt/impl/client_recv.ipp b/include/async_mqtt/impl/client_recv.ipp new file mode 100644 index 000000000..2e06c57af --- /dev/null +++ b/include/async_mqtt/impl/client_recv.ipp @@ -0,0 +1,116 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_CLIENT_RECV_IPP) +#define ASYNC_MQTT_IMPL_CLIENT_RECV_IPP + +#include + +#include +#include +#include +#include +#include + +namespace async_mqtt::detail { + +template +struct client_impl:: +recv_op { + this_type_sp cl; + enum { dispatch, recv, complete } state = dispatch; + template + void operator()( + Self& self + ) { + auto& a_cl{*cl}; + if (state == dispatch) { + state = recv; + as::dispatch( + a_cl.ep_.get_executor(), + force_move(self) + ); + } + else { + BOOST_ASSERT(state == recv); + state = complete; + if (a_cl.recv_queue_.empty()) { + a_cl.recv_queue_inserted_ = false; + auto tim = std::make_shared( + a_cl.ep_.get_executor() + ); + a_cl.tim_notify_publish_recv_.expires_at( + std::chrono::steady_clock::time_point::max() + ); + a_cl.tim_notify_publish_recv_.async_wait( + force_move(self) + ); + } + else { + auto [ec, pv] = force_move(a_cl.recv_queue_.front()); + a_cl.recv_queue_.pop_front(); + self.complete( + ec, + force_move(pv) + ); + } + } + } + + template + void operator()( + Self& self, + error_code /* ec */ + ) { + BOOST_ASSERT(state == complete); + auto& a_cl{*cl}; + if (a_cl.recv_queue_inserted_) { + auto [ec, pv] = force_move(a_cl.recv_queue_.front()); + a_cl.recv_queue_.pop_front(); + self.complete( + ec, + force_move(pv) + ); + } + else { + self.complete( + make_error_code(as::error::operation_aborted), + std::nullopt + ); + } + } +}; + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +client_impl::async_recv( + this_type_sp impl, + as::any_completion_handler< + void(error_code, std::optional) + > handler +) { + BOOST_ASSERT(impl); + auto exe = impl->get_executor(); + as::async_compose< + as::any_completion_handler< + void(error_code, std::optional) + >, + void(error_code, std::optional) + >( + recv_op{ + force_move(impl), + }, + handler, + exe + ); +} + +} // namespace async_mqtt::detail + +#include + +#endif // ASYNC_MQTT_IMPL_CLIENT_RECV_IPP diff --git a/include/async_mqtt/impl/client_register_packet_id.hpp b/include/async_mqtt/impl/client_register_packet_id.hpp index 5aec4363d..2b1175b4b 100644 --- a/include/async_mqtt/impl/client_register_packet_id.hpp +++ b/include/async_mqtt/impl/client_register_packet_id.hpp @@ -8,32 +8,10 @@ #define ASYNC_MQTT_IMPL_CLIENT_REGISTER_PACKET_ID_HPP #include +#include namespace async_mqtt { -namespace detail { - -template -template -auto -client_impl::async_register_packet_id( - packet_id_type pid, - CompletionToken&& token -) { - return ep_->async_register_packet_id(pid, std::forward(token)); -} - -// sync version - -template -inline -bool -client_impl::register_packet_id(packet_id_type packet_id) { - return ep_.register_packet_id(packet_id); -} - -} // namespace detail - template template auto @@ -42,7 +20,26 @@ client::async_register_packet_id( CompletionToken&& token ) { BOOST_ASSERT(impl_); - return impl_->async_register_packet_id(pid, std::forward(token)); + return + as::async_initiate< + CompletionToken, + void(error_code) + >( + []( + auto handler, + std::shared_ptr impl, + packet_id_type pid + ) { + impl_type::async_register_packet_id( + force_move(impl), + pid, + force_move(handler) + ); + }, + token, + impl_, + pid + ); } // sync version diff --git a/include/async_mqtt/impl/client_register_packet_id.ipp b/include/async_mqtt/impl/client_register_packet_id.ipp new file mode 100644 index 000000000..96957baed --- /dev/null +++ b/include/async_mqtt/impl/client_register_packet_id.ipp @@ -0,0 +1,42 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_CLIENT_REGISTER_PACKET_ID_IPP) +#define ASYNC_MQTT_IMPL_CLIENT_REGISTER_PACKET_ID_IPP + +#include +#include +#include + +namespace async_mqtt::detail { + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +client_impl::async_register_packet_id( + this_type_sp impl, + packet_id_type pid, + as::any_completion_handler< + void(error_code) + > handler +) { + impl->ep_.async_register_packet_id(pid, force_move(handler)); +} + +// sync version + +template +inline +bool +client_impl::register_packet_id(packet_id_type packet_id) { + return ep_.register_packet_id(packet_id); +} + +} // namespace async_mqtt::detail + +#include + +#endif // ASYNC_MQTT_IMPL_CLIENT_REGISTER_PACKET_ID_IPP diff --git a/include/async_mqtt/impl/client_release_packet_id.hpp b/include/async_mqtt/impl/client_release_packet_id.hpp index 2a84dba73..e2e9e0f4b 100644 --- a/include/async_mqtt/impl/client_release_packet_id.hpp +++ b/include/async_mqtt/impl/client_release_packet_id.hpp @@ -8,32 +8,10 @@ #define ASYNC_MQTT_IMPL_CLIENT_RELEASE_PACKET_ID_HPP #include +#include namespace async_mqtt { -namespace detail { - -template -template -auto -client_impl::async_release_packet_id( - packet_id_type pid, - CompletionToken&& token -) { - return ep_.async_release_packet_id(pid, std::forward(token)); -} - -// sync version - -template -inline -void -client_impl::release_packet_id(packet_id_type packet_id) { - ep_.release_packet_id(packet_id); -} - -} // namespace detail - template template auto @@ -42,7 +20,26 @@ client::async_release_packet_id( CompletionToken&& token ) { BOOST_ASSERT(impl_); - return impl_->async_release_packet_id(pid, std::forward(token)); + return + as::async_initiate< + CompletionToken, + void() + >( + []( + auto handler, + std::shared_ptr impl, + packet_id_type pid + ) { + impl_type::async_release_packet_id( + force_move(impl), + pid, + force_move(handler) + ); + }, + token, + impl_, + pid + ); } // sync version diff --git a/include/async_mqtt/impl/client_release_packet_id.ipp b/include/async_mqtt/impl/client_release_packet_id.ipp new file mode 100644 index 000000000..dad6a7383 --- /dev/null +++ b/include/async_mqtt/impl/client_release_packet_id.ipp @@ -0,0 +1,42 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_CLIENT_RELEASE_PACKET_ID_IPP) +#define ASYNC_MQTT_IMPL_CLIENT_RELEASE_PACKET_ID_IPP + +#include +#include +#include + +namespace async_mqtt::detail { + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +client_impl::async_release_packet_id( + this_type_sp impl, + packet_id_type pid, + as::any_completion_handler< + void() + > handler +) { + impl->ep_.async_release_packet_id(pid, force_move(handler)); +} + +// sync version + +template +inline +void +client_impl::release_packet_id(packet_id_type packet_id) { + ep_.release_packet_id(packet_id); +} + +} // namespace async_mqtt::detail + +#include + +#endif // ASYNC_MQTT_IMPL_CLIENT_RELEASE_PACKET_ID_IPP diff --git a/include/async_mqtt/impl/client_start.hpp b/include/async_mqtt/impl/client_start.hpp index 1ee80976d..73c9c425f 100644 --- a/include/async_mqtt/impl/client_start.hpp +++ b/include/async_mqtt/impl/client_start.hpp @@ -15,6 +15,7 @@ #include #include +#include #include #include @@ -23,88 +24,11 @@ namespace async_mqtt { namespace hana = boost::hana; namespace detail { -template -struct client_impl:: -start_op { - this_type_sp cl; - error_code ec; - std::optional packet; - - template - void operator()( - Self& self - ) { - auto& a_cl{*cl}; - if (ec) { - self.complete(ec, std::nullopt); - return; - } - auto a_packet{force_move(*packet)}; - a_cl.ep_.async_send( - force_move(a_packet), - force_move(self) - ); - } - - template - void operator()( - Self& self, - error_code const& ec - ) { - auto& a_cl{*cl}; - if (ec) { - self.complete(ec, std::nullopt); - return; - } - - auto tim = std::make_shared(a_cl.ep_.get_executor()); - tim->expires_at(std::chrono::steady_clock::time_point::max()); - a_cl.pid_tim_pv_res_col_.get_tim_idx().emplace(tim); - recv_loop(cl); - tim->async_wait( - as::append( - force_move(self), - tim - ) - ); - } - - template - void operator()( - Self& self, - error_code /* ec */, - std::shared_ptr tim - ) { - auto& a_cl{*cl}; - auto& idx = a_cl.pid_tim_pv_res_col_.get_tim_idx(); - auto it = idx.find(tim); - if (it == idx.end()) { - self.complete( - make_error_code(as::error::operation_aborted), - std::nullopt - ); - } - else { - auto pv = it->pv; - idx.erase(it); - if (auto *p = pv->template get_if()) { - self.complete(make_error_code(p->code()), *p); - } - else { - self.complete( - make_error_code(disconnect_reason_code::protocol_error), - std::nullopt - ); - } - } - } -}; - template template auto -client_impl::async_start_impl( +client_impl::async_start( this_type_sp impl, error_code ec, std::optional packet, @@ -116,19 +40,28 @@ client_impl::async_start_impl( << ASYNC_MQTT_ADD_VALUE(address, impl.get()) << *packet; } - auto exe = impl->get_executor(); return - as::async_compose< + as::async_initiate< CompletionToken, void(error_code, std::optional) >( - start_op{ - force_move(impl), - ec, - force_move(packet) + []( + auto handler, + this_type_sp impl, + error_code ec, + std::optional packet + ) { + async_start_impl( + force_move(impl), + ec, + force_move(packet), + force_move(handler) + ); }, token, - exe + force_move(impl), + ec, + force_move(packet) ); } @@ -141,14 +74,14 @@ client::async_start(Args&&... args) { BOOST_ASSERT(impl_); if constexpr (std::is_constructible_v(args))...>) { try { - return impl_type::async_start_impl( + return impl_type::async_start( impl_, error_code{}, connect_packet{std::forward(args)...} ); } catch (system_error const& se) { - return impl_type::async_start_impl( + return impl_type::async_start( impl_, se.code(), std::nullopt @@ -156,9 +89,9 @@ client::async_start(Args&&... args) { } } else { - auto t = hana::tuple(std::forward(args)...); - auto rest = hana::drop_back(std::move(t), hana::size_c<1>); - auto&& back = hana::back(t); + auto all = hana::tuple(std::forward(args)...); + auto back = hana::back(all); + auto rest = hana::drop_back(all, hana::size_c<1>); return hana::unpack( std::move(rest), [&](auto&&... rest_args) { @@ -170,21 +103,21 @@ client::async_start(Args&&... args) { "connect_packet is not constructible" ); try { - return impl_type::async_start_impl( + return impl_type::async_start( impl_, error_code{}, connect_packet{ std::forward>(rest_args)... }, - std::forward(back) + force_move(back) ); } catch (system_error const& se) { - return impl_type::async_start_impl( + return impl_type::async_start( impl_, se.code(), std::nullopt, - std::forward(back) + force_move(back) ); } } @@ -194,4 +127,8 @@ client::async_start(Args&&... args) { } // namespace async_mqtt +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + #endif // ASYNC_MQTT_IMPL_CLIENT_START_HPP diff --git a/include/async_mqtt/impl/client_start.ipp b/include/async_mqtt/impl/client_start.ipp new file mode 100644 index 000000000..37c27b0a7 --- /dev/null +++ b/include/async_mqtt/impl/client_start.ipp @@ -0,0 +1,136 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_CLIENT_START_IPP) +#define ASYNC_MQTT_IMPL_CLIENT_START_IPP + +#include +#include + +#include +#include +#include +#include + +namespace async_mqtt::detail { + +template +struct client_impl:: +start_op { + this_type_sp cl; + error_code ec; + std::optional packet; + + template + void operator()( + Self& self + ) { + auto& a_cl{*cl}; + if (ec) { + self.complete(ec, std::nullopt); + return; + } + auto a_packet{force_move(*packet)}; + a_cl.ep_.async_send( + force_move(a_packet), + force_move(self) + ); + } + + template + void operator()( + Self& self, + error_code const& ec + ) { + auto& a_cl{*cl}; + if (ec) { + self.complete(ec, std::nullopt); + return; + } + + auto tim = std::make_shared(a_cl.ep_.get_executor()); + tim->expires_at(std::chrono::steady_clock::time_point::max()); + a_cl.pid_tim_pv_res_col_.get_tim_idx().emplace(tim); + recv_loop(cl); + tim->async_wait( + as::append( + force_move(self), + tim + ) + ); + } + + template + void operator()( + Self& self, + error_code /* ec */, + std::shared_ptr tim + ) { + auto& a_cl{*cl}; + auto& idx = a_cl.pid_tim_pv_res_col_.get_tim_idx(); + auto it = idx.find(tim); + if (it == idx.end()) { + self.complete( + make_error_code(as::error::operation_aborted), + std::nullopt + ); + } + else { + auto pv = it->pv; + idx.erase(it); + if (auto *p = pv->template get_if()) { + self.complete(make_error_code(p->code()), *p); + } + else { + self.complete( + make_error_code(disconnect_reason_code::protocol_error), + std::nullopt + ); + } + } + } +}; + + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +client_impl::async_start_impl( + this_type_sp impl, + error_code ec, + std::optional packet, + as::any_completion_handler< + void(error_code, std::optional) + > handler +) { + BOOST_ASSERT(impl); + if (packet) { + ASYNC_MQTT_LOG("mqtt_api", info) + << ASYNC_MQTT_ADD_VALUE(address, impl.get()) + << *packet; + } + auto exe = impl->get_executor(); + as::async_compose< + as::any_completion_handler< + void(error_code, std::optional) + >, + void(error_code, std::optional) + >( + start_op{ + force_move(impl), + ec, + force_move(packet) + }, + handler, + exe + ); +} + +} // namespace async_mqtt::detail + +#include + +#endif // ASYNC_MQTT_IMPL_CLIENT_START_IPP diff --git a/include/async_mqtt/impl/client_subscribe.hpp b/include/async_mqtt/impl/client_subscribe.hpp index 4c50aaeed..7767fd1c8 100644 --- a/include/async_mqtt/impl/client_subscribe.hpp +++ b/include/async_mqtt/impl/client_subscribe.hpp @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -21,112 +22,10 @@ namespace hana = boost::hana; namespace detail { -template -struct client_impl:: -subscribe_op { - this_type_sp cl; - error_code ec; - std::optional packet; - - template - void operator()( - Self& self - ) { - auto& a_cl{*cl}; - if (ec) { - self.complete(ec, std::nullopt); - return; - } - auto pid = packet->packet_id(); - auto a_packet{force_move(*packet)}; - a_cl.ep_.async_send( - force_move(a_packet), - as::append( - force_move(self), - pid - ) - ); - } - - template - void operator()( - Self& self, - error_code const& ec, - packet_id_type pid - ) { - auto& a_cl{*cl}; - if (ec) { - self.complete(ec, std::nullopt); - return; - } - - auto tim = std::make_shared(a_cl.ep_.get_executor()); - tim->expires_at(std::chrono::steady_clock::time_point::max()); - a_cl.pid_tim_pv_res_col_.get_tim_idx().emplace(pid, tim); - tim->async_wait( - as::append( - force_move(self), - tim - ) - ); - } - - template - void operator()( - Self& self, - error_code /* ec */, - std::shared_ptr tim - ) { - auto& a_cl{*cl}; - auto& idx = a_cl.pid_tim_pv_res_col_.get_tim_idx(); - auto it = idx.find(tim); - if (it == idx.end()) { - self.complete( - make_error_code(as::error::operation_aborted), - std::nullopt - ); - } - else { - auto pv = it->pv; - idx.erase(it); - if (auto *p = pv->template get_if()) { - auto ec = - [&] { - switch (p->entries().size()) { - case 0: - return make_error_code(disconnect_reason_code::protocol_error); - case 1: - return make_error_code(p->entries().back()); - default: { - bool all_error = true; - bool any_error = false; - for (auto code : p->entries()) { - auto ec = make_error_code(code); - all_error = all_error && ec; - any_error = any_error || ec; - } - if (all_error) return make_error_code(mqtt_error::all_error_detected); - if (any_error) return make_error_code(mqtt_error::partial_error_detected); - return error_code{}; - } break; - } - }(); - self.complete(ec, *p); - } - else { - self.complete( - make_error_code(disconnect_reason_code::protocol_error), - std::nullopt - ); - } - } - } -}; - template template auto -client_impl::async_subscribe_impl( +client_impl::async_subscribe( this_type_sp impl, error_code ec, std::optional packet, @@ -140,17 +39,27 @@ client_impl::async_subscribe_impl( BOOST_ASSERT(impl); auto exe = impl->get_executor(); return - as::async_compose< + as::async_initiate< CompletionToken, void(error_code, std::optional) >( - subscribe_op{ - force_move(impl), - ec, - force_move(packet) + []( + auto handler, + this_type_sp impl, + error_code ec, + std::optional packet + ) { + async_subscribe_impl( + force_move(impl), + ec, + force_move(packet), + force_move(handler) + ); }, token, - exe + force_move(impl), + ec, + force_move(packet) ); } @@ -163,14 +72,14 @@ client::async_subscribe(Args&&... args) { BOOST_ASSERT(impl_); if constexpr (std::is_constructible_v(args))...>) { try { - return impl_type::async_subscribe_impl( + return impl_type::async_subscribe( impl_, error_code{}, subscribe_packet{std::forward(args)...} ); } catch (system_error const& se) { - return impl_type::async_subscribe_impl( + return impl_type::async_subscribe( impl_, se.code(), std::nullopt @@ -178,9 +87,9 @@ client::async_subscribe(Args&&... args) { } } else { - auto t = hana::tuple(std::forward(args)...); - auto rest = hana::drop_back(std::move(t), hana::size_c<1>); - auto&& back = hana::back(t); + auto all = hana::tuple(std::forward(args)...); + auto back = hana::back(all); + auto rest = hana::drop_back(all, hana::size_c<1>); return hana::unpack( std::move(rest), [&](auto&&... rest_args) { @@ -192,19 +101,19 @@ client::async_subscribe(Args&&... args) { "subscribe_packet is not constructible" ); try { - return impl_type::async_subscribe_impl( + return impl_type::async_subscribe( impl_, error_code{}, subscribe_packet{std::forward(rest_args)...}, - std::forward(back) + force_move(back) ); } catch (system_error const& se) { - return impl_type::async_subscribe_impl( + return impl_type::async_subscribe( impl_, se.code(), std::nullopt, - std::forward(back) + force_move(back) ); } } @@ -214,4 +123,8 @@ client::async_subscribe(Args&&... args) { } // namespace async_mqtt +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + #endif // ASYNC_MQTT_IMPL_CLIENT_SUBSCRIBE_HPP diff --git a/include/async_mqtt/impl/client_subscribe.ipp b/include/async_mqtt/impl/client_subscribe.ipp new file mode 100644 index 000000000..209470caa --- /dev/null +++ b/include/async_mqtt/impl/client_subscribe.ipp @@ -0,0 +1,157 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_CLIENT_SUBSCRIBE_IPP) +#define ASYNC_MQTT_IMPL_CLIENT_SUBSCRIBE_IPP + +#include +#include +#include +#include + +namespace async_mqtt::detail { + +template +struct client_impl:: +subscribe_op { + this_type_sp cl; + error_code ec; + std::optional packet; + + template + void operator()( + Self& self + ) { + auto& a_cl{*cl}; + if (ec) { + self.complete(ec, std::nullopt); + return; + } + auto pid = packet->packet_id(); + auto a_packet{force_move(*packet)}; + a_cl.ep_.async_send( + force_move(a_packet), + as::append( + force_move(self), + pid + ) + ); + } + + template + void operator()( + Self& self, + error_code const& ec, + packet_id_type pid + ) { + auto& a_cl{*cl}; + if (ec) { + self.complete(ec, std::nullopt); + return; + } + + auto tim = std::make_shared(a_cl.ep_.get_executor()); + tim->expires_at(std::chrono::steady_clock::time_point::max()); + a_cl.pid_tim_pv_res_col_.get_tim_idx().emplace(pid, tim); + tim->async_wait( + as::append( + force_move(self), + tim + ) + ); + } + + template + void operator()( + Self& self, + error_code /* ec */, + std::shared_ptr tim + ) { + auto& a_cl{*cl}; + auto& idx = a_cl.pid_tim_pv_res_col_.get_tim_idx(); + auto it = idx.find(tim); + if (it == idx.end()) { + self.complete( + make_error_code(as::error::operation_aborted), + std::nullopt + ); + } + else { + auto pv = it->pv; + idx.erase(it); + if (auto *p = pv->template get_if()) { + auto ec = + [&] { + switch (p->entries().size()) { + case 0: + return make_error_code(disconnect_reason_code::protocol_error); + case 1: + return make_error_code(p->entries().back()); + default: { + bool all_error = true; + bool any_error = false; + for (auto code : p->entries()) { + auto ec = make_error_code(code); + all_error = all_error && ec; + any_error = any_error || ec; + } + if (all_error) return make_error_code(mqtt_error::all_error_detected); + if (any_error) return make_error_code(mqtt_error::partial_error_detected); + return error_code{}; + } break; + } + }(); + self.complete(ec, *p); + } + else { + self.complete( + make_error_code(disconnect_reason_code::protocol_error), + std::nullopt + ); + } + } + } +}; + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +client_impl::async_subscribe_impl( + this_type_sp impl, + error_code ec, + std::optional packet, + as::any_completion_handler< + void(error_code, std::optional) + > handler +) { + if (packet) { + ASYNC_MQTT_LOG("mqtt_api", info) + << ASYNC_MQTT_ADD_VALUE(address, impl.get()) + << *packet; + } + BOOST_ASSERT(impl); + auto exe = impl->get_executor(); + as::async_compose< + as::any_completion_handler< + void(error_code, std::optional) + >, + void(error_code, std::optional) + >( + subscribe_op{ + force_move(impl), + ec, + force_move(packet) + }, + handler, + exe + ); +} + +} // namespace async_mqtt::detail + +#include + +#endif // ASYNC_MQTT_IMPL_CLIENT_SUBSCRIBE_IPP diff --git a/include/async_mqtt/impl/client_underlying_handshake.hpp b/include/async_mqtt/impl/client_underlying_handshake.hpp new file mode 100644 index 000000000..b928d00be --- /dev/null +++ b/include/async_mqtt/impl/client_underlying_handshake.hpp @@ -0,0 +1,40 @@ +// Copyright Takatoshi Kondo 2024 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_CLIENT_UNDERLYING_HANDSHAKE_HPP) +#define ASYNC_MQTT_IMPL_CLIENT_UNDERLYING_HANDSHAKE_HPP + +#include +#include + +namespace async_mqtt { + +namespace detail { + +template +template +auto +client_impl::async_underlying_handshake( + Args&&... args +) { + return ep_.async_underlying_handshake(std::forward(args)...); +} + +} // namespace detail + +template +template +auto +client::async_underlying_handshake( + Args&&... args +) { + BOOST_ASSERT(impl_); + return impl_->async_underlying_handshake(std::forward(args)...); +} + +} // namespace async_mqtt + +#endif // ASYNC_MQTT_IMPL_CLIENT_UNDERLYING_HANDSHAKE_HPP diff --git a/include/async_mqtt/impl/client_unsubscribe.hpp b/include/async_mqtt/impl/client_unsubscribe.hpp index 834d7290f..8ab431560 100644 --- a/include/async_mqtt/impl/client_unsubscribe.hpp +++ b/include/async_mqtt/impl/client_unsubscribe.hpp @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -21,117 +22,10 @@ namespace hana = boost::hana; namespace detail { -template -struct client_impl:: -unsubscribe_op { - this_type_sp cl; - error_code ec; - std::optional packet; - - template - void operator()( - Self& self - ) { - auto& a_cl{*cl}; - if (ec) { - self.complete(ec, std::nullopt); - return; - } - auto pid = packet->packet_id(); - auto a_packet{force_move(*packet)}; - a_cl.ep_.async_send( - force_move(a_packet), - as::append( - force_move(self), - pid - ) - ); - } - - template - void operator()( - Self& self, - error_code const& ec, - packet_id_type pid - ) { - auto& a_cl{*cl}; - if (ec) { - self.complete(ec, std::nullopt); - return; - } - - auto tim = std::make_shared(a_cl.ep_.get_executor()); - tim->expires_at(std::chrono::steady_clock::time_point::max()); - a_cl.pid_tim_pv_res_col_.get_tim_idx().emplace(pid, tim); - tim->async_wait( - as::append( - force_move(self), - tim - ) - ); - } - - template - void operator()( - Self& self, - error_code /* ec */, - std::shared_ptr tim - ) { - auto& a_cl{*cl}; - auto& idx = a_cl.pid_tim_pv_res_col_.get_tim_idx(); - auto it = idx.find(tim); - if (it == idx.end()) { - self.complete( - make_error_code(as::error::operation_aborted), - std::nullopt - ); - } - else { - auto pv = it->pv; - idx.erase(it); - if (auto *p = pv->template get_if()) { - auto ec = - [&] { - if constexpr(Version == protocol_version::v5) { - switch (p->entries().size()) { - case 0: - return make_error_code(disconnect_reason_code::protocol_error); - case 1: - return make_error_code(p->entries().back()); - default: { - bool all_error = true; - bool any_error = false; - for (auto code : p->entries()) { - auto ec = make_error_code(code); - all_error = all_error && ec; - any_error = any_error || ec; - } - if (all_error) return make_error_code(mqtt_error::all_error_detected); - if (any_error) return make_error_code(mqtt_error::partial_error_detected); - return error_code{}; - } break; - } - } - else { - return error_code{}; - } - }(); - self.complete(ec, *p); - } - else { - self.complete( - make_error_code(disconnect_reason_code::protocol_error), - std::nullopt - ); - } - } - } -}; - template template auto -client_impl::async_unsubscribe_impl( +client_impl::async_unsubscribe( this_type_sp impl, error_code ec, std::optional packet, @@ -145,17 +39,27 @@ client_impl::async_unsubscribe_impl( BOOST_ASSERT(impl); auto exe = impl->get_executor(); return - as::async_compose< + as::async_initiate< CompletionToken, void(error_code, std::optional) >( - unsubscribe_op{ - force_move(impl), - ec, - force_move(packet) + []( + auto handler, + this_type_sp impl, + error_code ec, + std::optional packet + ) { + async_unsubscribe_impl( + force_move(impl), + ec, + force_move(packet), + force_move(handler) + ); }, token, - exe + force_move(impl), + ec, + force_move(packet) ); } @@ -168,14 +72,14 @@ client::async_unsubscribe(Args&&... args) { BOOST_ASSERT(impl_); if constexpr (std::is_constructible_v(args))...>) { try { - return impl_type::async_unsubscribe_impl( + return impl_type::async_unsubscribe( impl_, error_code{}, unsubscribe_packet{std::forward(args)...} ); } catch (system_error const& se) { - return impl_type::async_unsubscribe_impl( + return impl_type::async_unsubscribe( impl_, se.code(), std::nullopt @@ -183,9 +87,9 @@ client::async_unsubscribe(Args&&... args) { } } else { - auto t = hana::tuple(std::forward(args)...); - auto rest = hana::drop_back(std::move(t), hana::size_c<1>); - auto&& back = hana::back(t); + auto all = hana::tuple(std::forward(args)...); + auto back = hana::back(all); + auto rest = hana::drop_back(all, hana::size_c<1>); return hana::unpack( std::move(rest), [&](auto&&... rest_args) { @@ -197,19 +101,19 @@ client::async_unsubscribe(Args&&... args) { "unsubscribe_packet is not constructible" ); try { - return impl_type::async_unsubscribe_impl( + return impl_type::async_unsubscribe( impl_, error_code{}, unsubscribe_packet{std::forward(rest_args)...}, - std::forward(back) + force_move(back) ); } catch (system_error const& se) { - return impl_type::async_unsubscribe_impl( + return impl_type::async_unsubscribe( impl_, se.code(), std::nullopt, - std::forward(back) + force_move(back) ); } } @@ -219,4 +123,8 @@ client::async_unsubscribe(Args&&... args) { } // namespace async_mqtt +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + #endif // ASYNC_MQTT_IMPL_CLIENT_UNSUBSCRIBE_HPP diff --git a/include/async_mqtt/impl/client_unsubscribe.ipp b/include/async_mqtt/impl/client_unsubscribe.ipp new file mode 100644 index 000000000..9f820f80d --- /dev/null +++ b/include/async_mqtt/impl/client_unsubscribe.ipp @@ -0,0 +1,162 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_CLIENT_UNSUBSCRIBE_IPP) +#define ASYNC_MQTT_IMPL_CLIENT_UNSUBSCRIBE_IPP + +#include +#include +#include +#include + +namespace async_mqtt::detail { + +template +struct client_impl:: +unsubscribe_op { + this_type_sp cl; + error_code ec; + std::optional packet; + + template + void operator()( + Self& self + ) { + auto& a_cl{*cl}; + if (ec) { + self.complete(ec, std::nullopt); + return; + } + auto pid = packet->packet_id(); + auto a_packet{force_move(*packet)}; + a_cl.ep_.async_send( + force_move(a_packet), + as::append( + force_move(self), + pid + ) + ); + } + + template + void operator()( + Self& self, + error_code const& ec, + packet_id_type pid + ) { + auto& a_cl{*cl}; + if (ec) { + self.complete(ec, std::nullopt); + return; + } + + auto tim = std::make_shared(a_cl.ep_.get_executor()); + tim->expires_at(std::chrono::steady_clock::time_point::max()); + a_cl.pid_tim_pv_res_col_.get_tim_idx().emplace(pid, tim); + tim->async_wait( + as::append( + force_move(self), + tim + ) + ); + } + + template + void operator()( + Self& self, + error_code /* ec */, + std::shared_ptr tim + ) { + auto& a_cl{*cl}; + auto& idx = a_cl.pid_tim_pv_res_col_.get_tim_idx(); + auto it = idx.find(tim); + if (it == idx.end()) { + self.complete( + make_error_code(as::error::operation_aborted), + std::nullopt + ); + } + else { + auto pv = it->pv; + idx.erase(it); + if (auto *p = pv->template get_if()) { + auto ec = + [&] { + if constexpr(Version == protocol_version::v5) { + switch (p->entries().size()) { + case 0: + return make_error_code(disconnect_reason_code::protocol_error); + case 1: + return make_error_code(p->entries().back()); + default: { + bool all_error = true; + bool any_error = false; + for (auto code : p->entries()) { + auto ec = make_error_code(code); + all_error = all_error && ec; + any_error = any_error || ec; + } + if (all_error) return make_error_code(mqtt_error::all_error_detected); + if (any_error) return make_error_code(mqtt_error::partial_error_detected); + return error_code{}; + } break; + } + } + else { + return error_code{}; + } + }(); + self.complete(ec, *p); + } + else { + self.complete( + make_error_code(disconnect_reason_code::protocol_error), + std::nullopt + ); + } + } + } +}; + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +client_impl::async_unsubscribe_impl( + this_type_sp impl, + error_code ec, + std::optional packet, + as::any_completion_handler< + void(error_code, std::optional) + > handler +) { + if (packet) { + ASYNC_MQTT_LOG("mqtt_api", info) + << ASYNC_MQTT_ADD_VALUE(address, impl.get()) + << *packet; + } + BOOST_ASSERT(impl); + auto exe = impl->get_executor(); + as::async_compose< + as::any_completion_handler< + void(error_code, std::optional) + >, + void(error_code, std::optional) + >( + unsubscribe_op{ + force_move(impl), + ec, + force_move(packet) + }, + handler, + exe + ); +} + +} // namespace async_mqtt::detail + +#include + +#endif // ASYNC_MQTT_IMPL_CLIENT_UNSUBSCRIBE_IPP diff --git a/include/async_mqtt/impl/endpoint_acquire_unique_packet_id.hpp b/include/async_mqtt/impl/endpoint_acquire_unique_packet_id.hpp index 224a1538c..31a5a0bf7 100644 --- a/include/async_mqtt/impl/endpoint_acquire_unique_packet_id.hpp +++ b/include/async_mqtt/impl/endpoint_acquire_unique_packet_id.hpp @@ -8,59 +8,10 @@ #define ASYNC_MQTT_IMPL_ENDPOINT_ACQUIRE_UNIQUE_PACKET_ID_HPP #include +#include namespace async_mqtt { -namespace detail { - -template -struct basic_endpoint_impl:: -acquire_unique_packet_id_op { - this_type_sp ep; - std::optional::type> pid_opt = std::nullopt; - enum { dispatch, complete } state = dispatch; - - template - void operator()( - Self& self - ) { - auto& a_ep{*ep}; - switch (state) { - case dispatch: { - state = complete; - as::dispatch( - a_ep.get_executor(), - force_move(self) - ); - } break; - case complete: - pid_opt = a_ep.pid_man_.acquire_unique_id(); - state = complete; - if (pid_opt) { - self.complete(error_code{}, *pid_opt); - } - else { - self.complete( - make_error_code(mqtt_error::packet_identifier_fully_used), - 0 - ); - } - break; - } - } -}; - -// sync version - -template -inline -std::optional::type> -basic_endpoint_impl::acquire_unique_packet_id() { - return pid_man_.acquire_unique_id(); -} - -} // namespace detail - template template auto @@ -72,39 +23,28 @@ basic_endpoint::async_acquire_unique_packet_id( << "acquire_unique_packet_id"; BOOST_ASSERT(impl_); return - as::async_compose< + as::async_initiate< CompletionToken, - void(error_code, typename basic_packet_id_type::type) + void(error_code, typename basic_packet_id_type::type) >( - typename impl_type::acquire_unique_packet_id_op{ - impl_ + []( + auto handler, + std::shared_ptr impl + ) { + impl_type::async_acquire_unique_packet_id( + force_move(impl), + force_move(handler) + ); }, token, - get_executor() + impl_ ); } -// sync version - -template -inline -std::optional::type> -basic_endpoint::acquire_unique_packet_id() { - BOOST_ASSERT(impl_); - auto pid = impl_->acquire_unique_packet_id(); - if (pid) { - ASYNC_MQTT_LOG("mqtt_api", info) - << ASYNC_MQTT_ADD_VALUE(address, this) - << "acquire_unique_packet_id:" << *pid; - } - else { - ASYNC_MQTT_LOG("mqtt_api", info) - << ASYNC_MQTT_ADD_VALUE(address, this) - << "acquire_unique_packet_id:full"; - } - return pid; -} - } // namespace async_mqtt +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + #endif // ASYNC_MQTT_IMPL_ENDPOINT_ACQUIRE_UNIQUE_PACKET_ID_HPP diff --git a/include/async_mqtt/impl/endpoint_acquire_unique_packet_id.ipp b/include/async_mqtt/impl/endpoint_acquire_unique_packet_id.ipp new file mode 100644 index 000000000..b196fcb3b --- /dev/null +++ b/include/async_mqtt/impl/endpoint_acquire_unique_packet_id.ipp @@ -0,0 +1,115 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_ENDPOINT_ACQUIRE_UNIQUE_PACKET_ID_IPP) +#define ASYNC_MQTT_IMPL_ENDPOINT_ACQUIRE_UNIQUE_PACKET_ID_IPP + +#include +#include +#include + +namespace async_mqtt { + +namespace detail { + +template +struct basic_endpoint_impl:: +acquire_unique_packet_id_op { + this_type_sp ep; + std::optional::type> pid_opt = std::nullopt; + enum { dispatch, complete } state = dispatch; + + template + void operator()( + Self& self + ) { + auto& a_ep{*ep}; + switch (state) { + case dispatch: { + state = complete; + as::dispatch( + a_ep.get_executor(), + force_move(self) + ); + } break; + case complete: + pid_opt = a_ep.con_.acquire_unique_packet_id(); + state = complete; + if (pid_opt) { + self.complete(error_code{}, *pid_opt); + } + else { + self.complete( + make_error_code(mqtt_error::packet_identifier_fully_used), + 0 + ); + } + break; + } + } +}; + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::async_acquire_unique_packet_id( + this_type_sp impl, + as::any_completion_handler< + void(error_code, typename basic_packet_id_type::type) + > handler +) { + auto exe = impl->get_executor(); + as::async_compose< + as::any_completion_handler< + void(error_code, typename basic_packet_id_type::type) + >, + void(error_code, typename basic_packet_id_type::type) + >( + acquire_unique_packet_id_op{ + force_move(impl) + }, + handler, + exe + ); +} + +// sync version + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +std::optional::type> +basic_endpoint_impl::acquire_unique_packet_id() { + return con_.acquire_unique_packet_id(); +} + +} // namespace detail + +// sync version + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +std::optional::type> +basic_endpoint::acquire_unique_packet_id() { + BOOST_ASSERT(impl_); + auto pid = impl_->acquire_unique_packet_id(); + if (pid) { + ASYNC_MQTT_LOG("mqtt_api", info) + << ASYNC_MQTT_ADD_VALUE(address, this) + << "acquire_unique_packet_id:" << *pid; + } + else { + ASYNC_MQTT_LOG("mqtt_api", info) + << ASYNC_MQTT_ADD_VALUE(address, this) + << "acquire_unique_packet_id:full"; + } + return pid; +} + +} // namespace async_mqtt + +#include + +#endif // ASYNC_MQTT_IMPL_ENDPOINT_ACQUIRE_UNIQUE_PACKET_ID_IPP diff --git a/include/async_mqtt/impl/endpoint_acquire_unique_packet_id_wait_until.hpp b/include/async_mqtt/impl/endpoint_acquire_unique_packet_id_wait_until.hpp index 8a28e33f0..9a969af26 100644 --- a/include/async_mqtt/impl/endpoint_acquire_unique_packet_id_wait_until.hpp +++ b/include/async_mqtt/impl/endpoint_acquire_unique_packet_id_wait_until.hpp @@ -8,88 +8,10 @@ #define ASYNC_MQTT_IMPL_ENDPOINT_ACQUIRE_UNIQUE_PACKET_ID_WAIT_UNTIL_HPP #include +#include namespace async_mqtt { -namespace detail { - -template -struct basic_endpoint_impl:: -acquire_unique_packet_id_wait_until_op { - this_type_sp ep; - this_type_wp retry_wp{ep}; - std::optional::type> pid_opt = std::nullopt; - enum { dispatch, complete } state = dispatch; - - template - void operator()( - Self& self, - error_code ec = error_code{} - ) { - auto& a_ep{*ep}; - if (retry_wp.expired()) return; - switch (state) { - case dispatch: { - state = complete; - as::dispatch( - a_ep.get_executor(), - force_move(self) - ); - } break; - case complete: { - auto acq_proc = - [&] { - pid_opt = a_ep.pid_man_.acquire_unique_id(); - if (pid_opt) { - self.complete(error_code{}, *pid_opt); - } - else { - ASYNC_MQTT_LOG("mqtt_impl", warning) - << ASYNC_MQTT_ADD_VALUE(address, &a_ep) - << "packet_id is fully allocated. waiting release"; - a_ep.packet_id_released_ = false; - // infinity timer. cancel is retry trigger. - auto ep_copy = ep; - async_add_retry( - force_move(ep_copy), - force_move(self) - ); - } - }; - - if (ec == as::error::operation_aborted) { - if (a_ep.packet_id_released_) { - a_ep.complete_retry_one(); - acq_proc(); - } - else { - self.complete( - ec, - 0 - ); - } - } - else if (a_ep.has_retry()) { - ASYNC_MQTT_LOG("mqtt_impl", warning) - << ASYNC_MQTT_ADD_VALUE(address, &a_ep) - << "packet_id waiter exists. add the end of waiter queue"; - // infinity timer. cancel is retry trigger. - auto ep_copy = ep; - async_add_retry( - force_move(ep_copy), - force_move(self) - ); - } - else { - acq_proc(); - } - } break; - } - } -}; - -} // namespace detail - template template auto @@ -101,18 +23,29 @@ basic_endpoint::async_acquire_unique_packet_id_w << "acquire_unique_packet_id_wait_until"; BOOST_ASSERT(impl_); return - as::async_compose< + as::async_initiate< CompletionToken, void(error_code, typename basic_packet_id_type::type) >( - typename impl_type::acquire_unique_packet_id_wait_until_op{ - impl_ + []( + auto handler, + std::shared_ptr impl + ) { + impl_type::async_acquire_unique_packet_id_wait_until( + force_move(impl), + force_move(handler) + ); }, token, - get_executor() + impl_ ); } } // namespace async_mqtt +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + #endif // ASYNC_MQTT_IMPL_ENDPOINT_ACQUIRE_UNIQUE_PACKET_ID_WAIT_UNTIL_HPP diff --git a/include/async_mqtt/impl/endpoint_acquire_unique_packet_id_wait_until.ipp b/include/async_mqtt/impl/endpoint_acquire_unique_packet_id_wait_until.ipp new file mode 100644 index 000000000..534620fa3 --- /dev/null +++ b/include/async_mqtt/impl/endpoint_acquire_unique_packet_id_wait_until.ipp @@ -0,0 +1,119 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_ENDPOINT_ACQUIRE_UNIQUE_PACKET_ID_WAIT_UNTIL_IPP) +#define ASYNC_MQTT_IMPL_ENDPOINT_ACQUIRE_UNIQUE_PACKET_ID_WAIT_UNTIL_IPP + +#include +#include +#include + +namespace async_mqtt::detail { + +template +struct basic_endpoint_impl:: +acquire_unique_packet_id_wait_until_op { + this_type_sp ep; + this_type_wp retry_wp{ep}; + std::optional::type> pid_opt = std::nullopt; + enum { dispatch, complete } state = dispatch; + + template + void operator()( + Self& self, + error_code ec = error_code{} + ) { + auto& a_ep{*ep}; + if (retry_wp.expired()) return; + switch (state) { + case dispatch: { + state = complete; + as::dispatch( + a_ep.get_executor(), + force_move(self) + ); + } break; + case complete: { + auto acq_proc = + [&] { + pid_opt = a_ep.con_.acquire_unique_packet_id(); + if (pid_opt) { + self.complete(error_code{}, *pid_opt); + } + else { + ASYNC_MQTT_LOG("mqtt_impl", warning) + << ASYNC_MQTT_ADD_VALUE(address, &a_ep) + << "packet_id is fully allocated. waiting release"; + a_ep.packet_id_released_ = false; + // infinity timer. cancel is retry trigger. + auto ep_copy = ep; + async_add_retry( + force_move(ep_copy), + force_move(self) + ); + } + }; + + if (ec == as::error::operation_aborted) { + if (a_ep.packet_id_released_) { + a_ep.complete_retry_one(); + acq_proc(); + } + else { + self.complete( + ec, + 0 + ); + } + } + else if (a_ep.has_retry()) { + ASYNC_MQTT_LOG("mqtt_impl", warning) + << ASYNC_MQTT_ADD_VALUE(address, &a_ep) + << "packet_id waiter exists. add the end of waiter queue"; + // infinity timer. cancel is retry trigger. + auto ep_copy = ep; + async_add_retry( + force_move(ep_copy), + force_move(self) + ); + } + else { + acq_proc(); + } + } break; + } + } +}; + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::async_acquire_unique_packet_id_wait_until( + this_type_sp impl, + as::any_completion_handler< + void(error_code, typename basic_packet_id_type::type) + > handler +) { + auto exe = impl->get_executor(); + as::async_compose< + as::any_completion_handler< + void(error_code, typename basic_packet_id_type::type) + >, + void(error_code, typename basic_packet_id_type::type) + >( + acquire_unique_packet_id_wait_until_op{ + force_move(impl) + }, + handler, + exe + ); +} + +} // namespace async_mqtt::detail + +#include + +#endif // ASYNC_MQTT_IMPL_ENDPOINT_ACQUIRE_UNIQUE_PACKET_ID_WAIT_UNTIL_IPP diff --git a/include/async_mqtt/impl/endpoint_add_retry.hpp b/include/async_mqtt/impl/endpoint_add_retry.ipp similarity index 74% rename from include/async_mqtt/impl/endpoint_add_retry.hpp rename to include/async_mqtt/impl/endpoint_add_retry.ipp index ac4df4778..a45743928 100644 --- a/include/async_mqtt/impl/endpoint_add_retry.hpp +++ b/include/async_mqtt/impl/endpoint_add_retry.ipp @@ -4,10 +4,12 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_IMPL_ENDPOINT_ADD_RETRY_HPP) -#define ASYNC_MQTT_IMPL_ENDPOINT_ADD_RETRY_HPP +#if !defined(ASYNC_MQTT_IMPL_ENDPOINT_ADD_RETRY_IPP) +#define ASYNC_MQTT_IMPL_ENDPOINT_ADD_RETRY_IPP #include +#include +#include namespace async_mqtt::detail { @@ -58,27 +60,32 @@ add_retry_op { template -template -auto +ASYNC_MQTT_HEADER_ONLY_INLINE +void basic_endpoint_impl::async_add_retry( this_type_sp impl, - CompletionToken&& token + as::any_completion_handler< + void(error_code) + > handler ) { BOOST_ASSERT(impl); auto exe = impl->get_executor(); - return - as::async_compose< - CompletionToken, - void(error_code ec) - >( - add_retry_op{ - force_move(impl) - }, - token, - exe - ); + as::async_compose< + as::any_completion_handler< + void(error_code) + >, + void(error_code) + >( + add_retry_op{ + force_move(impl) + }, + handler, + exe + ); } } // namespace async_mqtt::detail -#endif // ASYNC_MQTT_IMPL_ENDPOINT_ADD_RETRY_HPP +#include + +#endif // ASYNC_MQTT_IMPL_ENDPOINT_ADD_RETRY_IPP diff --git a/include/async_mqtt/impl/endpoint_close.hpp b/include/async_mqtt/impl/endpoint_close.hpp index 5e55cb1a0..9e4b4a613 100644 --- a/include/async_mqtt/impl/endpoint_close.hpp +++ b/include/async_mqtt/impl/endpoint_close.hpp @@ -8,77 +8,12 @@ #define ASYNC_MQTT_IMPL_ENDPOINT_CLOSE_HPP #include +#include namespace async_mqtt { namespace detail { -template -struct basic_endpoint_impl:: -close_op { - this_type_sp ep; - enum { dispatch, close, complete } state = dispatch; - - template - void operator()( - Self& self, - error_code = error_code{} - ) { - auto& a_ep{*ep}; - switch (state) { - case dispatch: { - state = close; - as::dispatch( - a_ep.get_executor(), - force_move(self) - ); - } break; - case close: - switch (a_ep.status_) { - case connection_status::connecting: - case connection_status::connected: - case connection_status::disconnecting: { - ASYNC_MQTT_LOG("mqtt_impl", trace) - << ASYNC_MQTT_ADD_VALUE(address, &a_ep) - << "close initiate status:" << static_cast(a_ep.status_); - state = complete; - a_ep.status_ = connection_status::closing; - a_ep.stream_.async_close( - force_move(self) - ); - } break; - case connection_status::closing: { - ASYNC_MQTT_LOG("mqtt_impl", trace) - << ASYNC_MQTT_ADD_VALUE(address, &a_ep) - << "already close requested"; - a_ep.close_queue_.post( - force_move(self) - ); - } break; - case connection_status::closed: - ASYNC_MQTT_LOG("mqtt_impl", trace) - << ASYNC_MQTT_ADD_VALUE(address, &a_ep) - << "already closed"; - self.complete(); - } break; - case complete: - ASYNC_MQTT_LOG("mqtt_impl", trace) - << ASYNC_MQTT_ADD_VALUE(address, &a_ep) - << "close complete status:" << static_cast(a_ep.status_); - a_ep.tim_pingreq_send_.cancel(); - a_ep.tim_pingreq_recv_.cancel(); - a_ep.tim_pingresp_recv_.cancel(); - a_ep.status_ = connection_status::closed; - ASYNC_MQTT_LOG("mqtt_impl", trace) - << ASYNC_MQTT_ADD_VALUE(address, &a_ep) - << "process enqueued close"; - a_ep.close_queue_.poll(); - self.complete(); - break; - } - } -}; - template template auto @@ -86,21 +21,23 @@ basic_endpoint_impl::async_close( this_type_sp impl, CompletionToken&& token ) { - ASYNC_MQTT_LOG("mqtt_api", info) - << ASYNC_MQTT_ADD_VALUE(address, impl.get()) - << "close"; BOOST_ASSERT(impl); - auto exe = impl->get_executor(); return - as::async_compose< + as::async_initiate< CompletionToken, void() >( - close_op{ - force_move(impl) + []( + auto handler, + this_type_sp impl + ) { + async_close_impl( + force_move(impl), + force_move(handler) + ); }, token, - exe + force_move(impl) ); } @@ -115,18 +52,28 @@ basic_endpoint::async_close(CompletionToken&& to << "close"; BOOST_ASSERT(impl_); return - as::async_compose< + as::async_initiate< CompletionToken, void() >( - typename impl_type::close_op{ - impl_ + []( + auto handler, + std::shared_ptr impl + ) { + impl_type::async_close_impl( + force_move(impl), + force_move(handler) + ); }, token, - get_executor() + impl_ ); } } // namespace async_mqtt +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + #endif // ASYNC_MQTT_IMPL_ENDPOINT_CLOSE_HPP diff --git a/include/async_mqtt/impl/endpoint_close.ipp b/include/async_mqtt/impl/endpoint_close.ipp new file mode 100644 index 000000000..162c91f13 --- /dev/null +++ b/include/async_mqtt/impl/endpoint_close.ipp @@ -0,0 +1,113 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_ENDPOINT_CLOSE_IPP) +#define ASYNC_MQTT_IMPL_ENDPOINT_CLOSE_IPP + +#include +#include +#include + +namespace async_mqtt::detail { + +template +struct basic_endpoint_impl:: +close_op { + this_type_sp ep; + enum { dispatch, close, complete } state = dispatch; + + template + void operator()( + Self& self, + error_code = error_code{} + ) { + auto& a_ep{*ep}; + switch (state) { + case dispatch: { + state = close; + as::dispatch( + a_ep.get_executor(), + force_move(self) + ); + } break; + case close: + switch (a_ep.status_) { + case close_status::open: { + ASYNC_MQTT_LOG("mqtt_impl", trace) + << ASYNC_MQTT_ADD_VALUE(address, &a_ep) + << "close initiate status:" << static_cast(a_ep.status_); + state = complete; + a_ep.status_ = close_status::closing; + a_ep.stream_.async_close( + force_move(self) + ); + } break; + case close_status::closing: { + ASYNC_MQTT_LOG("mqtt_impl", trace) + << ASYNC_MQTT_ADD_VALUE(address, &a_ep) + << "already close requested"; + a_ep.close_queue_.post( + force_move(self) + ); + } break; + case close_status::closed: + ASYNC_MQTT_LOG("mqtt_impl", trace) + << ASYNC_MQTT_ADD_VALUE(address, &a_ep) + << "already closed"; + self.complete(); + } break; + case complete: + ASYNC_MQTT_LOG("mqtt_impl", trace) + << ASYNC_MQTT_ADD_VALUE(address, &a_ep) + << "close complete status:" << static_cast(a_ep.status_); + a_ep.tim_pingreq_send_.cancel(); + a_ep.tim_pingreq_recv_.cancel(); + a_ep.tim_pingresp_recv_.cancel(); + a_ep.status_ = close_status::closed; + ASYNC_MQTT_LOG("mqtt_impl", trace) + << ASYNC_MQTT_ADD_VALUE(address, &a_ep) + << "process enqueued close"; + a_ep.con_.notify_closed(); + a_ep.close_queue_.poll(); + self.complete(); + break; + } + } +}; + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::async_close_impl( + this_type_sp impl, + as::any_completion_handler< + void() + > handler +) { + ASYNC_MQTT_LOG("mqtt_api", info) + << ASYNC_MQTT_ADD_VALUE(address, impl.get()) + << "close"; + BOOST_ASSERT(impl); + auto exe = impl->get_executor(); + as::async_compose< + as::any_completion_handler< + void() + >, + void() + >( + close_op{ + force_move(impl) + }, + handler, + exe + ); +} + +} // namespace async_mqtt::detail + +#include + +#endif // ASYNC_MQTT_IMPL_ENDPOINT_CLOSE_IPP diff --git a/include/async_mqtt/impl/endpoint_get_stored_packets.hpp b/include/async_mqtt/impl/endpoint_get_stored_packets.hpp index 7c2e716e6..c5134a057 100644 --- a/include/async_mqtt/impl/endpoint_get_stored_packets.hpp +++ b/include/async_mqtt/impl/endpoint_get_stored_packets.hpp @@ -8,50 +8,10 @@ #define ASYNC_MQTT_IMPL_ENDPOINT_GET_STORED_PACKETS_HPP #include +#include namespace async_mqtt { -namespace detail { - -template -struct basic_endpoint_impl:: -get_stored_packets_op { - this_type_sp ep; - std::vector> packets = {}; - enum { dispatch, complete } state = dispatch; - - template - void operator()( - Self& self - ) { - auto& a_ep{*ep}; - switch (state) { - case dispatch: { - state = complete; - as::dispatch( - a_ep.get_executor(), - force_move(self) - ); - } break; - case complete: - packets = a_ep.get_stored_packets(); - self.complete(error_code{}, force_move(packets)); - break; - } - } -}; - -// sync version - -template -inline -std::vector> -basic_endpoint_impl::get_stored_packets() const { - return store_.get_stored(); -} - -} // namespace detail - template template auto @@ -63,15 +23,21 @@ basic_endpoint::async_get_stored_packets( << "get_stored_packets"; BOOST_ASSERT(impl_); return - as::async_compose< + as::async_initiate< CompletionToken, void(error_code, std::vector>) >( - typename impl_type::get_stored_packets_op{ - impl_ + []( + auto handler, + std::shared_ptr impl + ) { + impl_type::async_get_stored_packets( + force_move(impl), + force_move(handler) + ); }, token, - get_executor() + impl_ ); } @@ -90,4 +56,8 @@ basic_endpoint::get_stored_packets() const { } // namespace async_mqtt +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + #endif // ASYNC_MQTT_IMPL_ENDPOINT_GET_STORED_PACKETS_HPP diff --git a/include/async_mqtt/impl/endpoint_get_stored_packets.ipp b/include/async_mqtt/impl/endpoint_get_stored_packets.ipp new file mode 100644 index 000000000..add2e19fd --- /dev/null +++ b/include/async_mqtt/impl/endpoint_get_stored_packets.ipp @@ -0,0 +1,81 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_ENDPOINT_GET_STORED_PACKETS_IPP) +#define ASYNC_MQTT_IMPL_ENDPOINT_GET_STORED_PACKETS_IPP + +#include +#include +#include + +namespace async_mqtt::detail { + +template +struct basic_endpoint_impl:: +get_stored_packets_op { + this_type_sp ep; + std::vector> packets = {}; + enum { dispatch, complete } state = dispatch; + + template + void operator()( + Self& self + ) { + auto& a_ep{*ep}; + switch (state) { + case dispatch: { + state = complete; + as::dispatch( + a_ep.get_executor(), + force_move(self) + ); + } break; + case complete: + packets = a_ep.con_.get_stored_packets(); + self.complete(error_code{}, force_move(packets)); + break; + } + } +}; + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::async_get_stored_packets( + this_type_sp impl, + as::any_completion_handler< + void(error_code, std::vector>) + > handler +) { + auto exe = impl->get_executor(); + as::async_compose< + as::any_completion_handler< + void(error_code, std::vector>) + >, + void(error_code, std::vector>) + >( + get_stored_packets_op{ + force_move(impl) + }, + handler, + exe + ); +} + +// sync version + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +std::vector> +basic_endpoint_impl::get_stored_packets() const { + return con_.get_stored_packets(); +} + +} // namespace async_mqtt::detail + +#include + +#endif // ASYNC_MQTT_IMPL_ENDPOINT_GET_STORED_PACKETS_IPP diff --git a/include/async_mqtt/impl/endpoint_impl.hpp b/include/async_mqtt/impl/endpoint_impl.hpp index 22c8091f7..ebc82831b 100644 --- a/include/async_mqtt/impl/endpoint_impl.hpp +++ b/include/async_mqtt/impl/endpoint_impl.hpp @@ -4,186 +4,332 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_IMPL_ENDPOINT_IMPL_HPP) -#define ASYNC_MQTT_IMPL_ENDPOINT_IMPL_HPP - -#include - -namespace async_mqtt { - -namespace detail { - -// classes +#if !defined(ASYNC_MQTT_DETAIL_ENDPOINT_IMPL_HPP) +#define ASYNC_MQTT_DETAIL_ENDPOINT_IMPL_HPP + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace async_mqtt::detail { template -struct basic_endpoint_impl::tim_cancelled { - tim_cancelled( - std::shared_ptr tim, - bool cancelled = false - ):tim{force_move(tim)}, cancelled{cancelled} - {} - std::shared_ptr tim; - bool cancelled; -}; - -// member functions - -// public +class basic_endpoint_impl { + + using this_type = basic_endpoint_impl; + using this_type_sp = std::shared_ptr; + using this_type_wp = std::weak_ptr; + using stream_type = + stream< + NextLayer + >; + +public: + using next_layer_type = typename stream_type::next_layer_type; + using lowest_layer_type = typename stream_type::lowest_layer_type; + using executor_type = typename next_layer_type::executor_type; + using packet_variant_type = basic_packet_variant; + + template + explicit + basic_endpoint_impl( + protocol_version ver, + Args&&... args + ); -template -template -basic_endpoint_impl::basic_endpoint_impl( - protocol_version ver, - Args&&... args -): protocol_version_{ver}, - stream_{std::forward(args)...}, - store_{stream_.get_executor()}, - tim_pingreq_send_{stream_.get_executor()}, - tim_pingreq_recv_{stream_.get_executor()}, - tim_pingresp_recv_{stream_.get_executor()} -{ - BOOST_ASSERT( - (Role == role::client && ver != protocol_version::undetermined) || - Role != role::client - ); -} + ~basic_endpoint_impl() = default; + basic_endpoint_impl(this_type const&) = delete; + basic_endpoint_impl(this_type&&) = delete; + + this_type& operator=(this_type const&) = delete; + this_type& operator=(this_type&&) = delete; + + as::any_io_executor get_executor(); + next_layer_type const& next_layer() const; + next_layer_type& next_layer(); + lowest_layer_type const& lowest_layer() const; + lowest_layer_type& lowest_layer(); + + void underlying_accepted(); + void set_offline_publish(bool val); + void set_auto_pub_response(bool val); + void set_auto_ping_response(bool val); + void set_auto_map_topic_alias_send(bool val); + void set_auto_replace_topic_alias_send(bool val); + void set_pingresp_recv_timeout(std::chrono::milliseconds duration); + void set_close_delay_after_disconnect_sent(std::chrono::milliseconds duration); + void set_bulk_write(bool val); + void set_read_buffer_size(std::size_t val); + + // async funcs + static void + async_acquire_unique_packet_id( + this_type_sp impl, + as::any_completion_handler< + void(error_code, typename basic_packet_id_type::type) + > handler + ); -template -inline -as::any_io_executor -basic_endpoint_impl::get_executor() { - return stream_.get_executor(); -} + static void + async_acquire_unique_packet_id_wait_until( + this_type_sp impl, + as::any_completion_handler< + void(error_code, typename basic_packet_id_type::type) + > handler + ); -template -inline -typename basic_endpoint_impl::next_layer_type const& -basic_endpoint_impl::next_layer() const { - return stream_.next_layer(); -} + static void + async_register_packet_id( + this_type_sp impl, + typename basic_packet_id_type::type packet_id, + as::any_completion_handler< + void(error_code) + > handler + ); -template -inline -typename basic_endpoint_impl::next_layer_type& -basic_endpoint_impl::next_layer() { - return stream_.next_layer(); -} + static void + async_release_packet_id( + this_type_sp impl, + typename basic_packet_id_type::type packet_id, + as::any_completion_handler< + void() + > handler + ); -template -inline -typename basic_endpoint_impl::lowest_layer_type const& -basic_endpoint_impl::lowest_layer() const { - return stream_.lowest_layer(); -} + static void + async_recv( + this_type_sp impl, + std::optional fil, + std::set types, + as::any_completion_handler< + void(error_code, std::optional) + > handler + ); -template -inline -typename basic_endpoint_impl::lowest_layer_type& -basic_endpoint_impl::lowest_layer() { - return stream_.lowest_layer(); -} + static void + async_get_stored_packets( + this_type_sp impl, + as::any_completion_handler< + void(error_code, std::vector>) + > handler + ); + static void + async_regulate_for_store( + this_type_sp impl, + v5::basic_publish_packet packet, + as::any_completion_handler< + void(error_code, v5::basic_publish_packet) + > handler + ); -// private + static void + async_restore_packets( + this_type_sp impl, + std::vector> pvs, + as::any_completion_handler< + void() + > handler + ); -template -inline -constexpr bool -basic_endpoint_impl::can_send_as_client(role r) { - return - static_cast(r) & - static_cast(role::client); -} + // sync funcs -template -inline -constexpr bool -basic_endpoint_impl::can_send_as_server(role r) { - return static_cast(r) & static_cast(role::server); -} + std::optional::type> acquire_unique_packet_id(); + bool register_packet_id(typename basic_packet_id_type::type packet_id); + void release_packet_id(typename basic_packet_id_type::type packet_id); + std::set::type> get_qos2_publish_handled_pids() const; + void restore_qos2_publish_handled_pids(std::set::type> pids); + void restore_packets( + std::vector> pvs + ); + std::vector> get_stored_packets() const; + protocol_version get_protocol_version() const; + bool is_publish_processing(typename basic_packet_id_type::type pid) const; + void regulate_for_store( + v5::basic_publish_packet& packet, + error_code& ec + ) const; + static void set_pingreq_send_interval( + this_type_sp ep, + std::chrono::milliseconds duration + ); -template -template -basic_endpoint_impl::basic_endpoint_impl( - basic_endpoint_impl&& other -): protocol_version_{other.ver}, - stream_{force_move(other.stream_)}, - store_{stream_.get_executor()}, - tim_pingreq_send_{stream_.get_executor()}, - tim_pingreq_recv_{stream_.get_executor()}, - tim_pingresp_recv_{stream_.get_executor()} -{ -} + template + struct rebind_executor { + using other = basic_endpoint< + Role, + PacketIdBytes, + typename NextLayer::template rebind_executor::other + >; + }; + + template < + typename ArgsTuple, + typename CompletionToken = as::default_completion_token_t + > + static + auto + async_underlying_handshake_impl( + this_type_sp impl, + ArgsTuple&& args_tuple, + CompletionToken&& token = as::default_completion_token_t{} + ); -} // namespace detail +private: // compose operation impl -// member functions + template + explicit + basic_endpoint_impl( + basic_endpoint_impl&& other + ); -// public + template struct underlying_handshake_op; + struct acquire_unique_packet_id_op; + struct acquire_unique_packet_id_wait_until_op; + struct register_packet_id_op; + struct release_packet_id_op; + template struct send_op; + struct recv_op; + struct close_op; + struct restore_packets_op; + struct get_stored_packets_op; + struct regulate_for_store_op; + struct add_retry_op; + +private: + + template < + typename Packet, + typename CompletionToken = as::default_completion_token_t + > + static + auto + async_send( + this_type_sp impl, + Packet packet, + bool from_queue, + CompletionToken&& token = as::default_completion_token_t{} + ); -template -template -basic_endpoint::basic_endpoint( - protocol_version ver, - Args&&... args -): impl_{ - std::make_shared( - ver, - std::forward(args)... - ) -} -{ -} + template < + typename Packet, + typename CompletionToken = as::default_completion_token_t + > + static + auto + async_send( + this_type_sp impl, + Packet packet, + CompletionToken&& token = as::default_completion_token_t{} + ); -template -inline -as::any_io_executor -basic_endpoint::get_executor() { - return impl_->get_executor(); -} + template < + typename CompletionToken = as::default_completion_token_t + > + static + auto + async_close( + this_type_sp impl, + CompletionToken&& token = as::default_completion_token_t{} + ); -template -inline -typename basic_endpoint::next_layer_type const& -basic_endpoint::next_layer() const { - return impl_->next_layer(); -} + static void + async_close_impl( + this_type_sp impl, + as::any_completion_handler< + void() + > handler + ); -template -inline -typename basic_endpoint::next_layer_type& -basic_endpoint::next_layer() { - return impl_->next_layer(); -} + static + void + async_add_retry( + this_type_sp impl, + as::any_completion_handler< + void(error_code) + > handler + ); -template -inline -typename basic_endpoint::lowest_layer_type const& -basic_endpoint::lowest_layer() const { - return impl_->lowest_layer(); -} + bool enqueue_publish(v5::basic_publish_packet& packet); + void initialize(); -template -inline -typename basic_endpoint::lowest_layer_type& -basic_endpoint::lowest_layer() { - return impl_->lowest_layer(); -} + static void set_pingreq_send_timer( + this_type_sp ep, + std::optional ms + ); + static void reset_pingreq_send_timer( + this_type_sp ep, + std::optional ms + ); + static void cancel_pingreq_send_timer( + this_type_sp ep + ); -// private + static void set_pingreq_recv_timer( + this_type_sp ep, + std::optional ms + ); + static void reset_pingreq_recv_timer( + this_type_sp ep, + std::optional ms + ); + static void cancel_pingreq_recv_timer( + this_type_sp ep + ); -template -template -basic_endpoint::basic_endpoint( - basic_endpoint&& other -): impl_{std::move(other.impl_)} -{ -} + static void reset_pingresp_recv_timer( + this_type_sp ep, + std::optional ms + ); -} // namespace async_mqtt + void notify_retry_one(); + void complete_retry_one(); + void notify_retry_all(); + bool has_retry() const; + + void clear_pid_man(); + void notify_release_pid(typename basic_packet_id_type::type pid); + +private: + + friend class basic_endpoint; + stream_type stream_; + std::size_t read_buffer_size_ = 65535; // TBD define constant + as::streambuf read_buf_; + basic_rv_connection con_; + + std::deque> publish_queue_; + ioc_queue close_queue_; + + as::steady_timer tim_pingreq_send_; + as::steady_timer tim_pingreq_recv_; + as::steady_timer tim_pingresp_recv_; + as::steady_timer tim_close_by_disconnect_; + std::chrono::milliseconds duration_close_by_disconnect_{std::chrono::milliseconds::zero()}; + struct tim_cancelled; + std::deque tim_retry_acq_pid_queue_; + bool packet_id_released_ = false; + + enum class close_status { + open, + closing, + closed + }; + close_status status_{close_status::closed}; + std::deque> recv_events_; +}; -#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include -#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +} // namespace async_mqtt::detail -#endif // ASYNC_MQTT_IMPL_ENDPOINT_IMPL_HPP +#endif // ASYNC_MQTT_DETAIL_ENDPOINT_IMPL_HPP diff --git a/include/async_mqtt/impl/endpoint_impl.ipp b/include/async_mqtt/impl/endpoint_impl.ipp deleted file mode 100644 index 15a169f87..000000000 --- a/include/async_mqtt/impl/endpoint_impl.ipp +++ /dev/null @@ -1,646 +0,0 @@ -// Copyright Takatoshi Kondo 2022 -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#if !defined(ASYNC_MQTT_IMPL_ENDPOINT_IMPL_IPP) -#define ASYNC_MQTT_IMPL_ENDPOINT_IMPL_IPP - -#include -#include - -namespace async_mqtt { - -namespace detail { - -// member functions - -// public - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl::set_auto_pub_response(bool val) { - auto_pub_response_ = val; -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl::set_auto_ping_response(bool val) { - auto_ping_response_ = val; -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl::set_auto_map_topic_alias_send(bool val) { - auto_map_topic_alias_send_ = val; -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl::set_auto_replace_topic_alias_send(bool val) { - auto_replace_topic_alias_send_ = val; -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl::set_pingresp_recv_timeout( - std::chrono::milliseconds duration -) { - if (duration == std::chrono::milliseconds::zero()) { - pingresp_recv_timeout_ms_ = std::nullopt; - } - else { - pingresp_recv_timeout_ms_.emplace(duration); - } -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl::set_bulk_write(bool val) { - stream_.set_bulk_write(val); -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl::set_bulk_read_buffer_size(std::size_t val) { - stream_.set_bulk_read_buffer_size(val); -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -std::set::type> -basic_endpoint_impl::get_qos2_publish_handled_pids() const { - return qos2_publish_handled_; -} - - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl::restore_qos2_publish_handled_pids( - std::set::type> pids -) { - qos2_publish_handled_ = force_move(pids); -} - - - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -protocol_version -basic_endpoint_impl::get_protocol_version() const { - return protocol_version_; -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -bool -basic_endpoint_impl::is_publish_processing(typename basic_packet_id_type::type pid) const { - return qos2_publish_processing_.find(pid) != qos2_publish_processing_.end(); -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl::set_pingreq_send_interval( - this_type_sp ep, - std::chrono::milliseconds duration -) { - if (duration == std::chrono::milliseconds::zero()) { - ep->pingreq_send_interval_ms_.reset(); - ep->tim_pingreq_send_.cancel(); - } - else { - ep->pingreq_send_interval_ms_.emplace(duration); - reset_pingreq_send_timer(force_move(ep)); - } -} - -// private - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -std::optional -basic_endpoint_impl::get_topic_alias(properties const& props) { - std::optional ta_opt; - for (auto const& prop : props) { - prop.visit( - overload { - [&](property::topic_alias const& p) { - ta_opt.emplace(p.val()); - }, - [](auto const&) { - } - } - ); - if (ta_opt) return ta_opt; - } - return ta_opt; -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -bool -basic_endpoint_impl::enqueue_publish( - v5::basic_publish_packet& packet -) { - if (packet.opts().get_qos() == qos::at_least_once || - packet.opts().get_qos() == qos::exactly_once - ) { - if (publish_send_count_ == publish_send_max_) { - publish_queue_.push_back(force_move(packet)); - return true; - } - else { - ++publish_send_count_; - if (!publish_queue_.empty()) { - publish_queue_.push_back(force_move(packet)); - return true; - } - } - } - return false; -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl::send_stored(this_type_sp ep) { - ep->store_.for_each( - [&](basic_store_packet_variant const& pv) { - if (pv.size() > ep->maximum_packet_size_send_) { - ep->release_pid(pv.packet_id()); - return false; - } - pv.visit( - // copy packet because the stored packets need to be preserved - // until receiving puback/pubrec/pubcomp - overload { - [&](v3_1_1::basic_publish_packet p) { - async_send( - ep, - p, - as::detached - ); - }, - [&](v5::basic_publish_packet p) { - if (ep->enqueue_publish(p)) return; - async_send( - ep, - p, - as::detached - ); - }, - [&](v3_1_1::basic_pubrel_packet p) { - async_send( - ep, - p, - as::detached - ); - }, - [&](v5::basic_pubrel_packet p) { - async_send( - ep, - p, - as::detached - ); - } - } - ); - return true; - } - ); -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl::initialize() { - publish_send_count_ = 0; - publish_queue_.clear(); - topic_alias_send_ = std::nullopt; - topic_alias_recv_ = std::nullopt; - publish_recv_.clear(); - qos2_publish_processing_.clear(); - need_store_ = false; - pid_suback_.clear(); - pid_unsuback_.clear(); - pid_puback_.clear(); - pid_pubrec_.clear(); - pid_pubcomp_.clear(); -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl::reset_pingreq_send_timer( - this_type_sp ep -) { - if constexpr (Role == role::client || Role == role::any) { - if (ep->pingreq_send_interval_ms_) { - ep->tim_pingreq_send_.cancel(); - if (ep->status_ == connection_status::disconnecting || - ep->status_ == connection_status::closing || - ep->status_ == connection_status::closed) return; - ep->tim_pingreq_send_.expires_after( - *ep->pingreq_send_interval_ms_ - ); - ep->tim_pingreq_send_.async_wait( - [wp = std::weak_ptr{ep}](error_code const& ec) { - if (!ec) { - if (auto ep = wp.lock()) { - switch (ep->protocol_version_) { - case protocol_version::v3_1_1: - async_send( - ep, - v3_1_1::pingreq_packet(), - as::detached - ); - break; - case protocol_version::v5: - async_send( - ep, - v5::pingreq_packet(), - as::detached - ); - break; - default: - BOOST_ASSERT(false); - break; - } - } - } - } - ); - } - } -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl::reset_pingreq_recv_timer( - this_type_sp ep -) { - if (ep->pingreq_recv_timeout_ms_) { - ep->tim_pingreq_recv_.cancel(); - if (ep->status_ == connection_status::disconnecting || - ep->status_ == connection_status::closing || - ep->status_ == connection_status::closed) return; - ep->tim_pingreq_recv_.expires_after( - *ep->pingreq_recv_timeout_ms_ - ); - ep->tim_pingreq_recv_.async_wait( - [wp = std::weak_ptr{ep}](error_code const& ec) { - if (!ec) { - if (auto ep = wp.lock()) { - switch (ep->protocol_version_) { - case protocol_version::v3_1_1: - ASYNC_MQTT_LOG("mqtt_impl", error) - << ASYNC_MQTT_ADD_VALUE(address, ep.get()) - << "pingreq recv timeout. close."; - async_close( - ep, - as::detached - ); - break; - case protocol_version::v5: - ASYNC_MQTT_LOG("mqtt_impl", error) - << ASYNC_MQTT_ADD_VALUE(address, ep.get()) - << "pingreq recv timeout. close."; - async_send( - ep, - v5::disconnect_packet{ - disconnect_reason_code::keep_alive_timeout, - properties{} - }, - [ep](error_code const&){ - async_close( - ep, - as::detached - ); - } - ); - break; - default: - BOOST_ASSERT(false); - break; - } - } - } - } - ); - } -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl::reset_pingresp_recv_timer( - this_type_sp ep -) { - if (ep->pingresp_recv_timeout_ms_) { - ep->tim_pingresp_recv_.cancel(); - if (ep->status_ == connection_status::disconnecting || - ep->status_ == connection_status::closing || - ep->status_ == connection_status::closed) return; - ep->tim_pingresp_recv_.expires_after( - *ep->pingresp_recv_timeout_ms_ - ); - ep->tim_pingresp_recv_.async_wait( - [wp = std::weak_ptr{ep}](error_code const& ec) { - if (!ec) { - if (auto ep = wp.lock()) { - switch (ep->protocol_version_) { - case protocol_version::v3_1_1: - ASYNC_MQTT_LOG("mqtt_impl", error) - << ASYNC_MQTT_ADD_VALUE(address, ep.get()) - << "pingresp recv timeout. close."; - async_close( - ep, - as::detached - ); - break; - case protocol_version::v5: - ASYNC_MQTT_LOG("mqtt_impl", error) - << ASYNC_MQTT_ADD_VALUE(address, ep.get()) - << "pingresp recv timeout. close."; - if (ep->status_ == connection_status::connected) { - async_send( - ep, - v5::disconnect_packet{ - disconnect_reason_code::keep_alive_timeout, - properties{} - }, - [ep](error_code const&){ - async_close( - ep, - as::detached - ); - } - ); - } - else { - async_close( - ep, - as::detached - ); - } - break; - default: - BOOST_ASSERT(false); - break; - } - } - } - } - ); - } -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl::notify_retry_one() { - for (auto it = tim_retry_acq_pid_queue_.begin(); - it != tim_retry_acq_pid_queue_.end(); - ++it - ) { - if (it->cancelled) continue; - it->tim->cancel(); - it->cancelled = true; - return; - } -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl::complete_retry_one() { - if (!tim_retry_acq_pid_queue_.empty()) { - tim_retry_acq_pid_queue_.pop_front(); - } -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl::notify_retry_all() { - tim_retry_acq_pid_queue_.clear(); -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -bool -basic_endpoint_impl::has_retry() const { - return !tim_retry_acq_pid_queue_.empty(); -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl::clear_pid_man() { - pid_man_.clear(); - notify_retry_all(); -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl::release_pid(typename basic_packet_id_type::type pid) { - pid_man_.release_id(pid); - packet_id_released_ = true; - notify_retry_one(); -} - -} // namespace detail - -// member functions - -// public - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -basic_endpoint::~basic_endpoint() { - ASYNC_MQTT_LOG("mqtt_impl", trace) - << ASYNC_MQTT_ADD_VALUE(address, this) - << "destroy"; -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint::set_auto_pub_response(bool val) { - ASYNC_MQTT_LOG("mqtt_api", info) - << ASYNC_MQTT_ADD_VALUE(address, this) - << "set_auto_pub_response val:" << val; - BOOST_ASSERT(impl_); - impl_->set_auto_pub_response(val); -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint::set_auto_ping_response(bool val) { - ASYNC_MQTT_LOG("mqtt_api", info) - << ASYNC_MQTT_ADD_VALUE(address, this) - << "set_auto_ping_response val:" << val; - BOOST_ASSERT(impl_); - impl_->set_auto_ping_response(val); -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint::set_auto_map_topic_alias_send(bool val) { - ASYNC_MQTT_LOG("mqtt_api", info) - << ASYNC_MQTT_ADD_VALUE(address, this) - << "set_auto_map_topic_alias_send val:" << val; - BOOST_ASSERT(impl_); - impl_->set_auto_map_topic_alias_send(val); -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint::set_auto_replace_topic_alias_send(bool val) { - ASYNC_MQTT_LOG("mqtt_api", info) - << ASYNC_MQTT_ADD_VALUE(address, this) - << "set_auto_replace_topic_alias_send val:" << val; - BOOST_ASSERT(impl_); - impl_->set_auto_replace_topic_alias_send(val); -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint::set_pingresp_recv_timeout( - std::chrono::milliseconds duration -) { - BOOST_ASSERT(impl_); - impl_->set_pingresp_recv_timeout(duration); -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint::set_bulk_write(bool val) { - BOOST_ASSERT(impl_); - impl_->set_bulk_write(val); -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint::set_bulk_read_buffer_size(std::size_t val) { - BOOST_ASSERT(impl_); - impl_->set_bulk_read_buffer_size(val); -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -std::set::type> -basic_endpoint::get_qos2_publish_handled_pids() const { - ASYNC_MQTT_LOG("mqtt_api", info) - << ASYNC_MQTT_ADD_VALUE(address, this) - << "get_qos2_publish_handled_pids"; - BOOST_ASSERT(impl_); - return impl_->get_qos2_publish_handled_pids(); -} - - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint::restore_qos2_publish_handled_pids( - std::set::type> pids -) { - ASYNC_MQTT_LOG("mqtt_api", info) - << ASYNC_MQTT_ADD_VALUE(address, this) - << "restore_qos2_publish_handled_pids"; - BOOST_ASSERT(impl_); - impl_->restore_qos2_publish_handled_pids(force_move(pids)); -} - - - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -protocol_version -basic_endpoint::get_protocol_version() const { - auto protocol_version = impl_->get_protocol_version(); - ASYNC_MQTT_LOG("mqtt_api", info) - << ASYNC_MQTT_ADD_VALUE(address, this) - << "get_protocol_version:" << protocol_version; - BOOST_ASSERT(impl_); - return protocol_version; -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -bool -basic_endpoint::is_publish_processing(typename basic_packet_id_type::type pid) const { - ASYNC_MQTT_LOG("mqtt_api", info) - << ASYNC_MQTT_ADD_VALUE(address, this) - << "is_publish_processing:" << pid; - BOOST_ASSERT(impl_); - return impl_->is_publish_processing(pid); -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint::set_pingreq_send_interval( - std::chrono::milliseconds duration -) { - ASYNC_MQTT_LOG("mqtt_api", info) - << ASYNC_MQTT_ADD_VALUE(address, this) - << "set_pingreq_send_interval"; - BOOST_ASSERT(impl_); - impl_type::set_pingreq_send_interval( - impl_, - duration - ); -} - -} // namespace async_mqtt - -#if defined(ASYNC_MQTT_SEPARATE_COMPILATION) - -#include - - -#define ASYNC_MQTT_INSTANTIATE_EACH(a_role, a_size, a_protocol) \ -namespace async_mqtt { \ -namespace detail { \ -template \ -class basic_endpoint_impl; \ -} \ -template \ -class basic_endpoint; \ -} // namespace async_mqtt - -#define ASYNC_MQTT_PP_GENERATE(r, product) \ - BOOST_PP_EXPAND( \ - ASYNC_MQTT_INSTANTIATE_EACH \ - BOOST_PP_SEQ_TO_TUPLE( \ - product \ - ) \ - ) - -BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_ROLE)(ASYNC_MQTT_PP_SIZE)(ASYNC_MQTT_PP_PROTOCOL)) - -#undef ASYNC_MQTT_PP_GENERATE -#undef ASYNC_MQTT_INSTANTIATE_EACH - -#endif // defined(ASYNC_MQTT_SEPARATE_COMPILATION) - -#endif // ASYNC_MQTT_IMPL_ENDPOINT_IMPL_IPP diff --git a/include/async_mqtt/impl/endpoint_instantiate.hpp b/include/async_mqtt/impl/endpoint_instantiate.hpp new file mode 100644 index 000000000..6fea7632c --- /dev/null +++ b/include/async_mqtt/impl/endpoint_instantiate.hpp @@ -0,0 +1,39 @@ +// Copyright Takatoshi Kondo 2024 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_ENDPOINT_INSTANTIATE_HPP) +#define ASYNC_MQTT_IMPL_ENDPOINT_INSTANTIATE_HPP + +#if defined(ASYNC_MQTT_SEPARATE_COMPILATION) + +#include + +#define ASYNC_MQTT_INSTANTIATE_EACH(a_role, a_size, a_protocol) \ +namespace async_mqtt { \ +namespace detail { \ +template \ +class basic_endpoint_impl; \ +} \ +template \ +class basic_endpoint; \ +} // namespace async_mqtt + +#define ASYNC_MQTT_PP_GENERATE(r, product) \ + BOOST_PP_EXPAND( \ + ASYNC_MQTT_INSTANTIATE_EACH \ + BOOST_PP_SEQ_TO_TUPLE( \ + product \ + ) \ + ) + +BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_ROLE)(ASYNC_MQTT_PP_SIZE)(ASYNC_MQTT_PP_PROTOCOL)) + +#undef ASYNC_MQTT_PP_GENERATE +#undef ASYNC_MQTT_INSTANTIATE_EACH + +#endif // defined(ASYNC_MQTT_SEPARATE_COMPILATION) + +#endif // ASYNC_MQTT_IMPL_ENDPOINT_INSTANTIATE_HPP diff --git a/include/async_mqtt/impl/endpoint_misc.hpp b/include/async_mqtt/impl/endpoint_misc.hpp new file mode 100644 index 000000000..633d633c8 --- /dev/null +++ b/include/async_mqtt/impl/endpoint_misc.hpp @@ -0,0 +1,173 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_ENDPOINT_IMPL_HPP) +#define ASYNC_MQTT_IMPL_ENDPOINT_IMPL_HPP + +#include +#include + +namespace async_mqtt { + +namespace detail { + +// classes + +template +struct basic_endpoint_impl::tim_cancelled { + tim_cancelled( + std::shared_ptr tim, + bool cancelled = false + ):tim{force_move(tim)}, cancelled{cancelled} + {} + std::shared_ptr tim; + bool cancelled; +}; + +// member functions + +// public + +template +template +basic_endpoint_impl::basic_endpoint_impl( + protocol_version ver, + Args&&... args +): stream_{std::forward(args)...}, + con_{ver}, + tim_pingreq_send_{stream_.get_executor()}, + tim_pingreq_recv_{stream_.get_executor()}, + tim_pingresp_recv_{stream_.get_executor()}, + tim_close_by_disconnect_{stream_.get_executor()} +{ + BOOST_ASSERT( + (Role == role::client && ver != protocol_version::undetermined) || + Role != role::client + ); +} + +template +inline +as::any_io_executor +basic_endpoint_impl::get_executor() { + return stream_.get_executor(); +} + +template +inline +typename basic_endpoint_impl::next_layer_type const& +basic_endpoint_impl::next_layer() const { + return stream_.next_layer(); +} + +template +inline +typename basic_endpoint_impl::next_layer_type& +basic_endpoint_impl::next_layer() { + return stream_.next_layer(); +} + +template +inline +typename basic_endpoint_impl::lowest_layer_type const& +basic_endpoint_impl::lowest_layer() const { + return stream_.lowest_layer(); +} + +template +inline +typename basic_endpoint_impl::lowest_layer_type& +basic_endpoint_impl::lowest_layer() { + return stream_.lowest_layer(); +} + + +// private + +template +template +basic_endpoint_impl::basic_endpoint_impl( + basic_endpoint_impl&& other +): stream_{force_move(other.stream_)}, + con_{force_move(other.con_)}, + tim_pingreq_send_{stream_.get_executor()}, + tim_pingreq_recv_{stream_.get_executor()}, + tim_pingresp_recv_{stream_.get_executor()} +{ +} + +} // namespace detail + +// member functions + +// public + +template +template +basic_endpoint::basic_endpoint( + protocol_version ver, + Args&&... args +): impl_{ + std::make_shared( + ver, + std::forward(args)... + ) +} +{ +} + +template +inline +as::any_io_executor +basic_endpoint::get_executor() { + return impl_->get_executor(); +} + +template +inline +typename basic_endpoint::next_layer_type const& +basic_endpoint::next_layer() const { + return impl_->next_layer(); +} + +template +inline +typename basic_endpoint::next_layer_type& +basic_endpoint::next_layer() { + return impl_->next_layer(); +} + +template +inline +typename basic_endpoint::lowest_layer_type const& +basic_endpoint::lowest_layer() const { + return impl_->lowest_layer(); +} + +template +inline +typename basic_endpoint::lowest_layer_type& +basic_endpoint::lowest_layer() { + return impl_->lowest_layer(); +} + +// private + +template +template +basic_endpoint::basic_endpoint( + basic_endpoint&& other +): impl_{std::move(other.impl_)} +{ +} + +} // namespace async_mqtt + +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + +#endif // ASYNC_MQTT_IMPL_ENDPOINT_IMPL_HPP diff --git a/include/async_mqtt/impl/endpoint_misc.ipp b/include/async_mqtt/impl/endpoint_misc.ipp new file mode 100644 index 000000000..be44acc37 --- /dev/null +++ b/include/async_mqtt/impl/endpoint_misc.ipp @@ -0,0 +1,698 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_ENDPOINT_IMPL_IPP) +#define ASYNC_MQTT_IMPL_ENDPOINT_IMPL_IPP + +#include +#include +#include + +namespace async_mqtt { + +namespace detail { + +// member functions + +// public + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::underlying_accepted() { + status_ = close_status::open; +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::set_offline_publish(bool val) { + con_.set_offline_publish(val); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::set_auto_pub_response(bool val) { + con_.set_auto_pub_response(val); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::set_auto_ping_response(bool val) { + con_.set_auto_ping_response(val); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::set_auto_map_topic_alias_send(bool val) { + con_.set_auto_map_topic_alias_send(val); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::set_auto_replace_topic_alias_send(bool val) { + con_.set_auto_replace_topic_alias_send(val); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::set_pingresp_recv_timeout( + std::chrono::milliseconds duration +) { + con_.set_pingresp_recv_timeout(duration); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::set_close_delay_after_disconnect_sent( + std::chrono::milliseconds duration +) { + duration_close_by_disconnect_ = duration; +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::set_bulk_write(bool val) { + stream_.set_bulk_write(val); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::set_read_buffer_size(std::size_t val) { + read_buffer_size_ = val; +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +std::set::type> +basic_endpoint_impl::get_qos2_publish_handled_pids() const { + return con_.get_qos2_publish_handled_pids(); +} + + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::restore_qos2_publish_handled_pids( + std::set::type> pids +) { + con_.restore_qos2_publish_handled_pids(force_move(pids)); +} + + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +protocol_version +basic_endpoint_impl::get_protocol_version() const { + return con_.get_protocol_version(); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +bool +basic_endpoint_impl::is_publish_processing(typename basic_packet_id_type::type pid) const { + return con_.is_publish_processing(pid); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::set_pingreq_send_interval( + this_type_sp ep, + std::chrono::milliseconds duration +) { + auto events = ep->con_.set_pingreq_send_interval(duration); + for (auto& event : events) { + std::visit( + overload { + [&](async_mqtt::event::timer const& ev) { + if (ev.get_kind() == timer_kind::pingreq_send) { + switch (ev.get_op()) { + case timer_op::set: + set_pingreq_send_timer(ep, ev.get_ms()); + break; + case timer_op::reset: + reset_pingreq_send_timer(ep, ev.get_ms()); + break; + case timer_op::cancel: + cancel_pingreq_send_timer(ep); + break; + } + } + else { + BOOST_ASSERT(false); + } + }, + [&](auto const&) { + BOOST_ASSERT(false); + } + }, + event + ); + } +} + +// private + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +bool +basic_endpoint_impl::enqueue_publish( + v5::basic_publish_packet& packet +) { + if (packet.opts().get_qos() == qos::at_least_once || + packet.opts().get_qos() == qos::exactly_once + ) { + auto vacancy_opt = con_.get_receive_maximum_vacancy_for_send(); + if (vacancy_opt && *vacancy_opt == 0) { + publish_queue_.push_back(force_move(packet)); + return true; + } + else { + if (!publish_queue_.empty()) { + publish_queue_.push_back(force_move(packet)); + return true; + } + } + } + return false; +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::initialize() { + // TBD where call from? + publish_queue_.clear(); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::set_pingreq_send_timer( + this_type_sp ep, + std::optional ms +) { + if constexpr (Role == role::client || Role == role::any) { + if (ms) { + ep->tim_pingreq_send_.expires_after( + *ms + ); + ep->tim_pingreq_send_.async_wait( + [wp = std::weak_ptr{ep}](error_code const& ec) { + if (!ec) { + if (auto ep = wp.lock()) { + auto events = ep->con_.notify_timer_fired(timer_kind::pingreq_send); + for (auto& event : events) { + namespace event_ns = async_mqtt::event; + std::visit( + overload { + [&](event_ns::timer const& ev) { + if (ev.get_kind() == timer_kind::pingreq_send) { + switch (ev.get_op()) { + case timer_op::set: + reset_pingreq_send_timer(ep, ev.get_ms()); + break; + case timer_op::reset: + reset_pingreq_send_timer(ep, ev.get_ms()); + break; + case timer_op::cancel: + ep->tim_pingreq_send_.cancel(); + break; + } + } + else { + BOOST_ASSERT(false); + } + }, + [&](event_ns::basic_send& ev) { + // must be pingreq packet here + BOOST_ASSERT(!ev.get_release_packet_id_if_send_error()); + ep->stream_.async_write_packet( + force_move(ev.get()), + as::detached + ); + }, + [&](auto const&) { + BOOST_ASSERT(false); + } + }, + event + ); + } + } + } + } + ); + } + } +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::reset_pingreq_send_timer( + this_type_sp ep, + std::optional ms +) { + cancel_pingreq_send_timer(ep); + set_pingreq_send_timer(ep, ms); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::cancel_pingreq_send_timer( + this_type_sp ep +) { + ep->tim_pingreq_send_.cancel(); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::set_pingreq_recv_timer( + this_type_sp ep, + std::optional ms +) { + if constexpr (Role == role::server || Role == role::any) { + if (ms) { + ep->tim_pingreq_recv_.expires_after( + *ms + ); + + ep->tim_pingreq_recv_.async_wait( + [wp = std::weak_ptr{ep}](error_code const& ec) { + if (!ec) { + if (auto ep = wp.lock()) { + auto events = ep->con_.notify_timer_fired(timer_kind::pingreq_recv); + for (auto it = events.begin(); it != events.end();) { + auto& event = *it++; + std::visit( + overload { + [&](async_mqtt::event::timer const& ev) { + if (ev.get_kind() == timer_kind::pingreq_recv) { + switch (ev.get_op()) { + case timer_op::set: + reset_pingreq_recv_timer(ep, ev.get_ms()); + break; + case timer_op::reset: + reset_pingreq_recv_timer(ep, ev.get_ms()); + break; + case timer_op::cancel: + ep->tim_pingreq_recv_.cancel(); + break; + } + } + else { + BOOST_ASSERT(false); + } + }, + [&](async_mqtt::event::basic_send& ev) { + auto pv{force_move(ev.get())}; + BOOST_ASSERT(pv.template get_if()); + BOOST_ASSERT(it != events.end()); + auto& ev_close = *it++; + BOOST_ASSERT(it == events.end()); + BOOST_ASSERT(std::get_if(&ev_close)); + ep->stream_.async_write_packet( + force_move(pv), + [ep] + ( + error_code const& /*ec*/, + std::size_t /*bytes_transferred*/ + ) { + async_close(ep, as::detached); + } + ); + }, + [&](async_mqtt::event::close const&) { + async_close(ep, as::detached); + }, + [&](auto const&) { + BOOST_ASSERT(false); + } + }, + event + ); + } + } + } + } + ); + } + } +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::reset_pingreq_recv_timer( + this_type_sp ep, + std::optional ms +) { + cancel_pingreq_recv_timer(ep); + set_pingreq_recv_timer(ep, ms); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::cancel_pingreq_recv_timer( + this_type_sp ep +) { + ep->tim_pingreq_recv_.cancel(); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::reset_pingresp_recv_timer( + this_type_sp ep, + std::optional ms +) { + if constexpr (Role == role::client || Role == role::any) { + if (ms) { + ep->tim_pingresp_recv_.cancel(); + ep->tim_pingresp_recv_.expires_after( + *ms + ); + + ep->tim_pingresp_recv_.async_wait( + [wp = std::weak_ptr{ep}](error_code const& ec) { + if (!ec) { + if (auto ep = wp.lock()) { + auto events = ep->con_.notify_timer_fired(timer_kind::pingresp_recv); + for (auto it = events.begin(); it != events.end();) { + auto& event = *it++; + std::visit( + overload { + [&](async_mqtt::event::timer const& ev) { + if (ev.get_kind() == timer_kind::pingresp_recv) { + switch (ev.get_op()) { + case timer_op::set: + reset_pingresp_recv_timer(ep, ev.get_ms()); + break; + case timer_op::reset: + reset_pingresp_recv_timer(ep, ev.get_ms()); + break; + case timer_op::cancel: + ep->tim_pingresp_recv_.cancel(); + break; + } + } + else { + BOOST_ASSERT(false); + } + }, + [&](async_mqtt::event::basic_send& ev) { + auto pv{force_move(ev.get())}; + BOOST_ASSERT(pv.template get_if()); + BOOST_ASSERT(it != events.end()); + auto& ev_close = *it++; + BOOST_ASSERT(it == events.end()); + BOOST_ASSERT(std::get_if(&ev_close)); + ep->stream_.async_write_packet( + force_move(pv), + [ep] + ( + error_code const& /*ec*/, + std::size_t /*bytes_transferred*/ + ) { + async_close(ep, as::detached); + } + ); + }, + [&](async_mqtt::event::close const&) { + async_close(ep, as::detached); + }, + [&](auto const&) { + BOOST_ASSERT(false); + } + }, + event + ); + } + } + } + } + ); + } + } +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::notify_retry_one() { + for (auto it = tim_retry_acq_pid_queue_.begin(); + it != tim_retry_acq_pid_queue_.end(); + ++it + ) { + if (it->cancelled) continue; + it->tim->cancel(); + it->cancelled = true; + return; + } +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::complete_retry_one() { + if (!tim_retry_acq_pid_queue_.empty()) { + tim_retry_acq_pid_queue_.pop_front(); + } +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::notify_retry_all() { + tim_retry_acq_pid_queue_.clear(); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +bool +basic_endpoint_impl::has_retry() const { + return !tim_retry_acq_pid_queue_.empty(); +} + +#if 0 // TBD +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::clear_pid_man() { + pid_man_.clear(); + notify_retry_all(); +} +#endif + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl:: +notify_release_pid(typename basic_packet_id_type::type /*pid*/) { + packet_id_released_ = true; + notify_retry_one(); +} + +} // namespace detail + +// member functions + +// public + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +basic_endpoint::~basic_endpoint() { + ASYNC_MQTT_LOG("mqtt_impl", trace) + << ASYNC_MQTT_ADD_VALUE(address, this) + << "destroy"; +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint::underlying_accepted() { + ASYNC_MQTT_LOG("mqtt_api", info) + << ASYNC_MQTT_ADD_VALUE(address, this) + << "underlying_accepted"; + BOOST_ASSERT(impl_); + impl_->underlying_accepted(); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint::set_offline_publish(bool val) { + ASYNC_MQTT_LOG("mqtt_api", info) + << ASYNC_MQTT_ADD_VALUE(address, this) + << "set_offline_publish val:" << val; + BOOST_ASSERT(impl_); + impl_->set_offline_publish(val); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint::set_auto_pub_response(bool val) { + ASYNC_MQTT_LOG("mqtt_api", info) + << ASYNC_MQTT_ADD_VALUE(address, this) + << "set_auto_pub_response val:" << val; + BOOST_ASSERT(impl_); + impl_->set_auto_pub_response(val); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint::set_auto_ping_response(bool val) { + ASYNC_MQTT_LOG("mqtt_api", info) + << ASYNC_MQTT_ADD_VALUE(address, this) + << "set_auto_ping_response val:" << val; + BOOST_ASSERT(impl_); + impl_->set_auto_ping_response(val); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint::set_auto_map_topic_alias_send(bool val) { + ASYNC_MQTT_LOG("mqtt_api", info) + << ASYNC_MQTT_ADD_VALUE(address, this) + << "set_auto_map_topic_alias_send val:" << val; + BOOST_ASSERT(impl_); + impl_->set_auto_map_topic_alias_send(val); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint::set_auto_replace_topic_alias_send(bool val) { + ASYNC_MQTT_LOG("mqtt_api", info) + << ASYNC_MQTT_ADD_VALUE(address, this) + << "set_auto_replace_topic_alias_send val:" << val; + BOOST_ASSERT(impl_); + impl_->set_auto_replace_topic_alias_send(val); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint::set_pingresp_recv_timeout( + std::chrono::milliseconds duration +) { + BOOST_ASSERT(impl_); + impl_->set_pingresp_recv_timeout(duration); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint::set_close_delay_after_disconnect_sent( + std::chrono::milliseconds duration +) { + BOOST_ASSERT(impl_); + impl_->set_close_delay_after_disconnect_sent(duration); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint::set_bulk_write(bool val) { + BOOST_ASSERT(impl_); + impl_->set_bulk_write(val); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint::set_read_buffer_size(std::size_t val) { + BOOST_ASSERT(impl_); + impl_->set_read_buffer_size(val); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +std::set::type> +basic_endpoint::get_qos2_publish_handled_pids() const { + ASYNC_MQTT_LOG("mqtt_api", info) + << ASYNC_MQTT_ADD_VALUE(address, this) + << "get_qos2_publish_handled_pids"; + BOOST_ASSERT(impl_); + return impl_->get_qos2_publish_handled_pids(); +} + + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint::restore_qos2_publish_handled_pids( + std::set::type> pids +) { + ASYNC_MQTT_LOG("mqtt_api", info) + << ASYNC_MQTT_ADD_VALUE(address, this) + << "restore_qos2_publish_handled_pids"; + BOOST_ASSERT(impl_); + impl_->restore_qos2_publish_handled_pids(force_move(pids)); +} + + + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +protocol_version +basic_endpoint::get_protocol_version() const { + auto protocol_version = impl_->get_protocol_version(); + ASYNC_MQTT_LOG("mqtt_api", info) + << ASYNC_MQTT_ADD_VALUE(address, this) + << "get_protocol_version:" << protocol_version; + BOOST_ASSERT(impl_); + return protocol_version; +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +bool +basic_endpoint::is_publish_processing(typename basic_packet_id_type::type pid) const { + ASYNC_MQTT_LOG("mqtt_api", info) + << ASYNC_MQTT_ADD_VALUE(address, this) + << "is_publish_processing:" << pid; + BOOST_ASSERT(impl_); + return impl_->is_publish_processing(pid); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint::set_pingreq_send_interval( + std::chrono::milliseconds duration +) { + ASYNC_MQTT_LOG("mqtt_api", info) + << ASYNC_MQTT_ADD_VALUE(address, this) + << "set_pingreq_send_interval"; + BOOST_ASSERT(impl_); + impl_type::set_pingreq_send_interval( + impl_, + duration + ); +} + +} // namespace async_mqtt + +#include + +#endif // ASYNC_MQTT_IMPL_ENDPOINT_IMPL_IPP diff --git a/include/async_mqtt/impl/endpoint_recv.hpp b/include/async_mqtt/impl/endpoint_recv.hpp index aebb8b3a0..9c41cf95e 100644 --- a/include/async_mqtt/impl/endpoint_recv.hpp +++ b/include/async_mqtt/impl/endpoint_recv.hpp @@ -8,678 +8,10 @@ #define ASYNC_MQTT_IMPL_ENDPOINT_RECV_HPP #include - -#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include -#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include namespace async_mqtt { -namespace detail { - -template -struct basic_endpoint_impl:: -recv_op { - this_type_sp ep; - std::optional fil = std::nullopt; - std::set types = {}; - std::optional decided_error = std::nullopt; - enum { initiate, disconnect, close, read } state = initiate; - - template - void operator()( - Self& self, - error_code ec = error_code{}, - buffer buf = buffer{} - ) { - auto& a_ep{*ep}; - if (ec) { - ASYNC_MQTT_LOG("mqtt_impl", info) - << ASYNC_MQTT_ADD_VALUE(address, &a_ep) - << "recv error:" << ec.message(); - if (ec == as::error::operation_aborted) { - // on cancel, not close the connection - self.complete( - ec, - packet_variant_type{} - ); - } - else { - decided_error.emplace(ec); - state = close; - auto ep_copy = ep; - a_ep.async_close( - force_move(ep_copy), - force_move(self) - ); - } - return; - } - - switch (state) { - case initiate: { - state = read; - a_ep.stream_.async_read_packet( - force_move(self) - ); - } break; - case read: { - if (buf.size() > a_ep.maximum_packet_size_recv_) { - // on v3.1.1 maximum_packet_size_recv_ is initialized as packet_size_no_limit - BOOST_ASSERT(a_ep.protocol_version_ == protocol_version::v5); - state = disconnect; - decided_error.emplace( - make_error_code( - disconnect_reason_code::packet_too_large - ) - ); - auto ep_copy = ep; - a_ep.async_send( - force_move(ep_copy), - v5::disconnect_packet{ - disconnect_reason_code::packet_too_large - }, - force_move(self) - ); - return; - } - - bool call_complete = true; - error_code ec = error_code{}; - auto v = buffer_to_basic_packet_variant(buf, a_ep.protocol_version_, ec); - auto ep_copy = ep; - if (ec) { - decided_error.emplace(ec); - if (a_ep.protocol_version_ == protocol_version::v5) { - state = disconnect; - if constexpr (can_send_as_server(Role)) { - if (ec.category() == get_connect_reason_code_category()) { - a_ep.status_ = connection_status::connecting; - auto ep_copy = ep; - async_send( - force_move(ep_copy), - v5::connack_packet{ - false, - static_cast(ec.value()) - }, - force_move(self) - ); - } - return; - } - if (ec.category() == get_disconnect_reason_code_category()) { - state = disconnect; - if (a_ep.status_ == connection_status::connected) { - auto ep_copy = ep; - a_ep.async_send( - force_move(ep_copy), - v5::disconnect_packet{ - static_cast(ec.value()) - }, - force_move(self) - ); - return; - } - } - } - state = close; - auto ep_copy = ep; - a_ep.async_close( - force_move(ep_copy), - force_move(self) - ); - return; - } - else { - ASYNC_MQTT_LOG("mqtt_impl", trace) - << ASYNC_MQTT_ADD_VALUE(address, &a_ep) - << "recv:" << v; - v.visit( - // do internal protocol processing - overload { - [&](v3_1_1::connect_packet& p) { - handle_v3_1_1_connect(p); - }, - [&](v5::connect_packet& p) { - handle_v5_connect(p); - }, - [&](v3_1_1::connack_packet& p) { - handle_v3_1_1_connack(p); - }, - [&](v5::connack_packet& p) { - handle_v5_connack(p); - }, - [&](v3_1_1::basic_publish_packet& p) { - switch (p.opts().get_qos()) { - case qos::at_least_once: { - if (a_ep.auto_pub_response_ && - a_ep.status_ == connection_status::connected) { - a_ep.async_send( - ep, - v3_1_1::basic_puback_packet(p.packet_id()), - as::detached - ); - } - } break; - case qos::exactly_once: { - call_complete = process_qos2_publish(protocol_version::v3_1_1, p.packet_id()); - if (!call_complete) { - // do the next read - a_ep.stream_.async_read_packet( - force_move(self) - ); - } - } break; - default: - break; - } - }, - [&](v5::basic_publish_packet& p) { - switch (p.opts().get_qos()) { - case qos::at_least_once: { - if (a_ep.publish_recv_.size() == a_ep.publish_recv_max_) { - state = disconnect; - decided_error.emplace( - make_error_code( - disconnect_reason_code::receive_maximum_exceeded - ) - ); - auto ep_copy = ep; - a_ep.async_send( - force_move(ep_copy), - v5::disconnect_packet{ - disconnect_reason_code::receive_maximum_exceeded - }, - force_move(self) - ); - return; - } - auto packet_id = p.packet_id(); - a_ep.publish_recv_.insert(packet_id); - if (a_ep.auto_pub_response_ && a_ep.status_ == connection_status::connected) { - a_ep.async_send( - ep, - v5::basic_puback_packet{packet_id}, - as::detached - ); - } - } break; - case qos::exactly_once: { - if (a_ep.publish_recv_.size() == a_ep.publish_recv_max_) { - state = disconnect; - decided_error.emplace( - make_error_code( - disconnect_reason_code::receive_maximum_exceeded - ) - ); - auto ep_copy = ep; - a_ep.async_send( - force_move(ep_copy), - v5::disconnect_packet{ - disconnect_reason_code::receive_maximum_exceeded - }, - force_move(self) - ); - return; - } - auto packet_id = p.packet_id(); - a_ep.publish_recv_.insert(packet_id); - call_complete = process_qos2_publish(protocol_version::v5, packet_id); - if (!call_complete) { - // do the next read - a_ep.stream_.async_read_packet( - force_move(self) - ); - } - } break; - default: - break; - } - - if (p.topic().empty()) { - if (auto ta_opt = get_topic_alias(p.props())) { - // extract topic from topic_alias - if (*ta_opt == 0 || - !a_ep.topic_alias_recv_ || // topic_alias_maximum is 0 - *ta_opt > a_ep.topic_alias_recv_->max()) { - state = disconnect; - decided_error.emplace( - make_error_code( - disconnect_reason_code::topic_alias_invalid - ) - ); - auto ep_copy = ep; - a_ep.async_send( - force_move(ep_copy), - v5::disconnect_packet{ - disconnect_reason_code::topic_alias_invalid - }, - force_move(self) - ); - return; - } - else { - BOOST_ASSERT(a_ep.topic_alias_recv_); - auto topic = a_ep.topic_alias_recv_->find(*ta_opt); - if (topic.empty()) { - ASYNC_MQTT_LOG("mqtt_impl", error) - << ASYNC_MQTT_ADD_VALUE(address, &a_ep) - << "no matching topic alias: " - << *ta_opt; - state = disconnect; - decided_error.emplace( - make_error_code( - disconnect_reason_code::topic_alias_invalid - ) - ); - auto ep_copy = ep; - a_ep.async_send( - force_move(ep_copy), - v5::disconnect_packet{ - disconnect_reason_code::topic_alias_invalid - }, - force_move(self) - ); - return; - } - else { - p.add_topic(force_move(topic)); - } - } - } - else { - ASYNC_MQTT_LOG("mqtt_impl", error) - << ASYNC_MQTT_ADD_VALUE(address, &a_ep) - << "topic is empty but topic_alias isn't set"; - state = disconnect; - decided_error.emplace( - make_error_code( - disconnect_reason_code::topic_alias_invalid - ) - ); - auto ep_copy = ep; - a_ep.async_send( - force_move(ep_copy), - v5::disconnect_packet{ - disconnect_reason_code::topic_alias_invalid - }, - force_move(self) - ); - return; - } - } - else { - if (auto ta_opt = get_topic_alias(p.props())) { - if (*ta_opt == 0 || - !a_ep.topic_alias_recv_ || // topic_alias_maximum is 0 - *ta_opt > a_ep.topic_alias_recv_->max()) { - state = disconnect; - decided_error.emplace( - make_error_code( - disconnect_reason_code::topic_alias_invalid - ) - ); - auto ep_copy = ep; - a_ep.async_send( - force_move(ep_copy), - v5::disconnect_packet{ - disconnect_reason_code::topic_alias_invalid - }, - force_move(self) - ); - return; - } - else { - BOOST_ASSERT(a_ep.topic_alias_recv_); - // extract topic from topic_alias - a_ep.topic_alias_recv_->insert_or_update(p.topic(), *ta_opt); - } - } - } - }, - [&](v3_1_1::basic_puback_packet& p) { - auto packet_id = p.packet_id(); - if (a_ep.pid_puback_.erase(packet_id)) { - a_ep.store_.erase(response_packet::v3_1_1_puback, packet_id); - a_ep.release_pid(packet_id); - } - else { - ASYNC_MQTT_LOG("mqtt_impl", info) - << ASYNC_MQTT_ADD_VALUE(address, &a_ep) - << "invalid packet_id puback received packet_id:" << packet_id; - state = disconnect; - decided_error.emplace( - make_error_code( - disconnect_reason_code::protocol_error - ) - ); - as::dispatch( - a_ep.get_executor(), - force_move(self) - ); - return; - } - }, - [&](v5::basic_puback_packet& p) { - auto packet_id = p.packet_id(); - if (a_ep.pid_puback_.erase(packet_id)) { - a_ep.store_.erase(response_packet::v5_puback, packet_id); - a_ep.release_pid(packet_id); - --a_ep.publish_send_count_; - send_publish_from_queue(); - } - else { - ASYNC_MQTT_LOG("mqtt_impl", info) - << ASYNC_MQTT_ADD_VALUE(address, &a_ep) - << "invalid packet_id puback received packet_id:" << packet_id; - state = disconnect; - decided_error.emplace( - make_error_code( - disconnect_reason_code::protocol_error - ) - ); - auto ep_copy = ep; - a_ep.async_send( - force_move(ep_copy), - v5::disconnect_packet{ - disconnect_reason_code::protocol_error - }, - force_move(self) - ); - return; - } - }, - [&](v3_1_1::basic_pubrec_packet& p) { - auto packet_id = p.packet_id(); - if (a_ep.pid_pubrec_.erase(packet_id)) { - a_ep.store_.erase(response_packet::v3_1_1_pubrec, packet_id); - if (a_ep.auto_pub_response_ && a_ep.status_ == connection_status::connected) { - a_ep.async_send( - ep, - v3_1_1::basic_pubrel_packet(packet_id), - as::detached - ); - } - } - else { - ASYNC_MQTT_LOG("mqtt_impl", info) - << ASYNC_MQTT_ADD_VALUE(address, &a_ep) - << "invalid packet_id pubrec received packet_id:" << packet_id; - state = disconnect; - decided_error.emplace( - make_error_code( - disconnect_reason_code::protocol_error - ) - ); - as::dispatch( - a_ep.get_executor(), - force_move(self) - ); - return; - } - }, - [&](v5::basic_pubrec_packet& p) { - auto packet_id = p.packet_id(); - if (a_ep.pid_pubrec_.erase(packet_id)) { - a_ep.store_.erase(response_packet::v5_pubrec, packet_id); - if (make_error_code(p.code())) { - a_ep.release_pid(packet_id); - a_ep.qos2_publish_processing_.erase(packet_id); - --a_ep.publish_send_count_; - send_publish_from_queue(); - } - else if (a_ep.auto_pub_response_ && a_ep.status_ == connection_status::connected) { - a_ep.async_send( - ep, - v5::basic_pubrel_packet(packet_id), - as::detached - ); - } - } - else { - ASYNC_MQTT_LOG("mqtt_impl", info) - << ASYNC_MQTT_ADD_VALUE(address, &a_ep) - << "invalid packet_id pubrec received packet_id:" << packet_id; - state = disconnect; - decided_error.emplace( - make_error_code( - disconnect_reason_code::protocol_error - ) - ); - auto ep_copy = ep; - a_ep.async_send( - force_move(ep_copy), - v5::disconnect_packet{ - disconnect_reason_code::protocol_error - }, - force_move(self) - ); - return; - } - }, - [&](v3_1_1::basic_pubrel_packet& p) { - auto packet_id = p.packet_id(); - a_ep.qos2_publish_handled_.erase(packet_id); - if (a_ep.auto_pub_response_ && a_ep.status_ == connection_status::connected) { - a_ep.async_send( - ep, - v3_1_1::basic_pubcomp_packet(packet_id), - as::detached - ); - } - }, - [&](v5::basic_pubrel_packet& p) { - auto packet_id = p.packet_id(); - a_ep.qos2_publish_handled_.erase(packet_id); - if (a_ep.auto_pub_response_ && a_ep.status_ == connection_status::connected) { - a_ep.async_send( - ep, - v5::basic_pubcomp_packet(packet_id), - as::detached - ); - } - }, - [&](v3_1_1::basic_pubcomp_packet& p) { - auto packet_id = p.packet_id(); - if (a_ep.pid_pubcomp_.erase(packet_id)) { - a_ep.store_.erase(response_packet::v3_1_1_pubcomp, packet_id); - a_ep.release_pid(packet_id); - a_ep.qos2_publish_processing_.erase(packet_id); - } - else { - ASYNC_MQTT_LOG("mqtt_impl", info) - << ASYNC_MQTT_ADD_VALUE(address, &a_ep) - << "invalid packet_id pubcomp received packet_id:" << packet_id; - state = disconnect; - decided_error.emplace( - make_error_code( - disconnect_reason_code::protocol_error - ) - ); - as::dispatch( - a_ep.get_executor(), - force_move(self) - ); - return; - } - }, - [&](v5::basic_pubcomp_packet& p) { - auto packet_id = p.packet_id(); - if (a_ep.pid_pubcomp_.erase(packet_id)) { - a_ep.store_.erase(response_packet::v5_pubcomp, packet_id); - a_ep.release_pid(packet_id); - a_ep.qos2_publish_processing_.erase(packet_id); - --a_ep.publish_send_count_; - send_publish_from_queue(); - } - else { - ASYNC_MQTT_LOG("mqtt_impl", info) - << ASYNC_MQTT_ADD_VALUE(address, &a_ep) - << "invalid packet_id pubcomp received packet_id:" << packet_id; - state = disconnect; - decided_error.emplace( - make_error_code( - disconnect_reason_code::protocol_error - ) - ); - auto ep_copy = ep; - a_ep.async_send( - force_move(ep_copy), - v5::disconnect_packet{ - disconnect_reason_code::protocol_error - }, - force_move(self) - ); - return; - } - }, - [&](v3_1_1::basic_subscribe_packet&) { - }, - [&](v5::basic_subscribe_packet&) { - }, - [&](v3_1_1::basic_suback_packet& p) { - auto packet_id = p.packet_id(); - if (a_ep.pid_suback_.erase(packet_id)) { - a_ep.release_pid(packet_id); - } - }, - [&](v5::basic_suback_packet& p) { - auto packet_id = p.packet_id(); - if (a_ep.pid_suback_.erase(packet_id)) { - a_ep.release_pid(packet_id); - } - }, - [&](v3_1_1::basic_unsubscribe_packet&) { - }, - [&](v5::basic_unsubscribe_packet&) { - }, - [&](v3_1_1::basic_unsuback_packet& p) { - auto packet_id = p.packet_id(); - if (a_ep.pid_unsuback_.erase(packet_id)) { - a_ep.release_pid(packet_id); - } - }, - [&](v5::basic_unsuback_packet& p) { - auto packet_id = p.packet_id(); - if (a_ep.pid_unsuback_.erase(packet_id)) { - a_ep.release_pid(packet_id); - } - }, - [&](v3_1_1::pingreq_packet&) { - if constexpr(can_send_as_server(Role)) { - if (a_ep.auto_ping_response_ && - a_ep.status_ == connection_status::connected) { - a_ep.async_send( - ep, - v3_1_1::pingresp_packet(), - as::detached - ); - } - } - }, - [&](v5::pingreq_packet&) { - if constexpr(can_send_as_server(Role)) { - if (a_ep.auto_ping_response_ && - a_ep.status_ == connection_status::connected) { - a_ep.async_send( - ep, - v5::pingresp_packet(), - as::detached - ); - } - } - }, - [&](v3_1_1::pingresp_packet&) { - a_ep.tim_pingresp_recv_.cancel(); - }, - [&](v5::pingresp_packet&) { - a_ep.tim_pingresp_recv_.cancel(); - }, - [&](v3_1_1::disconnect_packet&) { - a_ep.status_ = connection_status::disconnecting; - }, - [&](v5::disconnect_packet&) { - a_ep.status_ = connection_status::disconnecting; - }, - [&](v5::auth_packet&) { - }, - [&](std::monostate&) { - } - } - ); - } - reset_pingreq_recv_timer(force_move(ep_copy)); - - auto try_to_comp = - [&] { - if (call_complete && !decided_error) { - self.complete( - error_code{}, - force_move(v) - ); - } - }; - - if (fil) { - if (auto type_opt = v.type()) { - if ((*fil == filter::match && types.find(*type_opt) == types.end()) || - (*fil == filter::except && types.find(*type_opt) != types.end()) - ) { - // read the next packet - state = initiate; - as::dispatch( - a_ep.get_executor(), - force_move(self) - ); - } - else { - try_to_comp(); - } - } - else { - try_to_comp(); - } - } - else { - try_to_comp(); - } - } break; - case disconnect: { - state = close; - auto ep_copy = ep; - a_ep.async_close( - force_move(ep_copy), - force_move(self) - ); - } break; - case close: { - BOOST_ASSERT(decided_error); - ASYNC_MQTT_LOG("mqtt_impl", info) - << ASYNC_MQTT_ADD_VALUE(address, &a_ep) - << "recv code triggers close:" << decided_error->message(); - self.complete(force_move(*decided_error), packet_variant_type{}); - } break; - default: - BOOST_ASSERT(false); - break; - } - } - - void send_publish_from_queue(); - - bool process_qos2_publish( - protocol_version ver, - typename basic_packet_id_type::type packet_id - ); - - void handle_v3_1_1_connect(v3_1_1::connect_packet& p); - void handle_v5_connect(v5::connect_packet& p); - void handle_v3_1_1_connack(v3_1_1::connack_packet& p); - void handle_v5_connack(v5::connack_packet& p); -}; - -} // namespace detail - template template auto @@ -691,15 +23,23 @@ basic_endpoint::async_recv( << "recv"; BOOST_ASSERT(impl_); return - as::async_compose< + as::async_initiate< CompletionToken, - void(error_code, packet_variant_type) + void(error_code, std::optional) >( - typename impl_type::recv_op{ - impl_ + []( + auto handler, + std::shared_ptr impl + ) { + impl_type::async_recv( + force_move(impl), + std::nullopt, + std::set{}, + force_move(handler) + ); }, token, - get_executor() + impl_ ); } @@ -715,17 +55,25 @@ basic_endpoint::async_recv( << "recv"; BOOST_ASSERT(impl_); return - as::async_compose< + as::async_initiate< CompletionToken, - void(error_code, packet_variant_type) + void(error_code, std::optional) >( - typename impl_type::recv_op{ - impl_, - filter::match, - force_move(types) + []( + auto handler, + std::shared_ptr impl, + std::set types + ) { + impl_type::async_recv( + force_move(impl), + filter::match, + force_move(types), + force_move(handler) + ); }, token, - get_executor() + impl_, + force_move(types) ); } @@ -742,17 +90,27 @@ basic_endpoint::async_recv( << "recv"; BOOST_ASSERT(impl_); return - as::async_compose< + as::async_initiate< CompletionToken, - void(error_code, packet_variant_type) + void(error_code, std::optional) >( - typename impl_type::recv_op{ - impl_, - fil, - force_move(types) + []( + auto handler, + std::shared_ptr impl, + filter fil, + std::set types + ) { + impl_type::async_recv( + force_move(impl), + fil, + force_move(types), + force_move(handler) + ); }, token, - get_executor() + impl_, + fil, + force_move(types) ); } diff --git a/include/async_mqtt/impl/endpoint_recv.ipp b/include/async_mqtt/impl/endpoint_recv.ipp index a09a01ce3..a78c354d7 100644 --- a/include/async_mqtt/impl/endpoint_recv.ipp +++ b/include/async_mqtt/impl/endpoint_recv.ipp @@ -7,272 +7,328 @@ #if !defined(ASYNC_MQTT_IMPL_ENDPOINT_RECV_IPP) #define ASYNC_MQTT_IMPL_ENDPOINT_RECV_IPP -#include +#include +#include #include namespace async_mqtt::detail { template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl:: -recv_op:: -send_publish_from_queue() { - if (ep->status_ != connection_status::connected) return; - while (!ep->publish_queue_.empty() && - ep->publish_send_count_ != ep->publish_send_max_) { - async_send( - ep, - force_move(ep->publish_queue_.front()), - true, // from queue - as::detached +struct basic_endpoint_impl:: +recv_op { + this_type_sp ep; + std::optional fil = std::nullopt; + std::set types = {}; + std::optional decided_error = std::nullopt; + std::optional> recv_packet = std::nullopt; + bool try_resend_from_queue = false; + enum { dispatch, prev, read, protocol_read, sent, complete } state = dispatch; + + template + bool process_one_event( + Self& self + ) { + auto& a_ep{*ep}; + auto event{force_move(a_ep.recv_events_.front())}; + a_ep.recv_events_.pop_front(); + return std::visit( + overload{ + [&](error_code ec) { + decided_error.emplace(ec); + return true; + }, + [&](async_mqtt::event::basic_send& ev) { + state = sent; + auto ep_copy{ep}; + async_send( + force_move(ep_copy), + force_move(ev.get()), + force_move(self) + ); + BOOST_ASSERT(!ev.get_release_packet_id_if_send_error()); + return false; + }, + [&](async_mqtt::event::basic_packet_id_released ev) { + a_ep.notify_release_pid(ev.get()); + try_resend_from_queue = true; + return true; + }, + [&](async_mqtt::event::basic_packet_received ev) { + if (recv_packet) { + // rest events would be processed the next async_recv call + // back the event to the recv_events_ for the next async_recv + a_ep.recv_events_.push_front(force_move(event)); + state = complete; + as::post( + a_ep.get_executor(), + force_move(self) + ); + return false; + } + else { + recv_packet.emplace(force_move(ev.get())); + } + return true; + }, + [&](async_mqtt::event::timer ev) { + switch (ev.get_kind()) { + case timer_kind::pingreq_send: + // receive server keep alive property in connack + if (ev.get_op() == timer_op::reset) { + reset_pingreq_send_timer(ep, ev.get_ms()); + } + else { + BOOST_ASSERT(false); + } + break; + case timer_kind::pingreq_recv: + switch (ev.get_op()) { + case timer_op::set: + set_pingreq_recv_timer(ep, ev.get_ms()); + break; + case timer_op::reset: + reset_pingreq_recv_timer(ep, ev.get_ms()); + break; + case timer_op::cancel: + cancel_pingreq_recv_timer(ep); + break; + } + break; + case timer_kind::pingresp_recv: + if (ev.get_op() == timer_op::cancel) { + reset_pingresp_recv_timer(ep, ev.get_ms()); + } + else { + BOOST_ASSERT(false); + } + break; + default: + BOOST_ASSERT(false); + break; + } + return true; + }, + [&](async_mqtt::event::close) { + state = complete; + auto ep_copy{ep}; + async_close( + force_move(ep_copy), + force_move(self) + ); + return false; + }, + [&](auto const&) { + BOOST_ASSERT(false); + return false; + } + }, + event ); - ep->publish_queue_.pop_front(); } -} -template -ASYNC_MQTT_HEADER_ONLY_INLINE -bool -basic_endpoint_impl:: -recv_op:: -process_qos2_publish( - protocol_version ver, - typename basic_packet_id_type::type packet_id -) { - bool already_handled = false; - if (ep->qos2_publish_handled_.find(packet_id) == ep->qos2_publish_handled_.end()) { - ep->qos2_publish_handled_.emplace(packet_id); - } - else { - already_handled = true; - } - if (ep->status_ == connection_status::connected && - (ep->auto_pub_response_ || - already_handled) // already_handled is true only if the pubrec packet - ) { // corresponding to the publish packet has already - // been sent as success - switch (ver) { - case protocol_version::v3_1_1: - async_send( - ep, - v3_1_1::basic_pubrec_packet(packet_id), - as::detached - ); - break; - case protocol_version::v5: - ep->async_send( - ep, - v5::basic_pubrec_packet(packet_id), - as::detached - ); - break; - default: - BOOST_ASSERT(false); - break; + template + void operator()( + Self& self, + error_code ec = error_code{}, + std::size_t bytes_transferred = 0 + ) { + auto& a_ep{*ep}; + if (ec) { + ASYNC_MQTT_LOG("mqtt_impl", info) + << ASYNC_MQTT_ADD_VALUE(address, &a_ep) + << "recv error:" << ec.message(); + if (ec == as::error::operation_aborted) { + // on cancel, not close the connection + self.complete( + ec, + force_move(recv_packet) + ); + } + else { + state = complete; + decided_error.emplace(ec); + auto ep_copy = ep; + a_ep.async_close( + force_move(ep_copy), + force_move(self) + ); + } + return; } - } - if (already_handled) { - return false; - } - return true; -} -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl:: -recv_op:: -handle_v3_1_1_connect(v3_1_1::connect_packet& p) { - ep->initialize(); - ep->protocol_version_ = protocol_version::v3_1_1; - ep->status_ = connection_status::connecting; - auto keep_alive = p.keep_alive(); - if (keep_alive != 0) { - ep->pingreq_recv_timeout_ms_.emplace( - std::chrono::milliseconds{ - keep_alive * 1000 * 3 / 2 + switch (state) { + case dispatch: { + state = prev; + as::dispatch( + a_ep.get_executor(), + force_move(self) + ); + } break; + case prev: { + while (!a_ep.recv_events_.empty()) { + if (!process_one_event(self)) return; } - ); - } - if (p.clean_session()) { - ep->need_store_ = false; - } - else { - ep->need_store_ = true; - } -} - -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl:: -recv_op:: -handle_v5_connect(v5::connect_packet& p) { - ep->initialize(); - ep->protocol_version_ = protocol_version::v5; - ep->status_ = connection_status::connecting; - auto keep_alive = p.keep_alive(); - if (keep_alive != 0) { - ep->pingreq_recv_timeout_ms_.emplace( - std::chrono::milliseconds{ - keep_alive * 1000 * 3 / 2 + // all previous events processed + // and receive event is included in them + if (recv_packet) { + state = complete; + as::post( + a_ep.get_executor(), + force_move(self) + ); } - ); - } - for (auto const& prop : p.props()) { - prop.visit( - overload { - [&](property::topic_alias_maximum const& p) { - if (p.val() > 0) { - ep->topic_alias_send_.emplace(p.val()); - } - }, - [&](property::receive_maximum const& p) { - BOOST_ASSERT(p.val() != 0); - ep->publish_send_max_ = p.val(); - }, - [&](property::maximum_packet_size const& p) { - BOOST_ASSERT(p.val() != 0); - ep->maximum_packet_size_send_ = p.val(); - }, - [&](property::session_expiry_interval const& p) { - if (p.val() != 0) { - ep->need_store_ = true; + else { + state = read; + as::dispatch( + a_ep.get_executor(), + force_move(self) + ); + } + } break; + case read: { + state = protocol_read; + a_ep.stream_.async_read_some( + a_ep.read_buf_.prepare(a_ep.read_buffer_size_), + force_move(self) + ); + } break; + case protocol_read: { + a_ep.read_buf_.commit(bytes_transferred); + std::istream is{&a_ep.read_buf_}; + auto events{a_ep.con_.recv(is)}; + std::move(events.begin(), events.end(), std::back_inserter(a_ep.recv_events_)); + if (a_ep.recv_events_.empty()) { + // required more bytes + state = read; + as::dispatch( + a_ep.get_executor(), + force_move(self) + ); + } + else { + while (!a_ep.recv_events_.empty()) { + if (!process_one_event(self)) return; + } + state = complete; // all events processed + as::post( + a_ep.get_executor(), + force_move(self) + ); + } + } break; + case sent: { + while (!a_ep.recv_events_.empty()) { + if (!process_one_event(self)) return; + } + // all events processed + if (recv_packet || decided_error) { + state = complete; + as::post( + a_ep.get_executor(), + force_move(self) + ); + } + else { + // auto response send but no received packet + // (PUBLISH QoS2 received again after PUBREC sent) + state = read; + as::dispatch( + a_ep.get_executor(), + force_move(self) + ); + } + } break; + case complete: { + if (decided_error) { + self.complete( + *decided_error, + std::nullopt + ); + } + else { + BOOST_ASSERT(recv_packet); + if (fil) { + auto type = recv_packet->type(); + if ((*fil == filter::match && types.find(type) == types.end()) || + (*fil == filter::except && types.find(type) != types.end()) + ) { + // read the next packet + state = prev; + recv_packet.reset(); + as::dispatch( + a_ep.get_executor(), + force_move(self) + ); + return; } - }, - [](auto const&) { } + if (try_resend_from_queue) { + send_publish_from_queue(); + } + self.complete( + error_code{}, + force_move(recv_packet) + ); } - ); + } break; + default: + BOOST_ASSERT(false); + break; + } } -} -template -ASYNC_MQTT_HEADER_ONLY_INLINE -void -basic_endpoint_impl:: -recv_op:: -handle_v3_1_1_connack(v3_1_1::connack_packet& p) { - if (p.code() == connect_return_code::accepted) { - ep->status_ = connection_status::connected; - if (p.session_present()) { - send_stored(ep); - } - else { - ep->clear_pid_man(); - ep->store_.clear(); + void send_publish_from_queue() { + if (ep->status_ != close_status::open) return; + auto vacancy_opt = ep->con_.get_receive_maximum_vacancy_for_send(); + while ( + !ep->publish_queue_.empty() && // has elements + ( + !vacancy_opt || // no limit + *vacancy_opt != 0 // has vacancy + ) + ) { + async_send( + ep, + force_move(ep->publish_queue_.front()), + true, // from queue + as::detached + ); + ep->publish_queue_.pop_front(); } } -} +}; template ASYNC_MQTT_HEADER_ONLY_INLINE void basic_endpoint_impl:: -recv_op:: -handle_v5_connack(v5::connack_packet& p) { - if (p.code() == connect_reason_code::success) { - ep->status_ = connection_status::connected; - for (auto const& prop : p.props()) { - prop.visit( - overload { - [&](property::topic_alias_maximum const& p) { - if (p.val() > 0) { - ep->topic_alias_send_.emplace(p.val()); - } - }, - [&](property::receive_maximum const& p) { - BOOST_ASSERT(p.val() != 0); - ep->publish_send_max_ = p.val(); - }, - [&](property::maximum_packet_size const& p) { - BOOST_ASSERT(p.val() != 0); - ep->maximum_packet_size_send_ = p.val(); - }, - [&](property::server_keep_alive const& p) { - if constexpr (can_send_as_client(Role)) { - set_pingreq_send_interval( - ep, - std::chrono::seconds{ - p.val() - } - ); - } - }, - [](auto const&) { - } - } - ); - } - - if (p.session_present()) { - send_stored(ep); - } - else { - ep->clear_pid_man(); - ep->store_.clear(); - } - } +async_recv( + this_type_sp impl, + std::optional fil, + std::set types, + as::any_completion_handler< + void(error_code, std::optional) + > handler +) { + auto exe = impl->get_executor(); + as::async_compose< + as::any_completion_handler< + void(error_code, std::optional) + >, + void(error_code, std::optional) + >( + recv_op{ + force_move(impl), + fil, + force_move(types) + }, + handler, + exe + ); } } // namespace async_mqtt::detail -#if defined(ASYNC_MQTT_SEPARATE_COMPILATION) - -#include - -#define ASYNC_MQTT_INSTANTIATE_EACH(a_role, a_size, a_protocol) \ -namespace async_mqtt::detail { \ -\ -template \ -void \ -basic_endpoint_impl::recv_op:: \ -send_publish_from_queue(); \ -\ -template \ -bool \ -basic_endpoint_impl::recv_op:: \ -process_qos2_publish( \ - protocol_version, \ - typename basic_packet_id_type::type \ -); \ -\ -template \ -void \ -basic_endpoint_impl::recv_op:: \ -handle_v3_1_1_connect(v3_1_1::connect_packet&); \ -\ -template \ -void \ -basic_endpoint_impl::recv_op:: \ -handle_v3_1_1_connack(v3_1_1::connack_packet&); \ -\ -template \ -void \ -basic_endpoint_impl::recv_op:: \ -handle_v5_connect(v5::connect_packet&); \ -\ -template \ -void \ -basic_endpoint_impl::recv_op:: \ -handle_v5_connack(v5::connack_packet&); \ -\ -} // namespace async_mqtt::detail - -#define ASYNC_MQTT_PP_GENERATE(r, product) \ - BOOST_PP_EXPAND( \ - ASYNC_MQTT_INSTANTIATE_EACH \ - BOOST_PP_SEQ_TO_TUPLE( \ - product \ - ) \ - ) - -BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_ROLE)(ASYNC_MQTT_PP_SIZE)(ASYNC_MQTT_PP_PROTOCOL)) - -#undef ASYNC_MQTT_PP_GENERATE -#undef ASYNC_MQTT_INSTANTIATE_EACH - -#endif // defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include #endif // ASYNC_MQTT_IMPL_ENDPOINT_RECV_IPP diff --git a/include/async_mqtt/impl/endpoint_register_packet_id.hpp b/include/async_mqtt/impl/endpoint_register_packet_id.hpp index 963ee911f..34f93ec8a 100644 --- a/include/async_mqtt/impl/endpoint_register_packet_id.hpp +++ b/include/async_mqtt/impl/endpoint_register_packet_id.hpp @@ -8,59 +8,10 @@ #define ASYNC_MQTT_IMPL_ENDPOINT_REGISTER_PACKET_ID_HPP #include +#include namespace async_mqtt { -namespace detail { - -template -struct basic_endpoint_impl:: -register_packet_id_op { - this_type_sp ep; - typename basic_packet_id_type::type packet_id; - enum { dispatch, complete } state = dispatch; - - template - void operator()( - Self& self - ) { - auto& a_ep{*ep}; - switch (state) { - case dispatch: { - state = complete; - as::dispatch( - a_ep.get_executor(), - force_move(self) - ); - } break; - case complete: - if (a_ep.pid_man_.register_id(packet_id)) { - self.complete(error_code{}); - } - else { - self.complete( - make_error_code( - mqtt_error::packet_identifier_conflict - ) - ); - } - break; - } - } -}; - -// sync version - -template -inline -bool -basic_endpoint_impl:: -register_packet_id(typename basic_packet_id_type::type packet_id) { - return pid_man_.register_id(packet_id); -} - -} // namespace detail - template template auto @@ -73,16 +24,24 @@ basic_endpoint::async_register_packet_id( << "register_packet_id pid:" << packet_id; BOOST_ASSERT(impl_); return - as::async_compose< + as::async_initiate< CompletionToken, void(error_code) >( - typename impl_type::register_packet_id_op{ - impl_, - packet_id + []( + auto handler, + std::shared_ptr impl, + typename basic_packet_id_type::type packet_id + ) { + impl_type::async_register_packet_id( + force_move(impl), + packet_id, + force_move(handler) + ); }, token, - get_executor() + impl_, + packet_id ); } @@ -103,4 +62,8 @@ register_packet_id(typename basic_packet_id_type::type packet_id) } // namespace async_mqtt +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + #endif // ASYNC_MQTT_IMPL_ENDPOINT_REGISTER_PACKET_ID_HPP diff --git a/include/async_mqtt/impl/endpoint_register_packet_id.ipp b/include/async_mqtt/impl/endpoint_register_packet_id.ipp new file mode 100644 index 000000000..db182e1ec --- /dev/null +++ b/include/async_mqtt/impl/endpoint_register_packet_id.ipp @@ -0,0 +1,93 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_ENDPOINT_REGISTER_PACKET_ID_IPP) +#define ASYNC_MQTT_IMPL_ENDPOINT_REGISTER_PACKET_ID_IPP + +#include +#include +#include + +namespace async_mqtt::detail { + +template +struct basic_endpoint_impl:: +register_packet_id_op { + this_type_sp ep; + typename basic_packet_id_type::type packet_id; + enum { dispatch, complete } state = dispatch; + + template + void operator()( + Self& self + ) { + auto& a_ep{*ep}; + switch (state) { + case dispatch: { + state = complete; + as::dispatch( + a_ep.get_executor(), + force_move(self) + ); + } break; + case complete: + if (a_ep.con_.register_packet_id(packet_id)) { + self.complete(error_code{}); + } + else { + self.complete( + make_error_code( + mqtt_error::packet_identifier_conflict + ) + ); + } + break; + } + } +}; + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl:: +async_register_packet_id( + this_type_sp impl, + typename basic_packet_id_type::type packet_id, + as::any_completion_handler< + void(error_code) + > handler +) { + auto exe = impl->get_executor(); + as::async_compose< + as::any_completion_handler< + void(error_code) + >, + void(error_code) + >( + register_packet_id_op{ + force_move(impl), + packet_id + }, + handler, + exe + ); +} + +// sync version + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +bool +basic_endpoint_impl:: +register_packet_id(typename basic_packet_id_type::type packet_id) { + return con_.register_packet_id(packet_id); +} + +} // namespace async_mqtt::detail + +#include + +#endif // ASYNC_MQTT_IMPL_ENDPOINT_REGISTER_PACKET_ID_IPP diff --git a/include/async_mqtt/impl/endpoint_regulate_for_store.hpp b/include/async_mqtt/impl/endpoint_regulate_for_store.hpp index 06dcf5b58..801b5e376 100644 --- a/include/async_mqtt/impl/endpoint_regulate_for_store.hpp +++ b/include/async_mqtt/impl/endpoint_regulate_for_store.hpp @@ -8,75 +8,10 @@ #define ASYNC_MQTT_IMPL_ENDPOINT_REGULATE_FOR_STORE_HPP #include +#include namespace async_mqtt { -namespace detail { - -template -struct basic_endpoint_impl:: -regulate_for_store_op { - this_type_sp ep; - v5::basic_publish_packet packet; - enum { dispatch, complete } state = dispatch; - - template - void operator()( - Self& self - ) { - auto& a_ep{*ep}; - switch (state) { - case dispatch: { - state = complete; - as::dispatch( - a_ep.get_executor(), - force_move(self) - ); - } break; - case complete: { - error_code ec; - a_ep.regulate_for_store(packet, ec); - self.complete(ec, force_move(packet)); - } break; - } - } -}; - -// sync version - -template -inline -void -basic_endpoint_impl::regulate_for_store( - v5::basic_publish_packet& packet, - error_code& ec -) const { - if (packet.topic().empty()) { - if (auto ta_opt = get_topic_alias(packet.props())) { - auto topic = topic_alias_send_->find_without_touch(*ta_opt); - if (topic.empty()) { - ec = make_error_code( - mqtt_error::packet_not_regulated - ); - return; - } - packet.remove_topic_alias_add_topic(force_move(topic)); - } - else { - ec = make_error_code( - mqtt_error::packet_not_regulated - ); - return; - } - } - else { - packet.remove_topic_alias(); - } - ec = error_code{}; -} - -} // namespace detail - template template auto @@ -89,16 +24,24 @@ basic_endpoint::async_regulate_for_store( << "regulate_for_store:" << packet; BOOST_ASSERT(impl_); return - as::async_compose< + as::async_initiate< CompletionToken, void(error_code, v5::basic_publish_packet) >( - typename impl_type::regulate_for_store_op{ - impl_, - force_move(packet) + []( + auto handler, + std::shared_ptr impl, + v5::basic_publish_packet packet + ) { + impl_type::async_regulate_for_store( + force_move(impl), + force_move(packet), + force_move(handler) + ); }, token, - get_executor() + impl_, + force_move(packet) ); } @@ -120,4 +63,8 @@ basic_endpoint::regulate_for_store( } // namespace async_mqtt +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + #endif // ASYNC_MQTT_IMPL_ENDPOINT_REGULATE_FOR_STORE_HPP diff --git a/include/async_mqtt/impl/endpoint_regulate_for_store.ipp b/include/async_mqtt/impl/endpoint_regulate_for_store.ipp new file mode 100644 index 000000000..ddd40c05a --- /dev/null +++ b/include/async_mqtt/impl/endpoint_regulate_for_store.ipp @@ -0,0 +1,86 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_ENDPOINT_REGULATE_FOR_STORE_IPP) +#define ASYNC_MQTT_IMPL_ENDPOINT_REGULATE_FOR_STORE_IPP + +#include +#include +#include + +namespace async_mqtt::detail { + +template +struct basic_endpoint_impl:: +regulate_for_store_op { + this_type_sp ep; + v5::basic_publish_packet packet; + enum { dispatch, complete } state = dispatch; + + template + void operator()( + Self& self + ) { + auto& a_ep{*ep}; + switch (state) { + case dispatch: { + state = complete; + as::dispatch( + a_ep.get_executor(), + force_move(self) + ); + } break; + case complete: { + error_code ec = a_ep.con_.regulate_for_store(packet); + self.complete(ec, force_move(packet)); + } break; + } + } +}; + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::async_regulate_for_store( + this_type_sp impl, + v5::basic_publish_packet packet, + as::any_completion_handler< + void(error_code, v5::basic_publish_packet) + > handler +) { + auto exe = impl->get_executor(); + as::async_compose< + as::any_completion_handler< + void(error_code, v5::basic_publish_packet) + >, + void(error_code, v5::basic_publish_packet) + >( + regulate_for_store_op{ + force_move(impl), + force_move(packet) + }, + handler, + exe + ); +} + +// sync version + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::regulate_for_store( + v5::basic_publish_packet& packet, + error_code& ec +) const { + ec = con_.regulate_for_store(packet); +} + +} // namespace async_mqtt::detail + +#include + +#endif // ASYNC_MQTT_IMPL_ENDPOINT_REGULATE_FOR_STORE_IPP diff --git a/include/async_mqtt/impl/endpoint_release_packet_id.hpp b/include/async_mqtt/impl/endpoint_release_packet_id.hpp index 3fa092ab3..76b2cd813 100644 --- a/include/async_mqtt/impl/endpoint_release_packet_id.hpp +++ b/include/async_mqtt/impl/endpoint_release_packet_id.hpp @@ -8,52 +8,11 @@ #define ASYNC_MQTT_IMPL_ENDPOINT_RELEASE_PACKET_ID_HPP #include +#include +#include namespace async_mqtt { -namespace detail { - -template -struct basic_endpoint_impl:: -release_packet_id_op { - this_type_sp ep; - typename basic_packet_id_type::type packet_id; - enum { dispatch, complete } state = dispatch; - - template - void operator()( - Self& self - ) { - auto& a_ep{*ep}; - switch (state) { - case dispatch: { - state = complete; - as::dispatch( - a_ep.get_executor(), - force_move(self) - ); - } break; - case complete: - a_ep.release_pid(packet_id); - state = complete; - self.complete(); - break; - } - } -}; - -// sync version - -template -inline -void -basic_endpoint_impl:: -release_packet_id(typename basic_packet_id_type::type packet_id) { - release_pid(packet_id); -} - -} // namespace detail - template template auto @@ -66,16 +25,24 @@ basic_endpoint::async_release_packet_id( << "release_packet_id pid:" << packet_id; BOOST_ASSERT(impl_); return - as::async_compose< + as::async_initiate< CompletionToken, void() >( - typename impl_type::release_packet_id_op{ - impl_, - packet_id + []( + auto handler, + std::shared_ptr impl, + typename basic_packet_id_type::type packet_id + ) { + impl_type::async_release_packet_id( + force_move(impl), + packet_id, + force_move(handler) + ); }, token, - get_executor() + impl_, + packet_id ); } @@ -95,4 +62,8 @@ release_packet_id(typename basic_packet_id_type::type packet_id) } // namespace async_mqtt +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + #endif // ASYNC_MQTT_IMPL_ENDPOINT_RELEASE_PACKET_ID_HPP diff --git a/include/async_mqtt/impl/endpoint_release_packet_id.ipp b/include/async_mqtt/impl/endpoint_release_packet_id.ipp new file mode 100644 index 000000000..4e6d18311 --- /dev/null +++ b/include/async_mqtt/impl/endpoint_release_packet_id.ipp @@ -0,0 +1,100 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_ENDPOINT_RELEASE_PACKET_ID_IPP) +#define ASYNC_MQTT_IMPL_ENDPOINT_RELEASE_PACKET_ID_IPP + +#include +#include +#include +#include + +namespace async_mqtt::detail { + +template +struct basic_endpoint_impl:: +release_packet_id_op { + this_type_sp ep; + typename basic_packet_id_type::type packet_id; + enum { dispatch, complete } state = dispatch; + + template + void operator()( + Self& self + ) { + auto& a_ep{*ep}; + switch (state) { + case dispatch: { + state = complete; + as::dispatch( + a_ep.get_executor(), + force_move(self) + ); + } break; + case complete: { + auto events = a_ep.con_.release_packet_id(packet_id); + for (auto& event : events) { + std::visit( + overload { + [&](async_mqtt::event::basic_packet_id_released const& ev) { + a_ep.notify_release_pid(ev.get()); + }, + [](auto const&) { + BOOST_ASSERT(false); + } + }, + event + ); + } + state = complete; + self.complete(); + } break; + } + } +}; + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl:: +async_release_packet_id( + this_type_sp impl, + typename basic_packet_id_type::type packet_id, + as::any_completion_handler< + void() + > handler +) { + auto exe = impl->get_executor(); + as::async_compose< + as::any_completion_handler< + void() + >, + void() + >( + release_packet_id_op{ + force_move(impl), + packet_id + }, + handler, + exe + ); +} + +// sync version + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl:: +release_packet_id(typename basic_packet_id_type::type packet_id) { + con_.release_packet_id(packet_id); +} + +} // namespace async_mqtt::detail + +#include + +#endif // ASYNC_MQTT_IMPL_ENDPOINT_RELEASE_PACKET_ID_IPP diff --git a/include/async_mqtt/impl/endpoint_restore_packets.hpp b/include/async_mqtt/impl/endpoint_restore_packets.hpp index 7e29c2b9e..1a904a103 100644 --- a/include/async_mqtt/impl/endpoint_restore_packets.hpp +++ b/include/async_mqtt/impl/endpoint_restore_packets.hpp @@ -8,66 +8,10 @@ #define ASYNC_MQTT_IMPL_ENDPOINT_RESTORE_PACKETS_HPP #include +#include namespace async_mqtt { -namespace detail { - -template -struct basic_endpoint_impl:: -restore_packets_op { - this_type_sp ep; - std::vector> pvs; - enum { dispatch, complete } state = dispatch; - - template - void operator()( - Self& self - ) { - auto& a_ep{*ep}; - switch (state) { - case dispatch: { - state = complete; - as::dispatch( - a_ep.get_executor(), - force_move(self) - ); - } break; - case complete: - a_ep.restore_packets(force_move(pvs)); - self.complete(); - break; - } - } -}; - -// sync version - -template -inline -void -basic_endpoint_impl::restore_packets( - std::vector> pvs -) { - for (auto& pv : pvs) { - pv.visit( - [&](auto& p) { - if (pid_man_.register_id(p.packet_id())) { - store_.add(force_move(p)); - } - else { - ASYNC_MQTT_LOG("mqtt_impl", error) - << ASYNC_MQTT_ADD_VALUE(address, this) - << "packet_id:" << p.packet_id() - << " has already been used. Skip it"; - } - } - ); - } -} - -} // namespace detail - template template auto @@ -80,16 +24,24 @@ basic_endpoint::async_restore_packets( << "restore_packets"; BOOST_ASSERT(impl_); return - as::async_compose< + as::async_initiate< CompletionToken, void() >( - typename impl_type::restore_packets_op{ - impl_, - force_move(pvs) + []( + auto handler, + std::shared_ptr impl, + std::vector> pvs + ) { + impl_type::async_restore_packets( + force_move(impl), + force_move(pvs), + force_move(handler) + ); }, token, - get_executor() + impl_, + force_move(pvs) ); } @@ -110,4 +62,8 @@ basic_endpoint::restore_packets( } // namespace async_mqtt +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + #endif // ASYNC_MQTT_IMPL_ENDPOINT_RESTORE_PACKETS_HPP diff --git a/include/async_mqtt/impl/endpoint_restore_packets.ipp b/include/async_mqtt/impl/endpoint_restore_packets.ipp new file mode 100644 index 000000000..a3ec103a3 --- /dev/null +++ b/include/async_mqtt/impl/endpoint_restore_packets.ipp @@ -0,0 +1,85 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_ENDPOINT_RESTORE_PACKETS_IPP) +#define ASYNC_MQTT_IMPL_ENDPOINT_RESTORE_PACKETS_IPP + +#include +#include +#include + +namespace async_mqtt::detail { + +template +struct basic_endpoint_impl:: +restore_packets_op { + this_type_sp ep; + std::vector> pvs; + enum { dispatch, complete } state = dispatch; + + template + void operator()( + Self& self + ) { + auto& a_ep{*ep}; + switch (state) { + case dispatch: { + state = complete; + as::dispatch( + a_ep.get_executor(), + force_move(self) + ); + } break; + case complete: + a_ep.con_.restore_packets(force_move(pvs)); + self.complete(); + break; + } + } +}; + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::async_restore_packets( + this_type_sp impl, + std::vector> pvs, + as::any_completion_handler< + void() + > handler +) { + auto exe = impl->get_executor(); + as::async_compose< + as::any_completion_handler< + void() + >, + void() + >( + restore_packets_op{ + force_move(impl), + force_move(pvs) + }, + handler, + exe + ); +} + +// sync version + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_endpoint_impl::restore_packets( + std::vector> pvs +) { + con_.restore_packets(force_move(pvs)); +} + +} // namespace async_mqtt::detail + +#include + +#endif // ASYNC_MQTT_IMPL_ENDPOINT_RESTORE_PACKETS_IPP diff --git a/include/async_mqtt/impl/endpoint_send.hpp b/include/async_mqtt/impl/endpoint_send.hpp index 8ee8b073c..9f47397f6 100644 --- a/include/async_mqtt/impl/endpoint_send.hpp +++ b/include/async_mqtt/impl/endpoint_send.hpp @@ -8,6 +8,10 @@ #define ASYNC_MQTT_IMPL_ENDPOINT_SEND_HPP #include +#include +#include +#include +#include namespace async_mqtt { @@ -20,14 +24,116 @@ send_op { this_type_sp ep; Packet packet; bool from_queue = false; - std::optional::type> release_pid_opt = std::nullopt; - enum { dispatch, write, complete } state = dispatch; + std::optional decided_error = std::nullopt; + using events_type = std::vector>; + using events_it_type = typename events_type::iterator; + std::shared_ptr events = nullptr; + events_it_type it = events_it_type{}; + bool disconnect_sent_just_before = false; + enum { dispatch, write, sent, close, complete } state = dispatch; + + template + bool process_one_event( + Self& self + ) { + auto& a_ep{*ep}; + auto& event{*it++}; + return std::visit( + overload{ + [&](error_code ec) { + if (ec == disconnect_reason_code::receive_maximum_exceeded) { + if constexpr (std::is_same_v>) { + auto success = a_ep.register_packet_id(packet.packet_id()); + if (success) { + a_ep.enqueue_publish(packet); + decided_error.emplace( + make_error_code( + mqtt_error::packet_enqueued + ) + ); + } + else { + BOOST_ASSERT(false); + } + return true; + } + } + decided_error.emplace(ec); + return true; + }, + [&](async_mqtt::event::timer const& ev) { + switch (ev.get_kind()) { + case timer_kind::pingreq_send: + if (ev.get_op() == timer_op::reset) { + reset_pingreq_send_timer(ep, ev.get_ms()); + } + else { + BOOST_ASSERT(false); + } + break; + case timer_kind::pingresp_recv: + if (ev.get_op() == timer_op::reset) { + reset_pingresp_recv_timer(ep, ev.get_ms()); + } + else { + BOOST_ASSERT(false); + } + break; + default: + BOOST_ASSERT(false); + break; + } + return true; + }, + [&](async_mqtt::event::basic_packet_id_released const& ev) { + a_ep.notify_release_pid(ev.get()); + return true; + }, + [&](async_mqtt::event::basic_send& ev) { + state = sent; + disconnect_sent_just_before = ev.get().type() == control_packet_type::disconnect; + a_ep.stream_.async_write_packet( + force_move(ev.get()), + as::append( + force_move(self), + ev.get_release_packet_id_if_send_error() + ) + ); + return false; + }, + [&](async_mqtt::event::close) { + state = close; + if (disconnect_sent_just_before && + a_ep.duration_close_by_disconnect_ != std::chrono::milliseconds::zero() + ) { + a_ep.tim_close_by_disconnect_.expires_after(a_ep.duration_close_by_disconnect_); + a_ep.tim_close_by_disconnect_.async_wait( + force_move(self) + ); + } + else { + as::post( + a_ep.get_executor(), + force_move(self) + ); + } + return false; + }, + [&](auto const&) { + BOOST_ASSERT(false); + return true; + } + }, + event + ); + } template void operator()( Self& self, error_code ec = error_code{}, - std::size_t /*bytes_transferred*/ = 0 + std::size_t /*bytes_transferred*/ = 0, + std::optional::type> release_pid_opt = std::nullopt ) { auto& a_ep{*ep}; if (ec) { @@ -35,7 +141,7 @@ send_op { << ASYNC_MQTT_ADD_VALUE(address, &a_ep) << "send error:" << ec.message(); if (release_pid_opt) { - a_ep.release_pid(*release_pid_opt); + a_ep.con_.release_packet_id(*release_pid_opt); } self.complete(ec); return; @@ -50,546 +156,45 @@ send_op { ); } break; case write: { - state = complete; - if constexpr( - std::is_same_v, basic_packet_variant> || - std::is_same_v, basic_store_packet_variant> - ) { - packet.visit( - overload { - [&](auto actual_packet) { - if (process_send_packet(self, actual_packet)) { - auto ep_copy = ep; - a_ep.stream_.async_write_packet( - actual_packet, - force_move(self) - ); - if constexpr(is_connack>()) { - // server send stored packets after connack sent - send_stored(ep_copy); - } - if constexpr(Role == role::client) { - reset_pingreq_send_timer(force_move(ep_copy)); - } - } - }, - [&](std::monostate const&) {} - } - ); + events = std::make_shared(a_ep.con_.send(packet)); + it = events->begin(); + while (it != events->end()) { + if (!process_one_event(self)) return; } - else { - if (process_send_packet(self, packet)) { - auto a_packet{packet}; - auto ep_copy = ep; - a_ep.stream_.async_write_packet( - force_move(a_packet), - force_move(self) - ); - if constexpr(is_connack()) { - // server send stored packets after connack sent - send_stored(ep_copy); - } - if constexpr(Role == role::client) { - reset_pingreq_send_timer(force_move(ep_copy)); - } - } + state = complete; // all events processed + as::dispatch( + a_ep.get_executor(), + force_move(self) + ); + } break; + case sent: { + while (it != events->end()) { + if (!process_one_event(self)) return; } + state = complete; // all events processed + as::dispatch( + a_ep.get_executor(), + force_move(self) + ); } break; - case complete: - self.complete(ec); - break; - } - } - - template - bool process_send_packet(Self& self, ActualPacket& actual_packet) { - // MQTT protocol sendable packet check - if ( - !( - (can_send_as_client(Role) && is_client_sendable>()) || - (can_send_as_server(Role) && is_server_sendable>()) - ) - ) { - self.complete( - make_error_code( - mqtt_error::packet_not_allowed_to_send - ) + case close: { + state = complete; + auto ep_copy{ep}; + async_close( + force_move(ep_copy), + force_move(self) ); - return false; - } - - auto version_check = - [&] { - if (ep->protocol_version_ == protocol_version::v3_1_1 && is_v3_1_1()) { - return true; - } - if (ep->protocol_version_ == protocol_version::v5 && is_v5()) { - return true; - } - return false; - }; - - // connection status check - if constexpr(is_connect()) { - if (ep->status_ != connection_status::closed) { - self.complete( - make_error_code( - mqtt_error::packet_not_allowed_to_send - ) - ); - return false; - } - if (!version_check()) { - self.complete( - make_error_code( - mqtt_error::packet_not_allowed_to_send - ) - ); - return false; - } - } - else if constexpr(is_connack()) { - if (ep->status_ != connection_status::connecting) { - self.complete( - make_error_code( - mqtt_error::packet_not_allowed_to_send - ) - ); - return false; - } - if (!version_check()) { - self.complete( - make_error_code( - mqtt_error::packet_not_allowed_to_send - ) - ); - return false; - } - } - else if constexpr(std::is_same_v) { - if (ep->status_ != connection_status::connected && - ep->status_ != connection_status::connecting) { - self.complete( - make_error_code( - mqtt_error::packet_not_allowed_to_send - ) - ); - return false; - } - if (!version_check()) { - self.complete( - make_error_code( - mqtt_error::packet_not_allowed_to_send - ) - ); - return false; - } - } - else { - if (ep->status_ != connection_status::connected) { - if constexpr(!is_publish>()) { - self.complete( - make_error_code( - mqtt_error::packet_not_allowed_to_send - ) - ); - return false; - } - } - if (!version_check()) { - self.complete( - make_error_code( - mqtt_error::packet_not_allowed_to_send - ) - ); - return false; - } - } - - // sending process - bool topic_alias_validated = false; - - if constexpr(std::is_same_v>) { - ep->initialize(); - ep->status_ = connection_status::connecting; - auto keep_alive = actual_packet.keep_alive(); - if (keep_alive != 0 && !ep->pingreq_send_interval_ms_) { - ep->pingreq_send_interval_ms_.emplace(keep_alive * 1000); - } - if (actual_packet.clean_session()) { - ep->clear_pid_man(); - ep->store_.clear(); - ep->need_store_ = false; - } - else { - ep->need_store_ = true; - } - ep->topic_alias_send_ = std::nullopt; - } - - if constexpr(std::is_same_v>) { - ep->initialize(); - ep->status_ = connection_status::connecting; - auto keep_alive = actual_packet.keep_alive(); - if (keep_alive != 0 && !ep->pingreq_send_interval_ms_) { - ep->pingreq_send_interval_ms_.emplace(std::chrono::seconds{keep_alive}); - } - if (actual_packet.clean_start()) { - ep->clear_pid_man(); - ep->store_.clear(); - } - for (auto const& prop : actual_packet.props()) { - prop.visit( - overload { - [&](property::topic_alias_maximum const& p) { - if (p.val() != 0) { - ep->topic_alias_recv_.emplace(p.val()); - } - }, - [&](property::receive_maximum const& p) { - BOOST_ASSERT(p.val() != 0); - ep->publish_recv_max_ = p.val(); - }, - [&](property::maximum_packet_size const& p) { - BOOST_ASSERT(p.val() != 0); - ep->maximum_packet_size_recv_ = p.val(); - }, - [&](property::session_expiry_interval const& p) { - if (p.val() != 0) { - ep->need_store_ = true; - } - }, - [](auto const&){} - } - ); - } - } - - if constexpr(std::is_same_v>) { - if (actual_packet.code() == connect_return_code::accepted) { - ep->status_ = connection_status::connected; - } - else { - ep->status_ = connection_status::disconnecting; - } - } - - if constexpr(std::is_same_v>) { - if (actual_packet.code() == connect_reason_code::success) { - ep->status_ = connection_status::connected; - for (auto const& prop : actual_packet.props()) { - prop.visit( - overload { - [&](property::topic_alias_maximum const& p) { - if (p.val() != 0) { - ep->topic_alias_recv_.emplace(p.val()); - } - }, - [&](property::receive_maximum const& p) { - BOOST_ASSERT(p.val() != 0); - ep->publish_recv_max_ = p.val(); - }, - [&](property::maximum_packet_size const& p) { - BOOST_ASSERT(p.val() != 0); - ep->maximum_packet_size_recv_ = p.val(); - }, - [](auto const&){} - } - ); - } - } - else { - ep->status_ = connection_status::disconnecting; - } - } - - // store publish/pubrel packet - if constexpr(is_publish>()) { - if (actual_packet.opts().get_qos() == qos::at_least_once || - actual_packet.opts().get_qos() == qos::exactly_once - ) { - auto packet_id = actual_packet.packet_id(); - BOOST_ASSERT(ep->pid_man_.is_used_id(packet_id)); - release_pid_opt.emplace(packet_id); - if (ep->need_store_) { - if constexpr(is_instance_of>::value) { - auto ta_opt = get_topic_alias(actual_packet.props()); - if (actual_packet.topic().empty()) { - auto topic_opt = validate_topic_alias(ta_opt); - if (!topic_opt) { - self.complete( - make_error_code( - mqtt_error::packet_not_allowed_to_send - ) - ); - if (packet_id != 0) { - ep->release_pid(packet_id); - } - return false; - } - topic_alias_validated = true; - auto props = actual_packet.props(); - auto it = props.cbegin(); - auto end = props.cend(); - for (; it != end; ++it) { - if (it->id() == property::id::topic_alias) { - props.erase(it); - break; - } - } - - auto store_packet = - ActualPacket( - packet_id, - force_move(*topic_opt), - actual_packet.payload_as_buffer(), - actual_packet.opts(), - force_move(props) - ); - if (!validate_maximum_packet_size(store_packet.size())) { - self.complete( - make_error_code( - mqtt_error::packet_not_allowed_to_send - ) - ); - if (packet_id != 0) { - ep->release_pid(packet_id); - } - return false; - } - // add new packet that doesn't have topic_aliass to store - // the original packet still use topic alias to send - store_packet.set_dup(true); - ep->store_.add(force_move(store_packet)); - // even if send error would happens - // packet_id should be remained - release_pid_opt.reset(); - } - else { - auto props = actual_packet.props(); - auto it = props.cbegin(); - auto end = props.cend(); - for (; it != end; ++it) { - if (it->id() == property::id::topic_alias) { - props.erase(it); - break; - } - } - - auto store_packet = - ActualPacket( - packet_id, - actual_packet.topic(), - actual_packet.payload_as_buffer(), - actual_packet.opts(), - force_move(props) - ); - if (!validate_maximum_packet_size(store_packet.size())) { - self.complete( - make_error_code( - mqtt_error::packet_not_allowed_to_send - ) - ); - if (packet_id != 0) { - ep->release_pid(packet_id); - } - return false; - } - store_packet.set_dup(true); - ep->store_.add(force_move(store_packet)); - // even if send error would happens - // packet_id should be remained - release_pid_opt.reset(); - } - } - else { - if (!validate_maximum_packet_size(actual_packet.size())) { - self.complete( - make_error_code( - mqtt_error::packet_not_allowed_to_send - ) - ); - if (packet_id != 0) { - ep->release_pid(packet_id); - } - return false; - } - auto store_packet{actual_packet}; - store_packet.set_dup(true); - ep->store_.add(force_move(store_packet)); - // even if send error would happens - // packet_id should be remained - release_pid_opt.reset(); - } - } - if (actual_packet.opts().get_qos() == qos::exactly_once) { - ep->qos2_publish_processing_.insert(packet_id); - ep->pid_pubrec_.insert(packet_id); - } - else { - ep->pid_puback_.insert(packet_id); - } - } - } - - if constexpr(is_instance_of>::value) { - // apply topic_alias - auto ta_opt = get_topic_alias(actual_packet.props()); - if (actual_packet.topic().empty()) { - if (!topic_alias_validated && - !validate_topic_alias(ta_opt)) { - self.complete( - make_error_code( - mqtt_error::packet_not_allowed_to_send - ) - ); - auto packet_id = actual_packet.packet_id(); - if (packet_id != 0) { - ep->release_pid(packet_id); - } - return false; - } - // use topic_alias set by user + } break; + case complete: { + if (decided_error) { + self.complete(*decided_error); } else { - if (ta_opt) { - if (validate_topic_alias_range(*ta_opt)) { - ASYNC_MQTT_LOG("mqtt_impl", trace) - << ASYNC_MQTT_ADD_VALUE(address, &ep) - << "topia alias : " - << actual_packet.topic() << " - " << *ta_opt - << " is registered." ; - BOOST_ASSERT(ep->topic_alias_send_); - ep->topic_alias_send_->insert_or_update(actual_packet.topic(), *ta_opt); - } - else { - self.complete( - make_error_code( - mqtt_error::packet_not_allowed_to_send - ) - ); - auto packet_id = actual_packet.packet_id(); - if (packet_id != 0) { - ep->release_pid(packet_id); - } - return false; - } - } - else if (ep->auto_map_topic_alias_send_) { - if (ep->topic_alias_send_) { - if (auto ta_opt = ep->topic_alias_send_->find(actual_packet.topic())) { - ASYNC_MQTT_LOG("mqtt_impl", trace) - << ASYNC_MQTT_ADD_VALUE(address, &ep) - << "topia alias : " << actual_packet.topic() << " - " << *ta_opt - << " is found." ; - actual_packet.remove_topic_add_topic_alias(*ta_opt); - } - else { - auto lru_ta = ep->topic_alias_send_->get_lru_alias(); - ep->topic_alias_send_->insert_or_update(actual_packet.topic(), lru_ta); // remap topic alias - actual_packet.add_topic_alias(lru_ta); - } - } - } - else if (ep->auto_replace_topic_alias_send_) { - if (ep->topic_alias_send_) { - if (auto ta_opt = ep->topic_alias_send_->find(actual_packet.topic())) { - ASYNC_MQTT_LOG("mqtt_impl", trace) - << ASYNC_MQTT_ADD_VALUE(address, &ep) - << "topia alias : " << actual_packet.topic() << " - " << *ta_opt - << " is found." ; - actual_packet.remove_topic_add_topic_alias(*ta_opt); - } - } - } - } - - // receive_maximum for sending - if (!from_queue && ep->enqueue_publish(actual_packet)) { - self.complete( - error_code{} - ); - return false; - } - } - - if constexpr(is_instance_of>::value) { - ep->publish_recv_.erase(actual_packet.packet_id()); - } - - if constexpr(is_instance_of>::value) { - if (make_error_code(actual_packet.code())) { - ep->publish_recv_.erase(actual_packet.packet_id()); - ep->qos2_publish_handled_.erase(actual_packet.packet_id()); - } - } - - if constexpr(is_pubrel>()) { - auto packet_id = actual_packet.packet_id(); - BOOST_ASSERT(ep->pid_man_.is_used_id(packet_id)); - if (ep->need_store_) ep->store_.add(actual_packet); - ep->pid_pubcomp_.insert(packet_id); - } - - if constexpr(is_instance_of>::value) { - ep->publish_recv_.erase(actual_packet.packet_id()); - } - - if constexpr(is_subscribe>()) { - auto packet_id = actual_packet.packet_id(); - BOOST_ASSERT(ep->pid_man_.is_used_id(packet_id)); - ep->pid_suback_.insert(packet_id); - release_pid_opt.emplace(packet_id); - } - - if constexpr(is_unsubscribe>()) { - auto packet_id = actual_packet.packet_id(); - BOOST_ASSERT(ep->pid_man_.is_used_id(packet_id)); - ep->pid_unsuback_.insert(packet_id); - release_pid_opt.emplace(packet_id); - } - - if constexpr(is_pingreq>()) { - reset_pingresp_recv_timer(ep); - } - - if constexpr(is_disconnect>()) { - ep->status_ = connection_status::disconnecting; - } - - if (!validate_maximum_packet_size(actual_packet.size())) { - self.complete( - make_error_code( - mqtt_error::packet_not_allowed_to_send - ) - ); - if constexpr(own_packet_id>()) { - auto packet_id = actual_packet.packet_id(); - if (packet_id != 0) { - ep->release_pid(packet_id); - } - } - return false; - } - - if constexpr(is_publish>()) { - if (ep->status_ != connection_status::connected) { - // offline publish - ASYNC_MQTT_LOG("mqtt_impl", trace) - << ASYNC_MQTT_ADD_VALUE(address, &ep) - << "publish message is not sent but stored"; - self.complete( - error_code{} - ); - return false; + self.complete(ec); } + } break; } - return true; } - - bool validate_topic_alias_range(topic_alias_type ta); - std::optional validate_topic_alias(std::optional ta_opt); - bool validate_maximum_packet_size(std::size_t size); }; template @@ -656,14 +261,6 @@ basic_endpoint::async_send( << ASYNC_MQTT_ADD_VALUE(address, this) << "send:" << packet; BOOST_ASSERT(impl_); - if constexpr(!std::is_same_v>) { - static_assert( - (impl_type::can_send_as_client(Role) && is_client_sendable>()) || - (impl_type::can_send_as_server(Role) && is_server_sendable>()), - "Packet cannot be send by MQTT protocol" - ); - } - return impl_type::async_send( impl_, @@ -674,8 +271,4 @@ basic_endpoint::async_send( } // namespace async_mqtt -#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include -#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) - #endif // ASYNC_MQTT_IMPL_ENDPOINT_SEND_HPP diff --git a/include/async_mqtt/impl/endpoint_send.ipp b/include/async_mqtt/impl/endpoint_send.ipp deleted file mode 100644 index dc8492837..000000000 --- a/include/async_mqtt/impl/endpoint_send.ipp +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright Takatoshi Kondo 2022 -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#if !defined(ASYNC_MQTT_IMPL_ENDPOINT_SEND_IPP) -#define ASYNC_MQTT_IMPL_ENDPOINT_SEND_IPP - -#include -#include - -namespace async_mqtt::detail { - -template -template -ASYNC_MQTT_HEADER_ONLY_INLINE -bool -basic_endpoint_impl:: -send_op:: -validate_topic_alias_range(topic_alias_type ta) { - if (!ep->topic_alias_send_) { - ASYNC_MQTT_LOG("mqtt_impl", error) - << ASYNC_MQTT_ADD_VALUE(address, ep.get()) - << "topic_alias is set but topic_alias_maximum is 0"; - return false; - } - if (ta == 0 || ta > ep->topic_alias_send_->max()) { - ASYNC_MQTT_LOG("mqtt_impl", error) - << ASYNC_MQTT_ADD_VALUE(address, ep.get()) - << "topic_alias is set but out of range"; - return false; - } - return true; -} - -template -template -ASYNC_MQTT_HEADER_ONLY_INLINE -std::optional -basic_endpoint_impl:: -send_op:: -validate_topic_alias(std::optional ta_opt) { - if (!ta_opt) { - ASYNC_MQTT_LOG("mqtt_impl", error) - << ASYNC_MQTT_ADD_VALUE(address, ep.get()) - << "topic is empty but topic_alias isn't set"; - return std::nullopt; - } - - if (!validate_topic_alias_range(*ta_opt)) { - return std::nullopt; - } - - auto topic = ep->topic_alias_send_->find(*ta_opt); - if (topic.empty()) { - ASYNC_MQTT_LOG("mqtt_impl", error) - << ASYNC_MQTT_ADD_VALUE(address, ep.get()) - << "topic is empty but topic_alias is not registered"; - return std::nullopt; - } - return topic; -} - -template -template -ASYNC_MQTT_HEADER_ONLY_INLINE -bool -basic_endpoint_impl:: -send_op:: -validate_maximum_packet_size(std::size_t size) { - if (size > ep->maximum_packet_size_send_) { - ASYNC_MQTT_LOG("mqtt_impl", error) - << ASYNC_MQTT_ADD_VALUE(address, ep.get()) - << "packet size over maximum_packet_size for sending"; - return false; - } - return true; -} - -} // namespace async_mqtt::detail - -#if defined(ASYNC_MQTT_SEPARATE_COMPILATION) - -#include - -#define ASYNC_MQTT_INSTANTIATE_EACH_PACKET(a_role, a_size, a_protocol, a_packet) \ -namespace async_mqtt::detail { \ -template \ -bool \ -basic_endpoint_impl::send_op:: \ -validate_topic_alias_range(topic_alias_type); \ -\ -template \ -std::optional \ -basic_endpoint_impl::send_op:: \ -validate_topic_alias(std::optional); \ -\ -template \ -bool \ -basic_endpoint_impl::send_op:: \ -validate_maximum_packet_size(std::size_t); \ -} // namespace async_mqtt::detail - -#define ASYNC_MQTT_PP_GENERATE(r, product) \ - BOOST_PP_EXPAND( \ - ASYNC_MQTT_INSTANTIATE_EACH_PACKET \ - BOOST_PP_SEQ_TO_TUPLE( \ - product \ - ) \ - ) - -BOOST_PP_SEQ_FOR_EACH_PRODUCT( - ASYNC_MQTT_PP_GENERATE, - (ASYNC_MQTT_PP_ROLE)(ASYNC_MQTT_PP_SIZE)(ASYNC_MQTT_PP_PROTOCOL)(ASYNC_MQTT_PP_PACKET) -) - -#define ASYNC_MQTT_PP_GENERATE_BASIC(r, product) \ - BOOST_PP_EXPAND( \ - ASYNC_MQTT_INSTANTIATE_EACH_PACKET \ - BOOST_PP_SEQ_TO_TUPLE( \ - BOOST_PP_SEQ_REPLACE( \ - product, \ - BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(product)), \ - ASYNC_MQTT_PP_BASIC_PACKET_INSTANTIATE( \ - BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(product)), product), \ - BOOST_PP_SEQ_ELEM(1, product) \ - ) \ - ) \ - ) \ - ) - -BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE_BASIC, (ASYNC_MQTT_PP_ROLE)(ASYNC_MQTT_PP_SIZE)(ASYNC_MQTT_PP_PROTOCOL)(ASYNC_MQTT_PP_BASIC_PACKET)) - - -#undef ASYNC_MQTT_PP_GENERATE -#undef ASYNC_MQTT_PP_GENERATE_BASIC -#undef ASYNC_MQTT_INSTANTIATE_EACH_PACKET - -#endif // defined(ASYNC_MQTT_SEPARATE_COMPILATION) - -#endif // ASYNC_MQTT_IMPL_ENDPOINT_SEND_IPP diff --git a/include/async_mqtt/impl/endpoint_underlying_handshake.hpp b/include/async_mqtt/impl/endpoint_underlying_handshake.hpp new file mode 100644 index 000000000..b57af9bc2 --- /dev/null +++ b/include/async_mqtt/impl/endpoint_underlying_handshake.hpp @@ -0,0 +1,174 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_ENDPOINT_UNDERLYING_HANDSHAKE_HPP) +#define ASYNC_MQTT_IMPL_ENDPOINT_UNDERLYING_HANDSHAKE_HPP + +#include +#include +#include +#include +#include + +#include +#include + +namespace async_mqtt { + +namespace hana = boost::hana; + +namespace detail { + +template +template +struct basic_endpoint_impl:: +underlying_handshake_op { + this_type_sp ep; + ArgsTuple args_tuple; + enum { dispatch, underlying_handshake, complete } state = dispatch; + template + void operator()( + Self& self, + error_code ec = error_code{} + ) { + auto& a_ep{*ep}; + switch (state) { + case dispatch: { + state = underlying_handshake; + as::dispatch( + a_ep.get_executor(), + force_move(self) + ); + } break; + case underlying_handshake: + state = complete; + ASYNC_MQTT_LOG("mqtt_api", info) + << ASYNC_MQTT_ADD_VALUE(address, this) + << "underlying_handshake"; + hana::unpack( + force_move(args_tuple), + [&](auto&&... args) { + a_ep.stream_.async_underlying_handshake( + std::forward(args)..., + force_move(self) + ); + } + ); + break; + case complete: + if (!ec) { + a_ep.status_ = close_status::open; + } + self.complete(ec); + break; + } + } +}; + +template +template < + typename ArgsTuple, + typename CompletionToken +> +auto +basic_endpoint_impl:: +async_underlying_handshake_impl( + this_type_sp impl, + ArgsTuple&& args_tuple, + CompletionToken&& token +) { + return + as::async_compose< + CompletionToken, + void(error_code) + >( + underlying_handshake_op{ + impl, + std::forward(args_tuple) + }, + token, + impl->get_executor() + ); +} + +struct is_customize_handshake_callable_impl { + template < + typename Impl, + typename... Args + > + static + auto + check(Impl&& impl, Args&&... args) -> + decltype( + layer_customize< + typename Impl::next_layer_type + >::async_handshake( + impl.next_layer(), + std::forward(args)... + ), + std::true_type() + ); + + template < + typename Impl, + typename... Args + > + static auto check(...) -> std::false_type; +}; + +template < + typename Impl, + typename... Args +> +struct is_customize_handshake_callable + : decltype( + is_customize_handshake_callable_impl::template check< + Impl, + Args... + >( + std::declval(), + std::declval()... + ) + ) +{ +}; + +} // namespace detail + +template +template +auto +basic_endpoint::async_underlying_handshake( + Args&&... args +) { + BOOST_ASSERT(impl_); + auto all = hana::tuple(std::forward(args)...); + auto back = hana::back(all); + auto rest = hana::drop_back(all, hana::size_c<1>); + + if constexpr( + detail::is_customize_handshake_callable< + impl_type, + Args... + >::value + ) { + return impl_type::async_underlying_handshake_impl( + impl_, + force_move(rest), + force_move(back) // token + ); + } + else { + return impl_type::async_underlying_handshake_impl( + impl_, + force_move(all) + ); + } +} + +} // namespace async_mqtt + +#endif // ASYNC_MQTT_IMPL_ENDPOINT_UNDERLYING_HANDSHAKE_HPP diff --git a/include/async_mqtt/util/stream.hpp b/include/async_mqtt/impl/stream.hpp similarity index 76% rename from include/async_mqtt/util/stream.hpp rename to include/async_mqtt/impl/stream.hpp index f691eec75..3e79df57f 100644 --- a/include/async_mqtt/util/stream.hpp +++ b/include/async_mqtt/impl/stream.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_UTIL_STREAM_HPP) -#define ASYNC_MQTT_UTIL_STREAM_HPP +#if !defined(ASYNC_MQTT_IMPL_STREAM_HPP) +#define ASYNC_MQTT_IMPL_STREAM_HPP #include #include @@ -13,14 +13,14 @@ #include -#include +#include +#include +#include #include #include #include -#include #include -#include namespace async_mqtt { namespace as = boost::asio; @@ -31,12 +31,9 @@ class stream { public: using this_type = stream; using impl_type = detail::stream_impl; - using next_layer_type = typename std::remove_reference::type; - using lowest_layer_type = - typename std::remove_reference< - decltype(get_lowest_layer(std::declval())) - >::type; - using executor_type = async_mqtt::executor_type; + using next_layer_type = NextLayer; + using lowest_layer_type = detail::lowest_layer_type; + using executor_type = typename next_layer_type::executor_type; template < typename T, @@ -80,10 +77,20 @@ class stream { } template < + typename... Args + > + auto + async_underlying_handshake( + Args&&... args + ); + + template < + typename MutableBufferSequence, typename CompletionToken = as::default_completion_token_t > auto - async_read_packet( + async_read_some( + MutableBufferSequence const& buffers, CompletionToken&& token = as::default_completion_token_t{} ); @@ -120,8 +127,8 @@ class stream { >; }; - void set_bulk_read_buffer_size(std::size_t size) { - impl_->set_bulk_read_buffer_size(size); + void set_read_buffer_size(std::size_t size) { + impl_->set_read_buffer_size(size); } private: @@ -141,8 +148,9 @@ class stream { } // namespace async_mqtt -#include -#include -#include +#include +#include +#include +#include -#endif // ASYNC_MQTT_UTIL_STREAM_HPP +#endif // ASYNC_MQTT_IMPL_STREAM_HPP diff --git a/include/async_mqtt/util/impl/stream_close.hpp b/include/async_mqtt/impl/stream_close.hpp similarity index 97% rename from include/async_mqtt/util/impl/stream_close.hpp rename to include/async_mqtt/impl/stream_close.hpp index 0cc23d3b6..ab1f5ffa8 100644 --- a/include/async_mqtt/util/impl/stream_close.hpp +++ b/include/async_mqtt/impl/stream_close.hpp @@ -7,8 +7,9 @@ #if !defined(ASYNC_MQTT_UTIL_IMPL_STREAM_CLOSE_HPP) #define ASYNC_MQTT_UTIL_IMPL_STREAM_CLOSE_HPP -#include -#include +#include +#include +#include namespace async_mqtt { diff --git a/include/async_mqtt/util/stream_traits.hpp b/include/async_mqtt/impl/stream_customize.hpp similarity index 53% rename from include/async_mqtt/util/stream_traits.hpp rename to include/async_mqtt/impl/stream_customize.hpp index 5d2a904a6..140dc05a7 100644 --- a/include/async_mqtt/util/stream_traits.hpp +++ b/include/async_mqtt/impl/stream_customize.hpp @@ -4,88 +4,21 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_UTIL_STREAM_TRAITS_HPP) -#define ASYNC_MQTT_UTIL_STREAM_TRAITS_HPP +#if !defined(ASYNC_MQTT_STREAM_CUSTOMIZE_HPP) +#define ASYNC_MQTT_STREAM_CUSTOMIZE_HPP #include #include #include #include -#include -#include +#include namespace async_mqtt { namespace as = boost::asio; -namespace detail { - -template -std::false_type has_next_layer_impl(void*); - -template -auto has_next_layer_impl(decltype(nullptr)) -> - decltype(std::declval().next_layer(), std::true_type{}); - -} // namespace detail - -template -using has_next_layer = decltype(detail::has_next_layer_impl(nullptr)); - - -namespace detail { - -template::value> -struct lowest_layer_type_impl { - using type = typename std::remove_reference::type; -}; - -template -struct lowest_layer_type_impl { - using type = typename lowest_layer_type_impl< - decltype(std::declval().next_layer())>::type; -}; - -} // namespace detail - -template -using lowest_layer_type = typename detail::lowest_layer_type_impl::type; - -namespace detail { - -template -T& -get_lowest_layer_impl(T& t, std::false_type) noexcept { - return t; -} - -template -lowest_layer_type& -get_lowest_layer_impl(T& t, std::true_type) noexcept { - return - get_lowest_layer_impl( - t.next_layer(), - has_next_layer::type>{} - ); -} - -} // namespace detail - - -template -using executor_type = decltype(std::declval().get_executor()); - -template -lowest_layer_type& get_lowest_layer(T& t) noexcept { - return - detail::get_lowest_layer_impl( - t, - has_next_layer{} - ); -} - /** * @defgroup underlying_customize underlying layer customization * @ingroup underlying_layer @@ -113,25 +46,6 @@ struct has_initialize< > > : std::true_type {}; -// async_read - -template -struct has_async_read : std::false_type {}; - -template -struct has_async_read< - Layer, - std::void_t< - decltype( - layer_customize::async_read( - std::declval(), - std::declval(), - std::declval>() - ) - ) - > -> : std::true_type {}; - // async_read_some template @@ -190,4 +104,4 @@ struct has_async_close< } // namespace async_mqtt -#endif // ASYNC_MQTT_UTIL_STREAM_TRAITS_HPP +#endif // ASYNC_MQTT_STREAM_CUSTOMIZE_HPP diff --git a/include/async_mqtt/util/stream_fwd.hpp b/include/async_mqtt/impl/stream_fwd.hpp similarity index 69% rename from include/async_mqtt/util/stream_fwd.hpp rename to include/async_mqtt/impl/stream_fwd.hpp index b569f115e..2688d6501 100644 --- a/include/async_mqtt/util/stream_fwd.hpp +++ b/include/async_mqtt/impl/stream_fwd.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_UTIL_STREAM_FWD_HPP) -#define ASYNC_MQTT_UTIL_STREAM_FWD_HPP +#if !defined(ASYNC_MQTT_IMPL_STREAM_FWD_HPP) +#define ASYNC_MQTT_IMPL_STREAM_FWD_HPP namespace async_mqtt { @@ -14,4 +14,4 @@ class stream; } // namespace async_mqtt -#endif // ASYNC_MQTT_UTIL_STREAM_FWD_HPP +#endif // ASYNC_MQTT_IMPL_STREAM_FWD_HPP diff --git a/include/async_mqtt/util/detail/stream_impl.hpp b/include/async_mqtt/impl/stream_impl.hpp similarity index 70% rename from include/async_mqtt/util/detail/stream_impl.hpp rename to include/async_mqtt/impl/stream_impl.hpp index 66379cfe1..4e8c177ce 100644 --- a/include/async_mqtt/util/detail/stream_impl.hpp +++ b/include/async_mqtt/impl/stream_impl.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_UTIL_DETAIL_STREAM_IMPL_HPP) -#define ASYNC_MQTT_UTIL_DETAIL_STREAM_IMPL_HPP +#if !defined(ASYNC_MQTT_IMPL_STREAM_IMPL_HPP) +#define ASYNC_MQTT_IMPL_STREAM_IMPL_HPP #include #include @@ -13,12 +13,13 @@ #include -#include -#include +#include +#include +#include +#include #include #include #include -#include #include namespace async_mqtt::detail { @@ -30,12 +31,9 @@ class stream_impl { public: using this_type = stream_impl; using this_type_sp = std::shared_ptr; - using next_layer_type = typename std::remove_reference::type; - using lowest_layer_type = - typename std::remove_reference< - decltype(get_lowest_layer(std::declval())) - >::type; - using executor_type = async_mqtt::executor_type; + using next_layer_type = NextLayer; + using lowest_layer_type = detail::lowest_layer_type; + using executor_type = typename next_layer_type::executor_type; // constructor template < @@ -100,10 +98,6 @@ class stream_impl { >; }; - void set_bulk_read_buffer_size(std::size_t size) { - bulk_read_buffer_size_ = size; - } - private: template static void initialize(Layer& layer) { @@ -119,22 +113,22 @@ class stream_impl { void parse_packet(); - // async operations - - template struct stream_write_packet_op; - struct stream_read_packet_op; - struct stream_close_op; - struct stream_read_some_op; template < - typename CompletionToken = as::default_completion_token_t + typename... Args > - static - auto - async_read_some( + static auto + async_underlying_handshake( this_type_sp impl, - CompletionToken&& token = as::default_completion_token_t{} + Args&&... args ); + // async operations + + template + struct stream_write_packet_op; + template + struct stream_read_some_op; + struct stream_close_op; private: friend class stream; @@ -150,14 +144,8 @@ class stream_impl { next_layer_type nl_; ioc_queue read_queue_; - as::streambuf read_buf_; - std::size_t remaining_length_ = 0; - std::size_t multiplier_ = 1; - std::size_t bulk_read_buffer_size_ = 0; - enum class read_state{fixed_header, remaining_length, payload} read_state_ = read_state::fixed_header; ioc_queue write_queue_; - std::deque read_packets_; - static_vector header_remaining_length_buf_; + struct stream_read_op; std::vector storing_cbs_; std::vector sending_cbs_; bool bulk_write_ = false; @@ -165,4 +153,4 @@ class stream_impl { } // namespace async_mqtt::detail -#endif // ASYNC_MQTT_UTIL_DETAIL_STREAM_IMPL_HPP +#endif // ASYNC_MQTT_IMPL_STREAM_IMPL_HPP diff --git a/include/async_mqtt/impl/stream_impl_fwd.hpp b/include/async_mqtt/impl/stream_impl_fwd.hpp new file mode 100644 index 000000000..53113d6c9 --- /dev/null +++ b/include/async_mqtt/impl/stream_impl_fwd.hpp @@ -0,0 +1,17 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_STREAM_IMPL_FWD_HPP) +#define ASYNC_MQTT_IMPL_STREAM_IMPL_FWD_HPP + +namespace async_mqtt::detail { + +template +class stream_impl; + +} // namespace async_mqtt::detail + +#endif // ASYNC_MQTT_IMPL_STREAM_IMPL_FWD_HPP diff --git a/include/async_mqtt/impl/stream_read.hpp b/include/async_mqtt/impl/stream_read.hpp new file mode 100644 index 000000000..bf8fb1e49 --- /dev/null +++ b/include/async_mqtt/impl/stream_read.hpp @@ -0,0 +1,109 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_UTIL_IMPL_STREAM_READ_HPP) +#define ASYNC_MQTT_UTIL_IMPL_STREAM_READ_HPP + +#include +#include +#include +#include + +namespace async_mqtt { + +namespace detail { + +template +template +struct stream_impl::stream_read_some_op { + using stream_type = this_type; + using stream_type_sp = std::shared_ptr; + using next_layer_type = stream_type::next_layer_type; + + std::shared_ptr strm; + MutableBufferSequence const& buffers; + + enum { dispatch, work, complete } state = dispatch; + + template + void operator()( + Self& self + ) { + auto& a_strm{*strm}; + switch (state) { + case dispatch: { + state = work; + as::dispatch( + a_strm.get_executor(), + force_move(self) + ); + } break; + case work: { + state = complete; + // start bulk read + if constexpr ( + has_async_read_some::value) { + layer_customize::async_read_some( + a_strm.nl_, + buffers, + force_move(self) + ); + } + else { + a_strm.nl_.async_read_some( + buffers, + force_move(self) + ); + } + } break; + default: + BOOST_ASSERT(false); + break; + } + } + + // finish read + template + void operator()( + Self& self, + error_code const& ec, + std::size_t bytes_transferred + ) { + self.complete(ec, bytes_transferred); + } +}; + +} // namespace detail + +template +template < + typename MutableBufferSequence, + typename CompletionToken +> +auto +stream::async_read_some( + MutableBufferSequence const& buffers, + CompletionToken&& token +) { + BOOST_ASSERT(impl_); + return + as::async_compose< + CompletionToken, + void(error_code, std::size_t) + >( + typename impl_type::template stream_read_some_op{ + impl_, + buffers + }, + token, + get_executor() + ); +} + + +} // namespace async_mqtt + +#endif // ASYNC_MQTT_UTIL_IMPL_STREAM_READ_HPP diff --git a/include/async_mqtt/impl/stream_underlying_handshake.hpp b/include/async_mqtt/impl/stream_underlying_handshake.hpp new file mode 100644 index 000000000..1d7e70986 --- /dev/null +++ b/include/async_mqtt/impl/stream_underlying_handshake.hpp @@ -0,0 +1,61 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_UTIL_IMPL_STREAM_UNDERLYING_HANDSHAKE_HPP) +#define ASYNC_MQTT_UTIL_IMPL_STREAM_UNDERLYING_HANDSHAKE_HPP + +#include +#include +#include +#include + +#include +#include + +namespace async_mqtt { + +namespace hana = boost::hana; + +namespace detail { + +template +template < + typename... Args +> +auto +stream_impl:: +async_underlying_handshake( + this_type_sp impl, + Args&&... args +) { + return layer_customize::async_handshake( + impl->next_layer(), + std::forward(args)... + ); +} + +} // namespace detail + +template +template < + typename... Args +> +auto +stream::async_underlying_handshake( + Args&&... args +) { + BOOST_ASSERT(impl_); + + return impl_type::async_underlying_handshake( + impl_, + std::forward(args)... + ); +} + + +} // namespace async_mqtt + +#endif // ASYNC_MQTT_UTIL_IMPL_STREAM_UNDERLYING_HANDSHAKE_HPP diff --git a/include/async_mqtt/util/impl/stream_write_packet.hpp b/include/async_mqtt/impl/stream_write_packet.hpp similarity index 98% rename from include/async_mqtt/util/impl/stream_write_packet.hpp rename to include/async_mqtt/impl/stream_write_packet.hpp index d21a11591..2c1ae2bba 100644 --- a/include/async_mqtt/util/impl/stream_write_packet.hpp +++ b/include/async_mqtt/impl/stream_write_packet.hpp @@ -7,7 +7,8 @@ #if !defined(ASYNC_MQTT_IMPL_STREAM_WRITE_PACKET_HPP) #define ASYNC_MQTT_IMPL_STREAM_WRITE_PACKET_HPP -#include +#include +#include namespace async_mqtt { diff --git a/include/async_mqtt/predefined_layer/customized_basic_stream.hpp b/include/async_mqtt/predefined_layer/customized_basic_stream.hpp index 8f0a0e46e..63f9bd6d9 100644 --- a/include/async_mqtt/predefined_layer/customized_basic_stream.hpp +++ b/include/async_mqtt/predefined_layer/customized_basic_stream.hpp @@ -9,7 +9,7 @@ #include -#include +#include #include namespace async_mqtt { @@ -34,6 +34,114 @@ namespace as = boost::asio; */ template struct layer_customize> { + template < + typename CompletionToken + > + static auto + async_handshake( + as::basic_stream_socket& stream, + std::string_view host, + std::string_view port, + CompletionToken&& token + ) { + return + as::async_compose< + CompletionToken, + void(error_code) + >( + handshake_op{ + stream, + host, + port + }, + token, + stream + ); + } + + struct handshake_op { + handshake_op( + as::basic_stream_socket& stream, + std::string_view host, + std::string_view port + ):stream{stream}, + host{host}, + port{port} + {} + + as::basic_stream_socket& stream; + std::string host; + std::string port; + enum { dispatch, resolve, connect, complete } state = dispatch; + + template + void operator()( + Self& self + ) { + if (state == dispatch) { + state = resolve; + auto& a_stream{stream}; + as::dispatch( + a_stream.get_executor(), + force_move(self) + ); + } + else { + BOOST_ASSERT(state == resolve); + state = connect; + auto res = std::make_shared(stream.get_executor()); + auto a_host{host}; + auto a_port{port}; + res->async_resolve( + a_host, + a_port, + as::consign( + force_move(self), + res + ) + ); + } + } + + struct default_connect_condition { + template + bool operator()(error_code const&, Endpoint const&) { + return true; + } + }; + + template + void operator()( + Self& self, + error_code ec, + as::ip::tcp::resolver::results_type eps + ) { + BOOST_ASSERT(state == connect); + state = complete; + if (ec) { + self.complete(ec); + return; + } + auto& a_stream{stream}; + as::async_connect( + a_stream, + eps, + default_connect_condition(), + force_move(self) + ); + } + + template + void operator()( + Self& self, + error_code ec, + as::ip::tcp::endpoint /*unused*/ + ) { + BOOST_ASSERT(state == complete); + self.complete(ec); + } + }; + template < typename CompletionToken > diff --git a/include/async_mqtt/predefined_layer/customized_ssl_stream.hpp b/include/async_mqtt/predefined_layer/customized_ssl_stream.hpp index 648338f1f..4ce2e83c6 100644 --- a/include/async_mqtt/predefined_layer/customized_ssl_stream.hpp +++ b/include/async_mqtt/predefined_layer/customized_ssl_stream.hpp @@ -10,7 +10,7 @@ #include #include -#include +#include #include /// @file @@ -34,6 +34,97 @@ static constexpr auto shutdown_timeout = std::chrono::seconds(3); */ template struct layer_customize> { + template < + typename CompletionToken = as::default_completion_token_t::executor_type> + > + static auto + async_handshake( + as::ssl::stream& stream, + std::string_view host, + std::string_view port, + CompletionToken&& token = as::default_completion_token_t::executor_type>{} + ) { + return + as::async_compose< + CompletionToken, + void(error_code) + >( + handshake_op{ + stream, + host, + port + }, + token, + stream + ); + } + + struct handshake_op { + handshake_op( + as::ssl::stream& stream, + std::string_view host, + std::string_view port + ):stream{stream}, + host{host}, + port{port} + {} + + as::ssl::stream& stream; + std::string host; + std::string port; + enum { dispatch, under, handshake, complete } state = dispatch; + + template + void operator()( + Self& self + ) { + if (state == dispatch) { + state = under; + auto& a_stream{stream}; + as::dispatch( + a_stream.get_executor(), + force_move(self) + ); + } + else { + BOOST_ASSERT(state == under); + state = handshake; + auto& a_stream{stream}; + auto a_host{host}; + auto a_port{port}; + layer_customize::async_handshake( + a_stream.next_layer(), + a_host, + a_port, + force_move(self) + ); + } + } + + template + void operator()( + Self& self, + error_code ec + ) { + if (state == handshake) { + state = complete; + if (ec) { + self.complete(ec); + return; + } + auto& a_stream{stream}; + a_stream.async_handshake( + as::ssl::stream_base::client, + force_move(self) + ); + } + else { + BOOST_ASSERT(state == complete); + self.complete(ec); + } + } + }; + template < typename CompletionToken > diff --git a/include/async_mqtt/predefined_layer/customized_websocket_stream.hpp b/include/async_mqtt/predefined_layer/customized_websocket_stream.hpp index 62d59cff0..0e35534c2 100644 --- a/include/async_mqtt/predefined_layer/customized_websocket_stream.hpp +++ b/include/async_mqtt/predefined_layer/customized_websocket_stream.hpp @@ -10,7 +10,7 @@ #include #include -#include +#include #include /// @file @@ -46,6 +46,133 @@ struct layer_customize> { ); } + // async_handshake + + template < + typename CompletionToken = as::default_completion_token_t::executor_type> + > + static auto + async_handshake( + bs::websocket::stream& stream, + std::string_view host, + std::string_view port, + std::string_view path, + CompletionToken&& token = as::default_completion_token_t::executor_type>{} + ) { + return + as::async_compose< + CompletionToken, + void(error_code) + >( + handshake_op{ + stream, + host, + port, + path + }, + token, + stream + ); + } + + template < + typename CompletionToken + > + static auto + async_handshake( + bs::websocket::stream& stream, + std::string_view host, + std::string_view port, + CompletionToken&& token + ) { + return + as::async_compose< + CompletionToken, + void(error_code) + >( + handshake_op{ + stream, + host, + port, + "/" + }, + token, + stream + ); + } + + struct handshake_op { + handshake_op( + bs::websocket::stream& stream, + std::string_view host, + std::string_view port, + std::string_view path + ):stream{stream}, + host{host}, + port{port}, + path{path} + {} + + bs::websocket::stream& stream; + std::string host; + std::string port; + std::string path; + enum {dispatch, under, handshake, complete} state = dispatch; + + template + void operator()( + Self& self + ) { + if (state == dispatch) { + state = under; + auto& a_stream{stream}; + as::dispatch( + a_stream.get_executor(), + force_move(self) + ); + } + else { + BOOST_ASSERT(state == under); + state = handshake; + auto& a_stream{stream}; + auto a_host{host}; + auto a_port{port}; + layer_customize::async_handshake( + a_stream.next_layer(), + a_host, + a_port, + force_move(self) + ); + } + } + + template + void operator()( + Self& self, + error_code ec + ) { + if (state == handshake) { + state = complete; + if (ec) { + self.complete(ec); + return; + } + auto& a_stream{stream}; + auto a_host{host}; + auto a_path{path}; + a_stream.async_handshake( + a_host, + a_path, + force_move(self) + ); + } + else { + BOOST_ASSERT(state == complete); + self.complete(ec); + } + } + }; + // async_write template < diff --git a/include/async_mqtt/predefined_layer/impl/mqtt_handshake.hpp b/include/async_mqtt/predefined_layer/impl/mqtt_handshake.hpp deleted file mode 100644 index 5180a368b..000000000 --- a/include/async_mqtt/predefined_layer/impl/mqtt_handshake.hpp +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright Takatoshi Kondo 2024 -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#if !defined(ASYNC_MQTT_PREDEFINED_LAYER_IMPL_MQTT_HANDSHAKE_HPP) -#define ASYNC_MQTT_PREDEFINED_LAYER_IMPL_MQTT_HANDSHAKE_HPP - -#include - -namespace async_mqtt { -namespace as = boost::asio; - -template < - typename Socket, - typename Executor -> -struct mqtt_handshake_op { - mqtt_handshake_op( - as::basic_stream_socket& layer, - std::string_view host, - std::string_view port - ):layer{layer}, - host{host}, - port{port} - {} - - as::basic_stream_socket& layer; - std::string host; - std::string port; - enum { dispatch, resolve, connect, complete } state = dispatch; - - template - void operator()( - Self& self - ) { - if (state == dispatch) { - state = resolve; - auto& a_layer{layer}; - as::dispatch( - a_layer.get_executor(), - force_move(self) - ); - } - else { - BOOST_ASSERT(state == resolve); - state = connect; - auto res = std::make_shared(layer.get_executor()); - auto a_host{host}; - auto a_port{port}; - res->async_resolve( - a_host, - a_port, - as::consign( - force_move(self), - res - ) - ); - } - } - - struct default_connect_condition { - template - bool operator()(error_code const&, Endpoint const&) { - return true; - } - }; - - template - void operator()( - Self& self, - error_code ec, - as::ip::tcp::resolver::results_type eps - ) { - BOOST_ASSERT(state == connect); - state = complete; - if (ec) { - self.complete(ec); - return; - } - auto& a_layer{layer}; - as::async_connect( - a_layer, - eps, - default_connect_condition(), - force_move(self) - ); - } - - template - void operator()( - Self& self, - error_code ec, - as::ip::tcp::endpoint /*unused*/ - ) { - BOOST_ASSERT(state == complete); - self.complete(ec); - } -}; - -template < - typename Socket, - typename Executor, - typename CompletionToken -> -auto -async_underlying_handshake( - as::basic_stream_socket& layer, - std::string_view host, - std::string_view port, - CompletionToken&& token -) { - return - as::async_compose< - CompletionToken, - void(error_code) - >( - mqtt_handshake_op{ - layer, - host, - port - }, - token, - layer - ); -} - -} // namespace async_mqtt - -#endif // ASYNC_MQTT_PREDEFINED_LAYER_IMPL_MQTT_HANDSHAKE_HPP diff --git a/include/async_mqtt/predefined_layer/impl/mqtts_handshake.hpp b/include/async_mqtt/predefined_layer/impl/mqtts_handshake.hpp deleted file mode 100644 index 3e5f4dc52..000000000 --- a/include/async_mqtt/predefined_layer/impl/mqtts_handshake.hpp +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright Takatoshi Kondo 2024 -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#if !defined(ASYNC_MQTT_PREDEFINED_LAYER_IMPL_MQTTS_HANDSHAKE_HPP) -#define ASYNC_MQTT_PREDEFINED_LAYER_IMPL_MQTTS_HANDSHAKE_HPP - -#include - -namespace async_mqtt { -namespace as = boost::asio; - -template -struct mqtts_handshake_op { - mqtts_handshake_op( - as::ssl::stream& layer, - std::string_view host, - std::string_view port - ):layer{layer}, - host{host}, - port{port} - {} - - as::ssl::stream& layer; - std::string host; - std::string port; - enum { dispatch, under, handshake, complete } state = dispatch; - - template - void operator()( - Self& self - ) { - if (state == dispatch) { - state = under; - auto& a_layer{layer}; - as::dispatch( - a_layer.get_executor(), - force_move(self) - ); - } - else { - BOOST_ASSERT(state == under); - state = handshake; - auto& a_layer{layer}; - auto a_host{host}; - auto a_port{port}; - async_underlying_handshake( - a_layer.next_layer(), - a_host, - a_port, - force_move(self) - ); - } - } - - template - void operator()( - Self& self, - error_code ec - ) { - if (state == handshake) { - state = complete; - if (ec) { - self.complete(ec); - return; - } - auto& a_layer{layer}; - a_layer.async_handshake( - as::ssl::stream_base::client, - force_move(self) - ); - } - else { - BOOST_ASSERT(state == complete); - self.complete(ec); - } - } -}; - -template < - typename NextLayer, - typename CompletionToken -> -auto -async_underlying_handshake( - as::ssl::stream& layer, - std::string_view host, - std::string_view port, - CompletionToken&& token -) { - return - as::async_compose< - CompletionToken, - void(error_code) - >( - mqtts_handshake_op{ - layer, - host, - port - }, - token, - layer - ); -} - -} // namespace async_mqtt - -#endif // ASYNC_MQTT_PREDEFINED_LAYER_IMPL_MQTTS_HANDSHAKE_HPP diff --git a/include/async_mqtt/predefined_layer/impl/ws_handshake.hpp b/include/async_mqtt/predefined_layer/impl/ws_handshake.hpp deleted file mode 100644 index d95d629d4..000000000 --- a/include/async_mqtt/predefined_layer/impl/ws_handshake.hpp +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright Takatoshi Kondo 2024 -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#if !defined(ASYNC_MQTT_PREDEFINED_LAYER_IMPL_WS_HANDSHAKE_HPP) -#define ASYNC_MQTT_PREDEFINED_LAYER_IMPL_WS_HANDSHAKE_HPP - -#include - -namespace async_mqtt { -namespace as = boost::asio; - -template -struct ws_handshake_op { - ws_handshake_op( - bs::websocket::stream& layer, - std::string_view host, - std::string_view port, - std::string_view path - ):layer{layer}, - host{host}, - port{port}, - path{path} - {} - - bs::websocket::stream& layer; - std::string host; - std::string port; - std::string path; - enum {dispatch, under, handshake, complete} state = dispatch; - - template - void operator()( - Self& self - ) { - if (state == dispatch) { - state = under; - auto& a_layer{layer}; - as::dispatch( - a_layer.get_executor(), - force_move(self) - ); - } - else { - BOOST_ASSERT(state == under); - state = handshake; - auto& a_layer{layer}; - auto a_host{host}; - auto a_port{port}; - async_underlying_handshake( - a_layer.next_layer(), - a_host, - a_port, - force_move(self) - ); - } - } - - template - void operator()( - Self& self, - error_code ec - ) { - if (state == handshake) { - state = complete; - if (ec) { - self.complete(ec); - return; - } - auto& a_layer{layer}; - auto a_host{host}; - auto a_path{path}; - a_layer.async_handshake( - a_host, - a_path, - force_move(self) - ); - } - else { - BOOST_ASSERT(state == complete); - self.complete(ec); - } - } -}; - -template < - typename NextLayer, - typename CompletionToken -> -auto -async_underlying_handshake( - bs::websocket::stream& layer, - std::string_view host, - std::string_view port, - std::string_view path, - CompletionToken&& token -) { - return - as::async_compose< - CompletionToken, - void(error_code) - >( - ws_handshake_op{ - layer, - host, - port, - path - }, - token, - layer - ); -} - -template < - typename NextLayer, - typename CompletionToken -> -auto -async_underlying_handshake( - bs::websocket::stream& layer, - std::string_view host, - std::string_view port, - CompletionToken&& token -) { - return - as::async_compose< - CompletionToken, - void(error_code) - >( - ws_handshake_op{ - layer, - host, - port, - "/" - }, - token, - layer - ); -} - - -} // namespace async_mqtt - -#endif // ASYNC_MQTT_PREDEFINED_LAYER_IMPL_WS_HANDSHAKE_HPP diff --git a/include/async_mqtt/predefined_layer/mqtt.hpp b/include/async_mqtt/predefined_layer/mqtt.hpp index c0d0f5d76..a74f9fcde 100644 --- a/include/async_mqtt/predefined_layer/mqtt.hpp +++ b/include/async_mqtt/predefined_layer/mqtt.hpp @@ -43,7 +43,6 @@ namespace protocol { */ using mqtt = as::basic_stream_socket; -} // namespace protocol /** * @ingroup predefined_layer_mqtt @@ -74,8 +73,8 @@ async_underlying_handshake( CompletionToken&& token = as::default_completion_token_t{} ); -} // namespace async_mqtt +} // namespace protocol -#include +} // namespace async_mqtt #endif // ASYNC_MQTT_PREDEFINED_LAYER_MQTT_HPP diff --git a/include/async_mqtt/predefined_layer/mqtts.hpp b/include/async_mqtt/predefined_layer/mqtts.hpp index 3188ba40d..c5724aa9f 100644 --- a/include/async_mqtt/predefined_layer/mqtts.hpp +++ b/include/async_mqtt/predefined_layer/mqtts.hpp @@ -33,7 +33,6 @@ namespace protocol { */ using mqtts = as::ssl::stream; -} // namespace protocol /** * @ingroup predefined_layer_mqtts @@ -65,8 +64,8 @@ async_underlying_handshake( >{} ); -} // namespace async_mqtt +} // namespace protocol -#include +} // namespace async_mqtt #endif // ASYNC_MQTT_PREDEFINED_LAYER_MQTTS_HPP diff --git a/include/async_mqtt/predefined_layer/ws.hpp b/include/async_mqtt/predefined_layer/ws.hpp index c236aa9be..031d5e544 100644 --- a/include/async_mqtt/predefined_layer/ws.hpp +++ b/include/async_mqtt/predefined_layer/ws.hpp @@ -28,9 +28,6 @@ namespace protocol { */ using ws = bs::websocket::stream; -} // namespace protocol - - /** * @ingroup predefined_layer_ws * @brief Websocket handshake @@ -94,8 +91,8 @@ async_underlying_handshake( >{} ); -} // namespace async_mqtt +} // namespace protocol -#include +} // namespace async_mqtt #endif // ASYNC_MQTT_PREDEFINED_LAYER_WS_HPP diff --git a/include/async_mqtt/buffer_to_packet_variant.hpp b/include/async_mqtt/protocol/buffer_to_packet_variant.hpp similarity index 51% rename from include/async_mqtt/buffer_to_packet_variant.hpp rename to include/async_mqtt/protocol/buffer_to_packet_variant.hpp index 226be74e5..073de8f07 100644 --- a/include/async_mqtt/buffer_to_packet_variant.hpp +++ b/include/async_mqtt/protocol/buffer_to_packet_variant.hpp @@ -4,12 +4,12 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_BUFFER_TO_PACKET_VARIANT_HPP) -#define ASYNC_MQTT_BUFFER_TO_PACKET_VARIANT_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_BUFFER_TO_PACKET_VARIANT_HPP) +#define ASYNC_MQTT_PROTOCOL_BUFFER_TO_PACKET_VARIANT_HPP -#include -#include -#include +#include +#include +#include #include namespace async_mqtt { @@ -20,10 +20,11 @@ namespace async_mqtt { * @param buf buffer contains packet bytes * @param ver protocol version to create packet * @param ec error_code for reporting error - * @return created basic_packet_variant + * @return if no error created basic_packet_variant, otherwise std::nullopt. */ template -basic_packet_variant buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); +std::optional> +buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); /** * @ingroup packet_variant @@ -31,10 +32,11 @@ basic_packet_variant buffer_to_basic_packet_variant(buffer buf, p * @param buf buffer contains packet bytes * @param ver protocol version to create packet * @param ec error_code for reporting error - * @return created packet_variant + * @return if no error created packet_variant, otherwise std::nullopt. */ -packet_variant buffer_to_packet_variant(buffer buf, protocol_version ver, error_code& ec); +std::optional +buffer_to_packet_variant(buffer buf, protocol_version ver, error_code& ec); } // namespace async_mqtt -#endif // ASYNC_MQTT_BUFFER_TO_PACKET_VARIANT_HPP +#endif // ASYNC_MQTT_PROTOCOL_BUFFER_TO_PACKET_VARIANT_HPP diff --git a/include/async_mqtt/protocol/connection.hpp b/include/async_mqtt/protocol/connection.hpp new file mode 100644 index 000000000..f5efea9c1 --- /dev/null +++ b/include/async_mqtt/protocol/connection.hpp @@ -0,0 +1,365 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_PROTOCOL_CONNECTION_HPP) +#define ASYNC_MQTT_PROTOCOL_CONNECTION_HPP + +#include +#include +#include + +#include +#include +#include +#include +#include +namespace async_mqtt { + +template +class basic_connection { + using impl_type = detail::basic_connection_impl; + +public: + basic_connection(protocol_version ver); + + virtual ~basic_connection() = default; + + /** + * @brief Packet sending request. + * + * @li If the packet cannot be sent, @ref on_error is called. + * @li If the packet is a @ref v3_1_1::pingreq_packet or @ref v5::pingreq_packet + * and Keep Alive is set, then @ref on_timer_op() for @ref timer_kind::pingreq_send is called. + * + * @param packet The packet to be sent. + */ + template + void + send(Packet packet); + + /** + * @brief Notify that some bytes of the packet have been received. + * + * All bytes will be processed in the input stream. + * + * @li If the packet is malformed or a protocol error occurs, @ref on_error is called. + * If the protocol_version is v5, then @ref on_send() is called with either + * a @ref v5::connack_packet or @ref v5::disconnect_packet . + * Finally, @ref on_close() is called. + * @li If a complete and valid packet is constructed, @ref on_receive() is called with + * the constructed packet. + * @li If the packet_id becomes reusable, @ref on_packet_id_release() is called with + * the packet_id. + * @li If a timer operation is required, @ref on_timer_op() is called. + * - If the connection acts as a client, a timer operation is required when a + * PINGRESP packet is received or a CONNACK packet with @ref property::server_keep_alive + * is received. + * - If the connection acts as a server, a timer operation is required whenever + * a packet is received, provided that Keep Alive is activated. + * @li If the bytes are incomplete for a packet, they are stored and processed during + * the next @ref recv() call. + * + * @param is Input stream containing some bytes of the packet. + */ + void + recv(std::istream& is); + + /** + * @brief Notify that a timer has been fired. + * + * Timer operations are requested through @ref on_timer_op(). + * Users are responsible for setting, resetting, or canceling the timer. When the timer fires, + * this function is expected to be called. + * + * @param kind The kind of timer. + */ + void + notify_timer_fired(timer_kind kind); + + /** + * @brief notify the connection is closed + * + * @li if the packet can't send @ref on_error is called. + * @li if the packet is @ref v3_1_1::pingreq_packet or @ref v5::pingreq_packet, + * and Keep Alive is set, then @ref on_timer_op() for @ref timer_kind::pingreq_send is called. + * + * @param packet The packet to send. + */ + void + notify_closed(); + + /** + * @brief Set the PINGREQ packet sending interval. + * + * @note By default, the PINGREQ packet sending interval is set to the same value as the + * CONNECT packet's keep-alive duration in seconds. If the CONNACK packet includes + * the Server Keep Alive property, its value (in seconds) is used instead. + * This function overrides the default value. + * + * @param duration If set to zero, the timer is disabled; otherwise, the specified duration is used. + * The minimum resolution is in milliseconds. + */ + void + set_pingreq_send_interval( + std::chrono::milliseconds duration + ); + + /** + * @brief Get the receive maximum vacancy for sending PUBLISH (QoS1, QoS2) packets. + * + * When the Receive Maximum property is included in a CONNECT/CONNACK packet received + * from the other side of the connection, the maximum number of inflight packets for + * sending is determined by that property. + * If no Receive Maximum property is provided, there is no limit. + * + * @note Even if the Receive Maximum property imposes no limit, the number of packet_id + * values is inherently limited. The maximum value is calculated as + * 2^(PacketIdBytes * 8) - 1. For example, if PacketIdBytes is 2 (the default in MQTT), + * the packet_id limit is 65535. + * + * @return If there is no limit, returns std::nullopt; otherwise, returns the current + * number of PUBLISH (QoS1, QoS2) packets that can be sent. + */ + std::optional + get_receive_maximum_vacancy_for_send() const; + + /** + * @brief set offline publish support + * \n This function should be called before async_send() call. + * @note By default offline publish is not supported. + * @param val if true, offline publish is supported, otherwise not supported + */ + void set_offline_publish(bool val); + + /** + * @brief auto publish response setter. + * @note By default not automatically sending. + * @param val if true, puback, pubrec, pubrel, and pubcomp are automatically sent + */ + void set_auto_pub_response(bool val); + + /** + * @brief auto publish response setter. + * @note By default not automatically sending. + * @param val if true, puback, pubrec, pubrel, and pubcomp are automatically sent + */ + void set_auto_ping_response(bool val); + + /** + * @brief auto map (allocate) topic alias on send PUBLISH packet. + * If all topic aliases are used, then overwrite by LRU algorithm. + * \n This function should be called before async_send() call. + * @note By default not automatically mapping. + * @param val if true, enable auto mapping, otherwise disable. + */ + void set_auto_map_topic_alias_send(bool val); + + /** + * @brief auto replace topic with corresponding topic alias on send PUBLISH packet. + * Registering topic alias need to do manually. + * \n This function should be called before async_send() call. + * @note By default not automatically replacing. + * @param val if true, enable auto replacing, otherwise disable. + */ + void set_auto_replace_topic_alias_send(bool val); + + /** + * @brief Set timeout for receiving PINGRESP packet after PINGREQ packet is sent. + * If the timer is fired, then the underlying layer is closed from the client side. + * If the protocol_version is v5, then send DISCONNECT packet with the reason code + * disconnect_reason_code::keep_alive_timeout automatically before underlying layer is closed. + * \n This function should be called before async_send() call. + * @note By default timeout is not set. + * @param duration if zero, timer is not set; otherwise duration is set. + * The minimum resolution is in milliseconds. + */ + void set_pingresp_recv_timeout(std::chrono::milliseconds duration); + + /** + * @brief acuire unique packet_id. + * @return std::optional::type> + * if acquired return acquired packet id, otherwise std::nullopt + */ + std::optional::type> acquire_unique_packet_id(); + + /** + * @brief register packet_id. + * @param packet_id packet_id to register + * @return If true, success, otherwise the packet_id has already been used. + */ + bool register_packet_id(typename basic_packet_id_type::type packet_id); + + /** + * @brief release packet_id. + * @param packet_id packet_id to release + * @return event list + */ + void + release_packet_id(typename basic_packet_id_type::type packet_id); + + /** + * @brief Get processed but not released QoS2 packet ids + * This function should be called after disconnection + * @return set of packet_ids + */ + std::set::type> get_qos2_publish_handled_pids() const; + + /** + * @brief Restore processed but not released QoS2 packet ids + * This function should be called before receive the first publish + * @param pids packet ids + */ + void restore_qos2_publish_handled_pids(std::set::type> pids); + + /** + * @brief restore packets + * the restored packets would automatically send when CONNACK packet is received + * @param pvs packets to restore + */ + void restore_packets( + std::vector> pvs + ); + + /** + * @brief get stored packets + * sotred packets mean inflight packets. + * @li PUBLISH packet (QoS1) not received PUBACK packet + * @li PUBLISH packet (QoS1) not received PUBREC packet + * @li PUBREL packet not received PUBCOMP packet + * @return std::vector> + */ + std::vector> get_stored_packets() const; + + /** + * @brief get MQTT protocol version + * @return MQTT protocol version + */ + protocol_version get_protocol_version() const; + + /** + * @brief Get MQTT PUBLISH packet processing status + * @param pid packet_id corresponding to the publish packet. + * @return If the packet is processing, then true, otherwise false. + */ + bool is_publish_processing(typename basic_packet_id_type::type pid) const; + + /** + * @brief Regulate publish packet for store + * If topic is empty, extract topic from topic alias, and remove topic alias + * Otherwise, remove topic alias if exists. + * @param packet packet to regulate + * @return error_code for repoting error + */ + error_code regulate_for_store( + v5::basic_publish_packet& packet + ) const; + + connection_status get_connection_status() const; + +#if defined(ASYNC_MQTT_MRDOCS) +public: +#else // defined(ASYNC_MQTT_MRDOCS) +private: +#endif // defined(ASYNC_MQTT_MRDOCS) + + /** + * @brief Handler for error notifications. + * + * This function is called when an error occurs in @ref send(), @ref recv(), @ref notify_timer_fired(), + * @ref set_pingreq_send_interval(), or @ref release_packet_id() **before these functions return**. + * + * @param ec The error_code indicating the error. + */ + virtual void on_error(error_code ec) = 0; + + /** + * @brief Handler for send requests. + * + * This function is called when a packet needs to be sent due to a situation arising in + * @ref send() or @ref recv() **before these functions return**. + * The implementation is responsible for sending the packet to the socket in its specific environment. + * If a send failure occurs and `release_packet_id_if_send_error` has a value, + * the implementation must call @ref release_packet_id() with the value of `release_packet_id_if_send_error`. + * + * @param packet The packet to send. You can retrieve a `ConstBufferSequence` using + * @ref basic_packet_variant::const_buffer_sequence(). + * If a continuous buffer is required, you can use + * to_string() to the result of + * @ref basic_packet_variant::const_buffer_sequence(). + * @param release_packet_id_if_send_error + * Specifies the packet_id to release if a send error occurs during implementation. + * If `std::nullopt`, no action is taken. + */ + virtual void on_send( + basic_packet_variant packet, + std::optional::type> + release_packet_id_if_send_error = std::nullopt + ) = 0; + + /** + * @brief Handler for packet_id release notifications. + * + * This function is called when a packet_id is released in + * @ref release_packet_id(), @ref send(), or @ref recv() **before these functions return**. + * After this notification, the packet_id becomes reusable. + * + * @param packet_id The packet_id that was released. + */ + virtual void on_packet_id_release( + typename basic_packet_id_type::type packet_id + ) = 0; + + /** + * @brief Handler for packet received notifications. + * + * This function is called when a complete packet is received in + * @ref recv() **before the function returns**. + * + * @param packet_id The packet_id associated with the received packet. + */ + virtual void on_receive( + basic_packet_variant packet + ) = 0; + + /** + * @brief Handler for timer operation requests. + * + * This function is called when a timer operation is required in situations arising from + * @ref set_pingreq_send_interval(), @ref send(), or @ref recv() **before these functions return**. + * + * @param timer_op The type of operation (set, reset, or cancel). + * @param kind The kind of timer. + */ + virtual void on_timer_op( + timer_op op, + timer_kind kind, + std::optional ms = std::nullopt + ) = 0; + + /** + * @brief Handler for socket closing requests. + * + * This function is called when a socket closing operation is required due to a situation arising in + * @ref notify_timer_fired(), @ref send(), or @ref recv() **before these functions return**. + */ + virtual void on_close() = 0; + +private: + friend class detail::basic_connection_impl; + std::shared_ptr impl_; +}; + +template +using connection = basic_connection; + +} // namespace async_mqtt + +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + +#endif // ASYNC_MQTT_PROTOCOL_CONNECTION_HPP diff --git a/include/async_mqtt/protocol/connection_fwd.hpp b/include/async_mqtt/protocol/connection_fwd.hpp new file mode 100644 index 000000000..1d08b1384 --- /dev/null +++ b/include/async_mqtt/protocol/connection_fwd.hpp @@ -0,0 +1,60 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_PROTOCOL_CONNECTION_FWD_HPP) +#define ASYNC_MQTT_PROTOCOL_CONNECTION_FWD_HPP + +#include // for std::size_t + +#include + +namespace async_mqtt { + +/** + * @ingroup connection + * @brief MQTT connection + * + * I/O independent MQTT protocol state machine. + * @li Manage connection status. + * @li Manage packet identifier. + * @li Manage Topic Alias. + * @li Manage resending packets on reconnection. + * @li Manage PINGREQ/PINGRESP timers. + * @li Manage automatic sending response packets. + * + * All requests and settings are implemented as synchronous functions. + * When caller's action is required, virtual function that is corresponding to + * the action is called **in the synchronous function before the function + * returns**. + * + * #### Thread Safety + * @li Distinct objects: Safe + * @li Shared objects: Unsafe + * + * @tparam Role role for packet sendable checking + * @tparam PacketIdBytes MQTT spec is 2. You can use `connection` for that. + */ +template +class basic_connection; + +/** + * @ingroup connection + * @related basic_connection + * @brief Type alias of basic_connection (PacketIdBytes=2). + * This is for typical usecase (e.g. MQTT client). + * + * #### Thread Safety + * @li Distinct objects: Safe + * @li Shared objects: Unsafe + * + * @tparam Role role for packet sendable checking + */ +template +using connection = basic_connection; + +} // namespace async_mqtt + +#endif // ASYNC_MQTT_PROTOCOL_CONNECTION_FWD_HPP diff --git a/include/async_mqtt/protocol/connection_status.hpp b/include/async_mqtt/protocol/connection_status.hpp new file mode 100644 index 000000000..86098f14b --- /dev/null +++ b/include/async_mqtt/protocol/connection_status.hpp @@ -0,0 +1,20 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_PROTOCOL_CONNECTION_STATUS_HPP) +#define ASYNC_MQTT_PROTOCOL_CONNECTION_STATUS_HPP + +namespace async_mqtt { + +enum class connection_status { + connecting, + connected, + disconnected, +}; + +} // namespace async_mqtt + +#endif // ASYNC_MQTT_PROTOCOL_CONNECTION_STATUS_HPP diff --git a/include/async_mqtt/protocol/detail/connection_impl_fwd.hpp b/include/async_mqtt/protocol/detail/connection_impl_fwd.hpp new file mode 100644 index 000000000..f6c7c9903 --- /dev/null +++ b/include/async_mqtt/protocol/detail/connection_impl_fwd.hpp @@ -0,0 +1,20 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_PROTOCOL_DETAIL_CONNECTION_IMPL_FWD_HPP) +#define ASYNC_MQTT_PROTOCOL_DETAIL_CONNECTION_IMPL_FWD_HPP + +#include // for std::size_t +#include + +namespace async_mqtt::detail { + +template +class basic_connection_impl; + +} // namespace async_mqtt::detail + +#endif // ASYNC_MQTT_PROTOCOL_DETAIL_CONNECTION_IMPL_FWD_HPP diff --git a/include/async_mqtt/error.hpp b/include/async_mqtt/protocol/error.hpp similarity index 90% rename from include/async_mqtt/error.hpp rename to include/async_mqtt/protocol/error.hpp index 806b2a130..80f96e951 100644 --- a/include/async_mqtt/error.hpp +++ b/include/async_mqtt/protocol/error.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_ERROR_HPP) -#define ASYNC_MQTT_ERROR_HPP +#if !defined(ASYNC_MQTT_ASYNC_MQTT_ERROR_HPP) +#define ASYNC_MQTT_ASYNC_MQTT_ERROR_HPP #include #include @@ -27,7 +27,7 @@ namespace async_mqtt { * @brief sys is a namespace alias of boost::system. * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -38,7 +38,7 @@ namespace sys = boost::system; * @brief errc is a namespace alias of boost::system::errc. * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -49,7 +49,7 @@ namespace errc = sys::errc; * @brief error_code is a type alias of boost::system::error_code. * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -60,7 +60,7 @@ using error_code = sys::error_code; * @brief system_error is a type alias of boost::system::system_error. * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -108,12 +108,13 @@ using system_error = sys::system_error; * @brief general error code * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ enum class mqtt_error { partial_error_detected = 0x0101, ///< Some entries have error on suback/unsuback (not an error) + packet_enqueued = 0x0102, ///< Due to receive_maximum, sent packet is enqueued (not an error) all_error_detected = 0x0180, ///< All entries have error on suback/unsuback packet_identifier_fully_used = 0x0181, ///< Packet Identifier fully used packet_identifier_conflict = 0x0182, ///< Packet Identifier conflict @@ -129,7 +130,7 @@ enum class mqtt_error { * @return mqtt_error string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -142,7 +143,7 @@ error_code make_error_code(mqtt_error v); * @return mqtt_error string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -156,7 +157,7 @@ constexpr char const* mqtt_error_to_string(mqtt_error v); * @return output stream * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -168,7 +169,7 @@ std::ostream& operator<<(std::ostream& o, mqtt_error v); * @return category * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -188,7 +189,7 @@ sys::error_category const& get_mqtt_error_category(); * See https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc385349256 * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -208,7 +209,7 @@ enum class connect_return_code : std::uint8_t { * @return connect_return_code string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -221,7 +222,7 @@ error_code make_error_code(connect_return_code v); * @return connect_return_code string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -235,7 +236,7 @@ constexpr char const* connect_return_code_to_string(connect_return_code v); * @return output stream * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -247,7 +248,7 @@ std::ostream& operator<<(std::ostream& o, connect_return_code v); * @return category * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -268,7 +269,7 @@ sys::error_category const& get_connect_return_code_category(); * \n See http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718071 * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -286,7 +287,7 @@ enum class suback_return_code : std::uint8_t { * @return suback_return_code string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -299,7 +300,7 @@ error_code make_error_code(suback_return_code v); * @return suback_return_code string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -313,7 +314,7 @@ constexpr char const* suback_return_code_to_string(suback_return_code v); * @return output stream * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -325,7 +326,7 @@ std::ostream& operator<<(std::ostream& o, suback_return_code v); * @return category * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -339,7 +340,7 @@ sys::error_category const& get_suback_return_code_category(); * @ingroup connack_v5 * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -350,7 +351,7 @@ sys::error_category const& get_suback_return_code_category(); * It is reported as CONNECT response via CONNACK packet * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -386,7 +387,7 @@ enum class connect_reason_code : std::uint8_t { * @return connect_reason_code string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -399,7 +400,7 @@ error_code make_error_code(connect_reason_code v); * @return connect_reason_code string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -413,7 +414,7 @@ constexpr char const* connect_reason_code_to_string(connect_reason_code v); * @return output stream * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -425,7 +426,7 @@ std::ostream& operator<<(std::ostream& o, connect_reason_code v); * @return category * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -445,7 +446,7 @@ sys::error_category const& get_connect_reason_code_category(); * It is reported via DISCONNECT * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -488,7 +489,7 @@ enum class disconnect_reason_code : std::uint8_t { * @return disconnect_reason_code string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -501,7 +502,7 @@ error_code make_error_code(disconnect_reason_code v); * @return disconnect_reason_code string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -515,7 +516,7 @@ constexpr char const* disconnect_reason_code_to_string(disconnect_reason_code v) * @return output stream * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -527,7 +528,7 @@ std::ostream& operator<<(std::ostream& o, disconnect_reason_code v); * @return category * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -547,7 +548,7 @@ sys::error_category const& get_disconnect_reason_code_category(); * It is reported as SUBSCRIBE response via SUBNACK packet * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -573,7 +574,7 @@ enum class suback_reason_code : std::uint8_t { * @return suback_reason_code string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -586,7 +587,7 @@ error_code make_error_code(suback_reason_code v); * @return suback_reason_code string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -600,7 +601,7 @@ constexpr char const* suback_reason_code_to_string(suback_reason_code v); * @return output stream * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -612,7 +613,7 @@ std::ostream& operator<<(std::ostream& o, suback_reason_code v); * @return category * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -632,7 +633,7 @@ sys::error_category const& get_suback_reason_code_category(); * It is reported as UNSUBSCRIBE response via UNSUBNACK packet * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -653,7 +654,7 @@ enum class unsuback_reason_code : std::uint8_t { * @return unsuback_reason_code string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -666,7 +667,7 @@ error_code make_error_code(unsuback_reason_code v); * @return unsuback_reason_code string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -680,7 +681,7 @@ constexpr char const* unsuback_reason_code_to_string(unsuback_reason_code v); * @return output stream * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -692,7 +693,7 @@ std::ostream& operator<<(std::ostream& o, unsuback_reason_code v); * @return category * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -712,7 +713,7 @@ sys::error_category const& get_unsuback_reason_code_category(); * It is reported as PUBLISH (QoS1) response via PUBACK packet * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -735,7 +736,7 @@ enum class puback_reason_code : std::uint8_t { * @return puback_reason_code string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -748,7 +749,7 @@ error_code make_error_code(puback_reason_code v); * @return puback_reason_code string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -762,7 +763,7 @@ constexpr char const* puback_reason_code_to_string(puback_reason_code v); * @return output stream * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -774,7 +775,7 @@ std::ostream& operator<<(std::ostream& o, puback_reason_code v); * @return category * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -794,7 +795,7 @@ sys::error_category const& get_puback_reason_code_category(); * It is reported as PUBLISH (QoS2) response via PUBREC packet * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -817,7 +818,7 @@ enum class pubrec_reason_code : std::uint8_t { * @return pubrec_reason_code string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -830,7 +831,7 @@ error_code make_error_code(pubrec_reason_code v); * @return pubrec_reason_code string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -844,7 +845,7 @@ constexpr char const* pubrec_reason_code_to_string(pubrec_reason_code v); * @return output stream * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -856,7 +857,7 @@ std::ostream& operator<<(std::ostream& o, pubrec_reason_code v); * @return category * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -875,7 +876,7 @@ sys::error_category const& get_pubrec_reason_code_category(); * It is reported as PUBREC response via PUBREL packet * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -891,7 +892,7 @@ enum class pubrel_reason_code : std::uint8_t { * @return pubrel_reason_code string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -904,7 +905,7 @@ error_code make_error_code(pubrel_reason_code v); * @return pubrel_reason_code string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -918,7 +919,7 @@ constexpr char const* pubrel_reason_code_to_string(pubrel_reason_code v); * @return output stream * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -930,7 +931,7 @@ std::ostream& operator<<(std::ostream& o, pubrel_reason_code v); * @return category * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -950,7 +951,7 @@ sys::error_category const& get_pubrel_reason_code_category(); * It is reported as PUBREL response via PUBCOMP packet * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -966,7 +967,7 @@ enum class pubcomp_reason_code : std::uint8_t { * @return pubcomp_reason_code string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -979,7 +980,7 @@ error_code make_error_code(pubcomp_reason_code v); * @return pubcomp_reason_code string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -993,7 +994,7 @@ constexpr char const* pubcomp_reason_code_to_string(pubcomp_reason_code v); * @return output stream * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1005,7 +1006,7 @@ std::ostream& operator<<(std::ostream& o, pubcomp_reason_code v); * @return category * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1024,7 +1025,7 @@ sys::error_category const& get_pubcomp_reason_code_category(); * It is reported via AUTH packet * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1041,7 +1042,7 @@ enum class auth_reason_code : std::uint8_t { * @return auth_reason_code string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1054,7 +1055,7 @@ error_code make_error_code(auth_reason_code v); * @return auth_reason_code string * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1068,7 +1069,7 @@ constexpr char const* auth_reason_code_to_string(auth_reason_code v); * @return output stream * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1080,7 +1081,7 @@ std::ostream& operator<<(std::ostream& o, auth_reason_code v); * @return category * * #### Requirements - * @li Header: async_mqtt/error.hpp + * @li Header: async_mqtt/protocol/error.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1119,6 +1120,6 @@ struct is_error_code_enum : public std::true_type } // namespace boost::system -#include +#include -#endif // ASYNC_MQTT_ERROR_HPP +#endif // ASYNC_MQTT_ASYNC_MQTT_ERROR_HPP diff --git a/include/async_mqtt/protocol/event/close.hpp b/include/async_mqtt/protocol/event/close.hpp new file mode 100644 index 000000000..cd0e570f8 --- /dev/null +++ b/include/async_mqtt/protocol/event/close.hpp @@ -0,0 +1,21 @@ +// Copyright Takatoshi Kondo 2024 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_PROTOCOL_EVENT_CLOSE_HPP) +#define ASYNC_MQTT_PROTOCOL_EVENT_CLOSE_HPP + +#include + +namespace async_mqtt::event { + +class close { +public: + constexpr close() = default; +}; + +} // namespace async_mqtt::event + +#endif // ASYNC_MQTT_PROTOCOL_EVENT_CLOSE_HPP diff --git a/include/async_mqtt/protocol/event/event_variant.hpp b/include/async_mqtt/protocol/event/event_variant.hpp new file mode 100644 index 000000000..76f3fc5a1 --- /dev/null +++ b/include/async_mqtt/protocol/event/event_variant.hpp @@ -0,0 +1,105 @@ +// Copyright Takatoshi Kondo 2024 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_PROTOCOL_EVENT_VARIANT_HPP) +#define ASYNC_MQTT_PROTOCOL_EVENT_VARIANT_HPP + +#include + +#include +#include +#include +#include +#include +#include + +namespace async_mqtt { + +/** + * @defgroup packet_variant variant class for all packets + * @ingroup packet + */ + +/** + * @defgroup packet_variant_detail implementation class + * @ingroup packet_variant + */ + +/** + * @ingroup packet_variant_detail + * @brief The varaint type of all packets and system_error + * + * #### Thread Safety + * @li Distinct objects: Safe + * @li Shared objects: Unsafe + * + * #### variants + * @li @ref std::monostate + * @li @ref v3_1_1::connect_packet + * @li @ref v3_1_1::connack_packet + * @li @ref v3_1_1::basic_publish_packet + * @li @ref v3_1_1::basic_puback_packet + * @li @ref v3_1_1::basic_pubrec_packet + * @li @ref v3_1_1::basic_pubrel_packet + * @li @ref v3_1_1::basic_pubcomp_packet + * @li @ref v3_1_1::basic_subscribe_packet + * @li @ref v3_1_1::basic_suback_packet + * @li @ref v3_1_1::basic_unsubscribe_packet + * @li @ref v3_1_1::basic_unsuback_packet + * @li @ref v3_1_1::pingreq_packet + * @li @ref v3_1_1::pingresp_packet + * @li @ref v3_1_1::disconnect_packet + * @li @ref v5::connect_packet + * @li @ref v5::connack_packet + * @li @ref v5::basic_publish_packet + * @li @ref v5::basic_puback_packet + * @li @ref v5::basic_pubrec_packet + * @li @ref v5::basic_pubrel_packet + * @li @ref v5::basic_pubcomp_packet + * @li @ref v5::basic_subscribe_packet + * @li @ref v5::basic_suback_packet + * @li @ref v5::basic_unsubscribe_packet + * @li @ref v5::basic_unsuback_packet + * @li @ref v5::pingreq_packet + * @li @ref v5::pingresp_packet + * @li @ref v5::disconnect_packet + * @li @ref v5::auth_packet + * + * #### Requirements + * @li Header: async_mqtt/packet/packet_variant.hpp + * @li Convenience header: async_mqtt/all.hpp + * + */ +template +using basic_event_variant = std::variant< + error_code, + event::basic_send, + event::basic_packet_id_released, + event::basic_packet_received, + event::timer, + event::close +>; + +/** + * @ingroup event_variant + * @related basic_event_variant + * @brief type alias of basic_event_variant (PacketIdBytes=2). + * + * #### Requirements + * @li Header: async_mqtt/packet/packet_variant.hpp + * @li Convenience header: async_mqtt/all.hpp + * + */ +using event_variant = basic_event_variant<2>; + +template +inline bool is_error(basic_event_variant const& ev) { + return ev.index() == 0; +} + +} // namespace async_mqtt + +#endif // ASYNC_MQTT_PROTOCOL_EVENT_VARIANT_HPP diff --git a/include/async_mqtt/protocol/event/event_variant_fwd.hpp b/include/async_mqtt/protocol/event/event_variant_fwd.hpp new file mode 100644 index 000000000..6000a1ebe --- /dev/null +++ b/include/async_mqtt/protocol/event/event_variant_fwd.hpp @@ -0,0 +1,86 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_PROTOCOL_EVENT_VARIANT_FWD_HPP) +#define ASYNC_MQTT_PROTOCOL_EVENT_VARIANT_FWD_HPP + +#include + +/** + * @defgroup packet_variant variant class for all packets + * @ingroup packet + */ + +/** + * @defgroup packet_variant_detail implementation class + * @ingroup packet_variant + */ + +namespace async_mqtt { + +/** + * @ingroup packet_variant_detail + * @brief The varaint type of all packets and system_error + * + * #### Thread Safety + * @li Distinct objects: Safe + * @li Shared objects: Unsafe + * + * #### variants + * @li @ref std::monostate + * @li @ref v3_1_1::connect_packet + * @li @ref v3_1_1::connack_packet + * @li @ref v3_1_1::basic_publish_packet + * @li @ref v3_1_1::basic_puback_packet + * @li @ref v3_1_1::basic_pubrec_packet + * @li @ref v3_1_1::basic_pubrel_packet + * @li @ref v3_1_1::basic_pubcomp_packet + * @li @ref v3_1_1::basic_subscribe_packet + * @li @ref v3_1_1::basic_suback_packet + * @li @ref v3_1_1::basic_unsubscribe_packet + * @li @ref v3_1_1::basic_unsuback_packet + * @li @ref v3_1_1::pingreq_packet + * @li @ref v3_1_1::pingresp_packet + * @li @ref v3_1_1::disconnect_packet + * @li @ref v5::connect_packet + * @li @ref v5::connack_packet + * @li @ref v5::basic_publish_packet + * @li @ref v5::basic_puback_packet + * @li @ref v5::basic_pubrec_packet + * @li @ref v5::basic_pubrel_packet + * @li @ref v5::basic_pubcomp_packet + * @li @ref v5::basic_subscribe_packet + * @li @ref v5::basic_suback_packet + * @li @ref v5::basic_unsubscribe_packet + * @li @ref v5::basic_unsuback_packet + * @li @ref v5::pingreq_packet + * @li @ref v5::pingresp_packet + * @li @ref v5::disconnect_packet + * @li @ref v5::auth_packet + * + * #### Requirements + * @li Header: async_mqtt/packet/packet_variant.hpp + * @li Convenience header: async_mqtt/all.hpp + * + */ +template +class basic_event_variant; + +/** + * @ingroup event_variant + * @related basic_event_variant + * @brief type alias of basic_event_variant (PacketIdBytes=2). + * + * #### Requirements + * @li Header: async_mqtt/packet/packet_variant.hpp + * @li Convenience header: async_mqtt/all.hpp + * + */ +using event_variant = basic_event_variant<2>; + +} // namespace async_mqtt + +#endif // ASYNC_MQTT_PROTOCOL_EVENT_VARIANT_FWD_HPP diff --git a/include/async_mqtt/protocol/event/packet_id_released.hpp b/include/async_mqtt/protocol/event/packet_id_released.hpp new file mode 100644 index 000000000..864276cb5 --- /dev/null +++ b/include/async_mqtt/protocol/event/packet_id_released.hpp @@ -0,0 +1,36 @@ +// Copyright Takatoshi Kondo 2024 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_PROTOCOL_EVENT_PACKET_ID_RELEASED_HPP) +#define ASYNC_MQTT_PROTOCOL_EVENT_PACKET_ID_RELEASED_HPP + +#include + +#include + +namespace async_mqtt::event { + +template +class basic_packet_id_released { +public: + basic_packet_id_released(typename basic_packet_id_type::type packet_id) + :packet_id_{packet_id} + { + } + + typename basic_packet_id_type::type get() const { + return packet_id_; + } + +private: + typename basic_packet_id_type::type packet_id_; +}; + +using packet_id_released = basic_packet_id_released<2>; + +} // namespace async_mqtt::event + +#endif // ASYNC_MQTT_PROTOCOL_EVENT_PACKET_ID_RELEASED_HPP diff --git a/include/async_mqtt/protocol/event/packet_received.hpp b/include/async_mqtt/protocol/event/packet_received.hpp new file mode 100644 index 000000000..9b84a1b2e --- /dev/null +++ b/include/async_mqtt/protocol/event/packet_received.hpp @@ -0,0 +1,42 @@ +// Copyright Takatoshi Kondo 2024 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_PROTOCOL_EVENT_PACKET_RECEIVED_HPP) +#define ASYNC_MQTT_PROTOCOL_EVENT_PACKET_RECEIVED_HPP + +#include + +#include + +namespace async_mqtt::event { + +template +class basic_packet_received { +public: + basic_packet_received( + basic_packet_variant packet + ) + :packet_{force_move(packet)} + { + } + + basic_packet_variant const& get() const { + return packet_; + } + + basic_packet_variant& get() { + return packet_; + } + +private: + basic_packet_variant packet_; +}; + +using packet_received = basic_packet_received<2>; + +} // namespace async_mqtt::event + +#endif // ASYNC_MQTT_PROTOCOL_EVENT_SEND_HPP diff --git a/include/async_mqtt/protocol/event/send.hpp b/include/async_mqtt/protocol/event/send.hpp new file mode 100644 index 000000000..066a41e29 --- /dev/null +++ b/include/async_mqtt/protocol/event/send.hpp @@ -0,0 +1,47 @@ +// Copyright Takatoshi Kondo 2024 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_PROTOCOL_EVENT_SEND_HPP) +#define ASYNC_MQTT_PROTOCOL_EVENT_SEND_HPP + +#include + +#include + +namespace async_mqtt::event { + +template +class basic_send { +public: + basic_send( + basic_packet_variant packet, + std::optional::type> + release_packet_id_if_send_error = std::nullopt + ) + :packet_{force_move(packet)}, + release_packet_id_if_send_error_{release_packet_id_if_send_error} + { + } + + basic_packet_variant get() const { + return packet_; + } + std::optional::type> + get_release_packet_id_if_send_error() const { + return release_packet_id_if_send_error_; + } + +private: + basic_packet_variant packet_; + std::optional::type> + release_packet_id_if_send_error_; +}; + +using send = basic_send<2>; + +} // namespace async_mqtt::event + +#endif // ASYNC_MQTT_PROTOCOL_EVENT_SEND_HPP diff --git a/include/async_mqtt/protocol/event/timer.hpp b/include/async_mqtt/protocol/event/timer.hpp new file mode 100644 index 000000000..876c2cd1e --- /dev/null +++ b/include/async_mqtt/protocol/event/timer.hpp @@ -0,0 +1,49 @@ +// Copyright Takatoshi Kondo 2024 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_PROTOCOL_EVENT_TIMER_HPP) +#define ASYNC_MQTT_PROTOCOL_EVENT_TIMER_HPP + +#include +#include +#include + +#include + +namespace async_mqtt::event { + +class timer { +public: + timer( + timer_op op, + timer_kind kind, + std::optional ms = std::nullopt + ) + :op_{op}, kind_{kind}, ms_{ms} + { + } + + timer_op get_op() const { + return op_; + } + + timer_kind get_kind() const { + return kind_; + } + + std::optional get_ms() const { + return ms_; + } + +private: + timer_op op_; + timer_kind kind_; + std::optional ms_; +}; + +} // namespace async_mqtt::event + +#endif // ASYNC_MQTT_PROTOCOL_EVENT_TIMER_HPP diff --git a/include/async_mqtt/impl/buffer_to_packet_variant.ipp b/include/async_mqtt/protocol/impl/buffer_to_packet_variant.ipp similarity index 74% rename from include/async_mqtt/impl/buffer_to_packet_variant.ipp rename to include/async_mqtt/protocol/impl/buffer_to_packet_variant.ipp index 384414263..319edbd6d 100644 --- a/include/async_mqtt/impl/buffer_to_packet_variant.ipp +++ b/include/async_mqtt/protocol/impl/buffer_to_packet_variant.ipp @@ -7,40 +7,40 @@ #if !defined(ASYNC_MQTT_IMPL_BUFFER_TO_PACKET_VARIANT_IPP) #define ASYNC_MQTT_IMPL_BUFFER_TO_PACKET_VARIANT_IPP -#include +#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include @@ -48,14 +48,15 @@ namespace async_mqtt { template ASYNC_MQTT_HEADER_ONLY_INLINE -basic_packet_variant buffer_to_basic_packet_variant( +std::optional> +buffer_to_basic_packet_variant( buffer buf, protocol_version ver, error_code& ec ) { if (buf.size() < 2) { ec = make_error_code(disconnect_reason_code::malformed_packet); - return basic_packet_variant{}; + return std::nullopt; } switch (get_control_packet_type(std::uint8_t(buf[0]))) { case control_packet_type::connect: @@ -73,7 +74,7 @@ basic_packet_variant buffer_to_basic_packet_variant( return v5::connect_packet(force_move(buf), ec); default: ec = make_error_code(connect_reason_code::unsupported_protocol_version); - return basic_packet_variant{}; + return std::nullopt; } } break; case control_packet_type::connack: @@ -84,7 +85,7 @@ basic_packet_variant buffer_to_basic_packet_variant( return v5::connack_packet(force_move(buf), ec); default: ec = make_error_code(disconnect_reason_code::protocol_error); - return basic_packet_variant{}; + return std::nullopt; } break; case control_packet_type::publish: @@ -95,7 +96,7 @@ basic_packet_variant buffer_to_basic_packet_variant( return v5::basic_publish_packet(force_move(buf), ec); default: ec = make_error_code(disconnect_reason_code::protocol_error); - return basic_packet_variant{}; + return std::nullopt; } break; case control_packet_type::puback: @@ -106,7 +107,7 @@ basic_packet_variant buffer_to_basic_packet_variant( return v5::basic_puback_packet(force_move(buf), ec); default: ec = make_error_code(disconnect_reason_code::protocol_error); - return basic_packet_variant{}; + return std::nullopt; } break; case control_packet_type::pubrec: @@ -117,7 +118,7 @@ basic_packet_variant buffer_to_basic_packet_variant( return v5::basic_pubrec_packet(force_move(buf), ec); default: ec = make_error_code(disconnect_reason_code::protocol_error); - return basic_packet_variant{}; + return std::nullopt; } break; case control_packet_type::pubrel: @@ -128,7 +129,7 @@ basic_packet_variant buffer_to_basic_packet_variant( return v5::basic_pubrel_packet(force_move(buf), ec); default: ec = make_error_code(disconnect_reason_code::protocol_error); - return basic_packet_variant{}; + return std::nullopt; } break; case control_packet_type::pubcomp: @@ -139,7 +140,7 @@ basic_packet_variant buffer_to_basic_packet_variant( return v5::basic_pubcomp_packet(force_move(buf), ec); default: ec = make_error_code(disconnect_reason_code::protocol_error); - return basic_packet_variant{}; + return std::nullopt; } break; case control_packet_type::subscribe: @@ -150,7 +151,7 @@ basic_packet_variant buffer_to_basic_packet_variant( return v5::basic_subscribe_packet(force_move(buf), ec); default: ec = make_error_code(disconnect_reason_code::protocol_error); - return basic_packet_variant{}; + return std::nullopt; } break; case control_packet_type::suback: @@ -161,7 +162,7 @@ basic_packet_variant buffer_to_basic_packet_variant( return v5::basic_suback_packet(force_move(buf), ec); default: ec = make_error_code(disconnect_reason_code::protocol_error); - return basic_packet_variant{}; + return std::nullopt; } break; case control_packet_type::unsubscribe: @@ -172,7 +173,7 @@ basic_packet_variant buffer_to_basic_packet_variant( return v5::basic_unsubscribe_packet(force_move(buf), ec); default: ec = make_error_code(disconnect_reason_code::protocol_error); - return basic_packet_variant{}; + return std::nullopt; } break; case control_packet_type::unsuback: @@ -183,7 +184,7 @@ basic_packet_variant buffer_to_basic_packet_variant( return v5::basic_unsuback_packet(force_move(buf), ec); default: ec = make_error_code(disconnect_reason_code::protocol_error); - return basic_packet_variant{}; + return std::nullopt; } break; case control_packet_type::pingreq: @@ -194,7 +195,7 @@ basic_packet_variant buffer_to_basic_packet_variant( return v5::pingreq_packet(force_move(buf), ec); default: ec = make_error_code(disconnect_reason_code::protocol_error); - return basic_packet_variant{}; + return std::nullopt; } break; case control_packet_type::pingresp: @@ -205,7 +206,7 @@ basic_packet_variant buffer_to_basic_packet_variant( return v5::pingresp_packet(force_move(buf), ec); default: ec = make_error_code(disconnect_reason_code::protocol_error); - return basic_packet_variant{}; + return std::nullopt; } break; case control_packet_type::disconnect: @@ -216,7 +217,7 @@ basic_packet_variant buffer_to_basic_packet_variant( return v5::disconnect_packet(force_move(buf), ec); default: ec = make_error_code(disconnect_reason_code::protocol_error); - return basic_packet_variant{}; + return std::nullopt; } break; case control_packet_type::auth: @@ -225,18 +226,18 @@ basic_packet_variant buffer_to_basic_packet_variant( return v5::auth_packet(force_move(buf), ec); default: ec = make_error_code(disconnect_reason_code::protocol_error); - return basic_packet_variant{}; + return std::nullopt; } break; default: break; } ec = make_error_code(disconnect_reason_code::malformed_packet); - return basic_packet_variant{}; + return std::nullopt; } ASYNC_MQTT_HEADER_ONLY_INLINE -packet_variant buffer_to_packet_variant(buffer buf, protocol_version ver, error_code& ec) { +std::optional buffer_to_packet_variant(buffer buf, protocol_version ver, error_code& ec) { return buffer_to_basic_packet_variant<2>(force_move(buf), ver, ec); } @@ -249,7 +250,7 @@ packet_variant buffer_to_packet_variant(buffer buf, protocol_version ver, error_ #define ASYNC_MQTT_INSTANTIATE_EACH(a_size) \ namespace async_mqtt { \ template \ -basic_packet_variant buffer_to_basic_packet_variant( \ +std::optional> buffer_to_basic_packet_variant( \ buffer, \ protocol_version, \ error_code& \ diff --git a/include/async_mqtt/protocol/impl/connection_impl.hpp b/include/async_mqtt/protocol/impl/connection_impl.hpp new file mode 100644 index 000000000..e123be6ca --- /dev/null +++ b/include/async_mqtt/protocol/impl/connection_impl.hpp @@ -0,0 +1,208 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_PROTOCOL_IMPL_CONNECTION_IMPL_HPP) +#define ASYNC_MQTT_PROTOCOL_IMPL_CONNECTION_IMPL_HPP + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace async_mqtt::detail { + +template +class basic_connection_impl { + using basic_pid_type = typename basic_packet_id_type::type; + +public: + explicit basic_connection_impl(protocol_version ver, basic_connection& con); + + void notify_handshaked(); + + template + void + send(Packet packet); + + void recv(std::istream& is); + + void + notify_timer_fired(timer_kind kind); + + void + notify_closed(); + + void + set_pingreq_send_interval( + std::chrono::milliseconds duration + ); + + std::optional get_receive_maximum_vacancy_for_send() const; + + void set_offline_publish(bool val); + + void set_auto_pub_response(bool val); + + void set_auto_ping_response(bool val); + + void set_auto_map_topic_alias_send(bool val); + + void set_auto_replace_topic_alias_send(bool val); + + void set_pingresp_recv_timeout(std::chrono::milliseconds duration); + + std::optional::type> acquire_unique_packet_id(); + + bool register_packet_id(typename basic_packet_id_type::type packet_id); + + void + release_packet_id(typename basic_packet_id_type::type packet_id); + + std::set::type> get_qos2_publish_handled_pids() const; + + void restore_qos2_publish_handled_pids(std::set::type> pids); + + void restore_packets( + std::vector> pvs + ); + + std::vector> get_stored_packets() const; + + protocol_version get_protocol_version() const; + + error_code regulate_for_store( + v5::basic_publish_packet& packet + ) const; + + bool is_publish_processing(typename basic_packet_id_type::type pid) const; + + connection_status get_connection_status() const; + +private: + template + bool + process_send_packet( + ActualPacket actual_packet + ); + + void + send_stored(); + + void + process_recv_packet(); + + void + initialize(bool is_client); + + std::optional + validate_topic_alias(std::optional ta_opt); + + bool + validate_topic_alias_range(topic_alias_type ta); + + bool + validate_maximum_packet_size(std::size_t size); + + std::optional + static get_topic_alias(properties const& props); + + static constexpr bool can_send_as_client(role r) { + return + static_cast(r) & + static_cast(role::client); + } + static constexpr bool can_send_as_server(role r) { + return + static_cast(r) & + static_cast(role::server); + } + +private: + basic_connection& con_; + protocol_version protocol_version_; + + packet_id_manager pid_man_; + std::set pid_suback_; + std::set pid_unsuback_; + std::set pid_puback_; + std::set pid_pubrec_; + std::set pid_pubcomp_; + + bool need_store_ = false; + store store_; + + bool offline_publish_ = false; + bool auto_pub_response_ = false; + bool auto_ping_response_ = false; + + bool auto_map_topic_alias_send_ = false; + bool auto_replace_topic_alias_send_ = false; + std::optional topic_alias_send_; + std::optional topic_alias_recv_; + + std::optional publish_send_max_; + std::optional publish_recv_max_; + receive_maximum_type publish_send_count_{0}; + + std::set publish_recv_; + + std::uint32_t maximum_packet_size_send_{packet_size_no_limit}; + std::uint32_t maximum_packet_size_recv_{packet_size_no_limit}; + + connection_status status_{connection_status::disconnected}; + + std::optional pingreq_send_interval_ms_; + std::optional pingreq_recv_timeout_ms_; + std::optional pingresp_recv_timeout_ms_; + + std::set qos2_publish_handled_; + std::set qos2_publish_processing_; + + struct error_packet { + error_packet(error_code ec) + :ec{ec} {} + error_packet(buffer packet) + :packet{force_move(packet)} {} + + error_code ec; + buffer packet; + }; + + class recv_packet_builder { + public: + void recv(std::istream& is); + error_packet front() const; + void pop_front(); + bool empty() const; + void initialize(); + private: + enum class read_state{fixed_header, remaining_length, payload} read_state_ = read_state::fixed_header; + std::size_t remaining_length_ = 0; + std::size_t multiplier_ = 1; + static_vector header_remaining_length_buf_; + std::shared_ptr raw_buf_; + std::size_t raw_buf_size_ = 0; + char* raw_buf_ptr_ = nullptr; + std::deque read_packets_; + }; + + recv_packet_builder rpb_; + bool is_client_ = true; +}; + +} // namespace async_mqtt::detail + +#endif // ASYNC_MQTT_PROTOCOL_IMPL_CONNECTION_IMPL_HPP diff --git a/include/async_mqtt/protocol/impl/connection_impl.ipp b/include/async_mqtt/protocol/impl/connection_impl.ipp new file mode 100644 index 000000000..bf38de8ee --- /dev/null +++ b/include/async_mqtt/protocol/impl/connection_impl.ipp @@ -0,0 +1,1647 @@ +// Copyright Takatoshi Kondo 2024 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_PROTOCOL_IMPL_CONNECTION_IMPL_IPP) +#define ASYNC_MQTT_PROTOCOL_IMPL_CONNECTION_IMPL_IPP + +#include +#include + +#include +#include +#include +#include +#include + +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + +namespace async_mqtt { + +namespace detail { + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection_impl::recv_packet_builder:: +recv(std::istream& is) { + BOOST_ASSERT(is); + auto size = static_cast(is.rdbuf()->in_avail()); + while (size != 0) { + switch (read_state_) { + case read_state::fixed_header: { + char fixed_header; + auto ret = is.readsome(&fixed_header, 1); + BOOST_ASSERT(ret == 1); + --size; + header_remaining_length_buf_.push_back(fixed_header); + read_state_ = read_state::remaining_length; + } break; + case read_state::remaining_length: { + while (size != 0) { + char encoded_byte; + auto ret = is.readsome(&encoded_byte, 1); + BOOST_ASSERT(ret == 1); + --size; + header_remaining_length_buf_.push_back(encoded_byte); + remaining_length_ += (std::uint8_t(encoded_byte) & 0b0111'1111) * multiplier_; + multiplier_ *= 128; + if ((encoded_byte & 0b1000'0000) == 0) { + raw_buf_size_ = header_remaining_length_buf_.size() + remaining_length_; + raw_buf_ = make_shared_ptr_char_array(raw_buf_size_); + raw_buf_ptr_ = raw_buf_.get(); + std::copy_n( + header_remaining_length_buf_.data(), + header_remaining_length_buf_.size(), + raw_buf_ptr_ + ); + raw_buf_ptr_ += header_remaining_length_buf_.size(); + if (remaining_length_ == 0) { + auto ptr = raw_buf_.get(); + read_packets_.emplace_back( + buffer{ptr, raw_buf_size_, force_move(raw_buf_)} + ); + initialize(); + return; + } + else { + read_state_ = read_state::payload; + } + break; + } + if (multiplier_ == 128 * 128 * 128 * 128) { + read_packets_.emplace_back(make_error_code(disconnect_reason_code::packet_too_large)); + initialize(); + return; + } + } + if (read_state_ != read_state::payload) { + return; + } + } break; + case read_state::payload: { + auto copied = is.readsome(raw_buf_ptr_, static_cast(remaining_length_)); + BOOST_ASSERT(copied > 0); + auto copied_size = static_cast(copied); + size -= copied_size; + if (copied_size == remaining_length_) { + auto ptr = raw_buf_.get(); + read_packets_.emplace_back( + buffer{ptr, raw_buf_size_, force_move(raw_buf_)} + ); + initialize(); + } + else { + raw_buf_ptr_ += copied_size; + remaining_length_ -= copied_size; + return; + } + } break; + } + } +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +typename basic_connection_impl::error_packet +basic_connection_impl::recv_packet_builder:: +front() const { + return read_packets_.front(); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection_impl::recv_packet_builder:: +pop_front() { + read_packets_.pop_front(); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +bool +basic_connection_impl::recv_packet_builder:: +empty() const { + return read_packets_.empty(); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection_impl::recv_packet_builder:: +initialize() { + read_state_ = read_state::fixed_header; + header_remaining_length_buf_.clear(); + remaining_length_ = 0; + multiplier_ = 1; + raw_buf_.reset(); + raw_buf_size_ = 0; + raw_buf_ptr_ = nullptr; +} + +// public +template +ASYNC_MQTT_HEADER_ONLY_INLINE +basic_connection_impl:: +basic_connection_impl( + protocol_version ver, + basic_connection& con +) + : con_{con}, + protocol_version_{ver} +{ +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection_impl:: +recv(std::istream& is) { + rpb_.recv(is); + return process_recv_packet(); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection_impl:: +notify_timer_fired(timer_kind kind) { + switch (kind) { + case timer_kind::pingreq_send: + switch (protocol_version_) { + case protocol_version::v3_1_1: + send(v3_1_1::pingreq_packet{}); + break; + case protocol_version::v5: + send(v5::pingreq_packet{}); + break; + default: + BOOST_ASSERT(false); + break; + } + break; + case timer_kind::pingreq_recv: + switch (protocol_version_) { + case protocol_version::v3_1_1: + con_.on_close(); + break; + case protocol_version::v5: + send( + v5::disconnect_packet{ + disconnect_reason_code::keep_alive_timeout, + properties{} + } + ); + break; + default: + BOOST_ASSERT(false); + break; + } + break; + case timer_kind::pingresp_recv: + switch (protocol_version_) { + case protocol_version::v3_1_1: + con_.on_close(); + break; + case protocol_version::v5: + send( + v5::disconnect_packet{ + disconnect_reason_code::keep_alive_timeout, + properties{} + } + ); + break; + default: + BOOST_ASSERT(false); + break; + } + break; + default: + BOOST_ASSERT(false); + break; + } +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection_impl:: +notify_closed() { + status_ = connection_status::disconnected; +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection_impl:: +set_pingreq_send_interval( + std::chrono::milliseconds duration +) { + if (duration == std::chrono::milliseconds::zero()) { + pingreq_send_interval_ms_.reset(); + con_.on_timer_op( + timer_op::cancel, + timer_kind::pingreq_send + ); + } + else { + pingreq_send_interval_ms_.emplace(duration); + con_.on_timer_op( + timer_op::reset, + timer_kind::pingreq_send, + duration + ); + } +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +std::optional +basic_connection_impl:: +get_receive_maximum_vacancy_for_send() const { + if (publish_send_max_) { + return *publish_send_max_ - publish_send_count_; + } + return std::nullopt; +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection_impl:: +set_auto_pub_response(bool val) { + auto_pub_response_ = val; +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection_impl:: +set_offline_publish(bool val) { + offline_publish_ = val; +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection_impl:: +set_auto_ping_response(bool val) { + auto_ping_response_ = val; +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection_impl:: +set_auto_map_topic_alias_send(bool val) { + auto_map_topic_alias_send_ = val; +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection_impl:: +set_auto_replace_topic_alias_send(bool val) { + auto_replace_topic_alias_send_ = val; +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection_impl:: +set_pingresp_recv_timeout(std::chrono::milliseconds duration) { + if (duration == std::chrono::milliseconds::zero()) { + pingresp_recv_timeout_ms_.reset(); + } + else { + pingresp_recv_timeout_ms_.emplace(duration); + } +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +std::optional::type> +basic_connection_impl:: +acquire_unique_packet_id() { + return pid_man_.acquire_unique_id(); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +bool +basic_connection_impl:: +register_packet_id( + typename basic_packet_id_type::type packet_id +) { + return pid_man_.register_id(packet_id); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection_impl:: +release_packet_id( + typename basic_packet_id_type::type packet_id +) { + if (pid_man_.is_used_id(packet_id)) { + pid_man_.release_id(packet_id); + con_.on_packet_id_release(packet_id); + } +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +std::set::type> +basic_connection_impl:: +get_qos2_publish_handled_pids() const { + return qos2_publish_handled_; +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection_impl:: +restore_qos2_publish_handled_pids( + std::set::type> pids +) { + qos2_publish_handled_ = force_move(pids); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection_impl:: +restore_packets( + std::vector> pvs +) { + auto add_publish = + [&](auto const& p) { + if (p.opts().get_qos() == qos::at_least_once) { + pid_puback_.insert(p.packet_id()); + } + else if (p.opts().get_qos() == qos::exactly_once) { + pid_pubrec_.insert(p.packet_id()); + } + }; + auto add_store = + [&] (auto&& p) { + if (pid_man_.register_id(p.packet_id())) { + store_.add(std::forward(p)); + } + else { + ASYNC_MQTT_LOG("mqtt_impl", error) + << "packet_id:" << p.packet_id() + << " has already been used. Skip it"; + } + }; + + for (auto& pv : pvs) { + pv.visit( + overload { + [&](v3_1_1::basic_publish_packet& p) { + add_publish(p); + add_store(force_move(p)); + }, + [&](v5::basic_publish_packet& p) { + add_publish(p); + add_store(force_move(p)); + }, + [&](v3_1_1::basic_pubrel_packet& p) { + pid_pubcomp_.insert(p.packet_id()); + add_store(force_move(p)); + }, + [&](v5::basic_pubrel_packet& p) { + pid_pubcomp_.insert(p.packet_id()); + add_store(force_move(p)); + } + } + ); + } +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +std::vector> +basic_connection_impl:: +get_stored_packets() const { + return store_.get_stored(); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +protocol_version +basic_connection_impl:: +get_protocol_version() const { + return protocol_version_; +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +bool +basic_connection_impl:: +is_publish_processing(typename basic_packet_id_type::type pid) const { + return qos2_publish_processing_.find(pid) != qos2_publish_processing_.end(); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +error_code +basic_connection_impl:: +regulate_for_store( + v5::basic_publish_packet& packet +) const { + if (packet.topic().empty()) { + if (auto ta_opt = + get_topic_alias(packet.props())) { + auto topic = topic_alias_send_->find_without_touch(*ta_opt); + if (topic.empty()) { + return make_error_code( + mqtt_error::packet_not_regulated + ); + } + packet.remove_topic_alias_add_topic(force_move(topic)); + } + else { + return make_error_code( + mqtt_error::packet_not_regulated + ); + } + } + else { + packet.remove_topic_alias(); + } + return error_code{}; +} + +// private + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection_impl:: +send_stored() { + store_.for_each( + [&](basic_store_packet_variant const& pv) mutable { + if (pv.size() > maximum_packet_size_send_) { + pid_man_.release_id(pv.packet_id()); + con_.on_packet_id_release(pv.packet_id()); + return false; + } + pv.visit( + // copy packet because the stored packets need to be preserved + // until receiving puback/pubrec/pubcomp + [&](auto const& p) { + con_.on_send(p); + } + ); + return true; + } + ); +} + + + + +// 1. ec, close (netowork level error, v3.1.1 packet error) +// 2. ec, send_disconnect, close (packet error after connected +// 3. ec, send_connack, close (packet error before connect) +// 4. packet_received, [auto_res,] [pingreq_recv_reset] + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection_impl:: +process_recv_packet() { + while (!rpb_.empty()) { + auto ep = rpb_.front(); + rpb_.pop_front(); + if (ep.ec) { + con_.on_error(ep.ec); + con_.on_close(); + status_ = connection_status::disconnected; + return; + } + auto& buf{ep.packet}; + + // Checking maximum_packet_size + if (buf.size() > maximum_packet_size_recv_) { + // on v3.1.1 maximum_packet_size_recv_ is initialized as packet_size_no_limit + BOOST_ASSERT(protocol_version_ == protocol_version::v5); + con_.on_error( + make_error_code( + disconnect_reason_code::packet_too_large + ) + ); + con_.on_send( + v5::disconnect_packet{ + disconnect_reason_code::packet_too_large + } + ); + return; + } + + error_code ec; + auto pv_opt = buffer_to_basic_packet_variant(buf, protocol_version_, ec); + if (ec) { + if (status_ == connection_status::disconnected && + ec.category() == get_connect_reason_code_category() + ) { + // first received connect packet with error + + // packet is error but connack needs to be sent + status_ = connection_status::connecting; + con_.on_error( + make_error_code( + static_cast(ec.value()) + ) + ); + if (protocol_version_ == protocol_version::v5) { + con_.on_send( + v5::connack_packet{ + false, // session_present + static_cast(ec.value()) + } + ); + } + else { + con_.on_send( + v3_1_1::connack_packet{ + false, // session_present + static_cast(ec.value()) + } + ); + } + } + else { + con_.on_error( + make_error_code( + static_cast(ec.value()) + ) + ); + if (status_ == connection_status::connected && + protocol_version_ == protocol_version::v5 + ) { + con_.on_send( + v5::disconnect_packet{ + static_cast(ec.value()) + } + ); + } + else { + con_.on_close(); + } + } + return; + } + + // no errors on packet creation phase + BOOST_ASSERT(pv_opt); + auto& pv{*pv_opt}; + ASYNC_MQTT_LOG("mqtt_impl", trace) + << "recv:" << pv; + auto result = pv.visit( + // do internal protocol processing + overload { + [&](v3_1_1::connect_packet& p) { + initialize(false); + protocol_version_ = protocol_version::v3_1_1; + status_ = connection_status::connecting; + auto keep_alive = p.keep_alive(); + if (keep_alive != 0) { + pingreq_recv_timeout_ms_.emplace( + std::chrono::milliseconds{ + keep_alive * 1000 * 3 / 2 + } + ); + } + if (p.clean_session()) { + need_store_ = false; + pid_puback_.clear(); + pid_pubrec_.clear(); + pid_pubcomp_.clear(); + } + else { + need_store_ = true; + } + con_.on_receive(pv); + return true; + }, + [&](v5::connect_packet& p) { + initialize(false); + protocol_version_ = protocol_version::v5; + status_ = connection_status::connecting; + auto keep_alive = p.keep_alive(); + if (keep_alive != 0) { + pingreq_recv_timeout_ms_.emplace( + std::chrono::milliseconds{ + keep_alive * 1000 * 3 / 2 + } + ); + } + if (p.clean_start()) { + pid_puback_.clear(); + pid_pubrec_.clear(); + pid_pubcomp_.clear(); + } + for (auto const& prop : p.props()) { + prop.visit( + overload { + [&](property::topic_alias_maximum const& p) { + if (p.val() > 0) { + topic_alias_send_.emplace(p.val()); + } + }, + [&](property::receive_maximum const& p) { + BOOST_ASSERT(p.val() != 0); + publish_send_max_.emplace(p.val()); + }, + [&](property::maximum_packet_size const& p) { + BOOST_ASSERT(p.val() != 0); + maximum_packet_size_send_ = p.val(); + }, + [&](property::session_expiry_interval const& p) { + if (p.val() != 0) { + need_store_ = true; + } + }, + [](auto const&) { + } + } + ); + } + con_.on_receive(p); + return true; + }, + [&](v3_1_1::connack_packet& p) { + if (p.code() == connect_return_code::accepted) { + status_ = connection_status::connected; + if (p.session_present()) { + send_stored(); + } + else { + pid_man_.clear(); + store_.clear(); + pid_puback_.clear(); + pid_pubrec_.clear(); + pid_pubcomp_.clear(); + } + } + con_.on_receive(p); + return true; + }, + [&](v5::connack_packet& p) { + if (p.code() == connect_reason_code::success) { + status_ = connection_status::connected; + for (auto const& prop : p.props()) { + prop.visit( + overload { + [&](property::topic_alias_maximum const& p) { + if (p.val() > 0) { + topic_alias_send_.emplace(p.val()); + } + }, + [&](property::receive_maximum const& p) { + BOOST_ASSERT(p.val() != 0); + publish_send_max_.emplace(p.val()); + }, + [&](property::maximum_packet_size const& p) { + BOOST_ASSERT(p.val() != 0); + maximum_packet_size_send_ = p.val(); + }, + [&](property::server_keep_alive const& p) { + if constexpr (can_send_as_client(Role)) { + set_pingreq_send_interval( + std::chrono::seconds{p.val()} + ); + } + }, + [](auto const&) { + } + } + ); + } + + if (p.session_present()) { + send_stored(); + } + else { + pid_man_.clear(); + store_.clear(); + pid_puback_.clear(); + pid_pubrec_.clear(); + pid_pubcomp_.clear(); + } + } + con_.on_receive(p); + return true; + }, + [&](v3_1_1::basic_publish_packet& p) { + switch (p.opts().get_qos()) { + case qos::at_most_once: + con_.on_receive(p); + break; + case qos::at_least_once: { + con_.on_receive(p); + auto packet_id = p.packet_id(); + if (auto_pub_response_ && + status_ == connection_status::connected) { + con_.on_send( + v3_1_1::basic_puback_packet(packet_id) + ); + } + } break; + case qos::exactly_once: { + auto packet_id = p.packet_id(); + bool already_handled = false; + if (qos2_publish_handled_.find(packet_id) == qos2_publish_handled_.end()) { + qos2_publish_handled_.emplace(packet_id); + } + else { + already_handled = true; + } + if (!already_handled) { + con_.on_receive(p); + } + if (status_ == connection_status::connected && + (auto_pub_response_ || + already_handled) // already_handled is true only if the pubrec packet + ) { // corresponding to the publish packet has already + con_.on_send( + v3_1_1::basic_pubrec_packet(packet_id) + ); + } + } break; + default: + break; + } + return true; + }, + [&](v5::basic_publish_packet& p) { + bool already_handled = false; + bool puback_send = false; + bool pubrec_send = false; + auto packet_id = p.packet_id(); + switch (p.opts().get_qos()) { + case qos::at_least_once: { + if (publish_recv_max_ && publish_recv_.size() == *publish_recv_max_) { + con_.on_error( + make_error_code( + disconnect_reason_code::receive_maximum_exceeded + ) + ); + con_.on_send( + v5::disconnect_packet{ + disconnect_reason_code::receive_maximum_exceeded + } + ); + return false; + } + publish_recv_.insert(packet_id); + if (auto_pub_response_ && status_ == connection_status::connected) { + puback_send = true; + } + } break; + case qos::exactly_once: { + auto packet_id = p.packet_id(); + if (publish_recv_max_ && publish_recv_.size() == *publish_recv_max_) { + con_.on_error( + make_error_code( + disconnect_reason_code::receive_maximum_exceeded + ) + ); + con_.on_send( + v5::disconnect_packet{ + disconnect_reason_code::receive_maximum_exceeded + } + ); + return false; + } + publish_recv_.insert(packet_id); + + if (qos2_publish_handled_.find(packet_id) == qos2_publish_handled_.end()) { + qos2_publish_handled_.emplace(packet_id); + } + else { + already_handled = true; + } + if (status_ == connection_status::connected && + (auto_pub_response_ || + already_handled) // already_handled is true only if the pubrec packet + ) { // corresponding to the publish packet has already + pubrec_send = true; + } + } break; + default: + break; + } + + if (p.topic().empty()) { + if (auto ta_opt = get_topic_alias(p.props())) { + // extract topic from topic_alias + if (*ta_opt == 0 || + !topic_alias_recv_ || // topic_alias_maximum is 0 + *ta_opt > topic_alias_recv_->max()) { + con_.on_error( + make_error_code( + disconnect_reason_code::topic_alias_invalid + ) + ); + con_.on_send( + v5::disconnect_packet{ + disconnect_reason_code::topic_alias_invalid + } + ); + return false; + } + BOOST_ASSERT(topic_alias_recv_); + auto topic = topic_alias_recv_->find(*ta_opt); + if (topic.empty()) { + ASYNC_MQTT_LOG("mqtt_impl", error) + << "no matching topic alias: " + << *ta_opt; + con_.on_error( + make_error_code( + disconnect_reason_code::topic_alias_invalid + ) + ); + con_.on_send( + v5::disconnect_packet{ + disconnect_reason_code::topic_alias_invalid + } + ); + return false; + } + else { + p.add_topic(force_move(topic)); + } + } + else { + ASYNC_MQTT_LOG("mqtt_impl", error) + << "topic is empty but topic_alias isn't set"; + con_.on_error( + make_error_code( + disconnect_reason_code::topic_alias_invalid + ) + ); + con_.on_send( + v5::disconnect_packet{ + disconnect_reason_code::topic_alias_invalid + } + ); + return false; + } + } + else { + if (auto ta_opt = get_topic_alias(p.props())) { + if (*ta_opt == 0 || + !topic_alias_recv_ || // topic_alias_maximum is 0 + *ta_opt > topic_alias_recv_->max()) { + con_.on_error( + make_error_code( + disconnect_reason_code::topic_alias_invalid + ) + ); + con_.on_send( + v5::disconnect_packet{ + disconnect_reason_code::topic_alias_invalid + } + ); + return false; + } + BOOST_ASSERT(topic_alias_recv_); + // extract topic from topic_alias + topic_alias_recv_->insert_or_update(p.topic(), *ta_opt); + } + } + if (!already_handled) { + con_.on_receive(p); + } + if (puback_send) { + con_.on_send( + v5::basic_puback_packet(packet_id) + ); + } + if (pubrec_send) { + con_.on_send( + v5::basic_pubrec_packet(packet_id) + ); + } + return true; + }, + [&](v3_1_1::basic_puback_packet& p) { + auto packet_id = p.packet_id(); + if (pid_puback_.erase(packet_id)) { + con_.on_receive(p); + store_.erase(response_packet::v3_1_1_puback, packet_id); + pid_man_.release_id(packet_id); + con_.on_packet_id_release(packet_id); + } + else { + ASYNC_MQTT_LOG("mqtt_impl", error) + << "invalid packet_id puback received packet_id:" << packet_id; + con_.on_error( + make_error_code( + disconnect_reason_code::protocol_error + ) + ); + con_.on_close(); + return false; + } + return true; + }, + [&](v5::basic_puback_packet& p) { + auto packet_id = p.packet_id(); + if (pid_puback_.erase(packet_id)) { + con_.on_receive(p); + store_.erase(response_packet::v5_puback, packet_id); + pid_man_.release_id(packet_id); + con_.on_packet_id_release(packet_id); + if (publish_send_max_) { + --publish_send_count_; + } + } + else { + ASYNC_MQTT_LOG("mqtt_impl", error) + << "invalid packet_id puback received packet_id:" << packet_id; + con_.on_error( + make_error_code( + disconnect_reason_code::protocol_error + ) + ); + con_.on_send( + v5::disconnect_packet{ + disconnect_reason_code::protocol_error + } + ); + return false; + } + return true; + }, + [&](v3_1_1::basic_pubrec_packet& p) { + auto packet_id = p.packet_id(); + if (pid_pubrec_.erase(packet_id)) { + store_.erase(response_packet::v3_1_1_pubrec, packet_id); + con_.on_receive(p); + if (auto_pub_response_ && status_ == connection_status::connected) { + con_.on_send( + v3_1_1::basic_pubrel_packet{packet_id} + ); + } + } + else { + ASYNC_MQTT_LOG("mqtt_impl", error) + << "invalid packet_id pubrec received packet_id:" << packet_id; + con_.on_error( + make_error_code( + disconnect_reason_code::protocol_error + ) + ); + con_.on_close(); + return false; + } + return true; + }, + [&](v5::basic_pubrec_packet& p) { + auto packet_id = p.packet_id(); + if (pid_pubrec_.erase(packet_id)) { + store_.erase(response_packet::v5_pubrec, packet_id); + con_.on_receive(p); + if (make_error_code(p.code())) { + pid_man_.release_id(packet_id); + con_.on_packet_id_release(packet_id); + qos2_publish_processing_.erase(packet_id); + if (publish_send_max_) { + --publish_send_count_; + } + } + else if (auto_pub_response_ && status_ == connection_status::connected) { + con_.on_send( + v5::basic_pubrel_packet{packet_id} + ); + } + } + else { + ASYNC_MQTT_LOG("mqtt_impl", error) + << "invalid packet_id pubrec received packet_id:" << packet_id; + con_.on_error( + make_error_code( + disconnect_reason_code::protocol_error + ) + ); + con_.on_send( + v5::disconnect_packet{ + disconnect_reason_code::protocol_error + } + ); + return false; + } + return true; + }, + [&](v3_1_1::basic_pubrel_packet& p) { + auto packet_id = p.packet_id(); + con_.on_receive(p); + qos2_publish_handled_.erase(packet_id); + if (auto_pub_response_ && status_ == connection_status::connected) { + con_.on_send( + v3_1_1::basic_pubcomp_packet{packet_id} + ); + } + return true; + }, + [&](v5::basic_pubrel_packet& p) { + auto packet_id = p.packet_id(); + con_.on_receive(p); + qos2_publish_handled_.erase(packet_id); + if (auto_pub_response_ && status_ == connection_status::connected) { + con_.on_send( + v5::basic_pubcomp_packet{packet_id} + ); + } + return true; + }, + [&](v3_1_1::basic_pubcomp_packet& p) { + auto packet_id = p.packet_id(); + if (pid_pubcomp_.erase(packet_id)) { + store_.erase(response_packet::v3_1_1_pubcomp, packet_id); + con_.on_receive(p); + pid_man_.release_id(packet_id); + con_.on_packet_id_release(packet_id); + qos2_publish_processing_.erase(packet_id); + } + else { + ASYNC_MQTT_LOG("mqtt_impl", error) + << "invalid packet_id pubcomp received packet_id:" << packet_id; + con_.on_error( + make_error_code( + disconnect_reason_code::protocol_error + ) + ); + con_.on_close(); + return false; + } + return true; + }, + [&](v5::basic_pubcomp_packet& p) { + auto packet_id = p.packet_id(); + if (pid_pubcomp_.erase(packet_id)) { + store_.erase(response_packet::v5_pubcomp, packet_id); + con_.on_receive(p); + pid_man_.release_id(packet_id); + con_.on_packet_id_release(packet_id); + qos2_publish_processing_.erase(packet_id); + if (publish_send_max_) { + --publish_send_count_; + } + } + else { + ASYNC_MQTT_LOG("mqtt_impl", error) + << "invalid packet_id pubcomp received packet_id:" << packet_id; + con_.on_error( + make_error_code( + disconnect_reason_code::protocol_error + ) + ); + con_.on_send( + v5::disconnect_packet{ + disconnect_reason_code::protocol_error + } + ); + return false; + } + return true; + }, + [&](v3_1_1::basic_subscribe_packet& p) { + con_.on_receive(p); + return true; + }, + [&](v5::basic_subscribe_packet& p) { + con_.on_receive(p); + return true; + }, + [&](v3_1_1::basic_suback_packet& p) { + auto packet_id = p.packet_id(); + if (pid_suback_.erase(packet_id)) { + con_.on_receive(p); + pid_man_.release_id(packet_id); + con_.on_packet_id_release(packet_id); + } + else { + ASYNC_MQTT_LOG("mqtt_impl", error) + << "invalid packet_id suback received packet_id:" << packet_id; + con_.on_error( + make_error_code( + disconnect_reason_code::protocol_error + ) + ); + con_.on_close(); + return false; + } + return true; + }, + [&](v5::basic_suback_packet& p) { + auto packet_id = p.packet_id(); + if (pid_suback_.erase(packet_id)) { + con_.on_receive(p); + pid_man_.release_id(packet_id); + con_.on_packet_id_release(packet_id); + } + else { + ASYNC_MQTT_LOG("mqtt_impl", error) + << "invalid packet_id suback received packet_id:" << packet_id; + con_.on_error( + make_error_code( + disconnect_reason_code::protocol_error + ) + ); + con_.on_send( + v5::disconnect_packet{ + disconnect_reason_code::protocol_error + } + ); + con_.on_close(); + return false; + } + return true; + }, + [&](v3_1_1::basic_unsubscribe_packet& p) { + con_.on_receive(p); + return true; + }, + [&](v5::basic_unsubscribe_packet& p) { + con_.on_receive(p); + return true; + }, + [&](v3_1_1::basic_unsuback_packet& p) { + auto packet_id = p.packet_id(); + if (pid_unsuback_.erase(packet_id)) { + con_.on_receive(p); + pid_man_.release_id(packet_id); + con_.on_packet_id_release(packet_id); + } + else { + ASYNC_MQTT_LOG("mqtt_impl", error) + << "invalid packet_id unsuback received packet_id:" << packet_id; + con_.on_error( + make_error_code( + disconnect_reason_code::protocol_error + ) + ); + con_.on_close(); + return false; + } + return true; + }, + [&](v5::basic_unsuback_packet& p) { + auto packet_id = p.packet_id(); + if (pid_unsuback_.erase(packet_id)) { + con_.on_receive(p); + pid_man_.release_id(packet_id); + con_.on_packet_id_release(packet_id); + } + else { + ASYNC_MQTT_LOG("mqtt_impl", error) + << "invalid packet_id unsuback received packet_id:" << packet_id; + con_.on_error( + make_error_code( + disconnect_reason_code::protocol_error + ) + ); + con_.on_send( + v5::disconnect_packet{ + disconnect_reason_code::protocol_error + } + ); + con_.on_close(); + return false; + } + return true; + }, + [&](v3_1_1::pingreq_packet& p) { + con_.on_receive(p); + if constexpr(can_send_as_server(Role)) { + if (auto_ping_response_ && + status_ == connection_status::connected) { + con_.on_send( + v3_1_1::pingresp_packet{} + ); + } + } + return true; + }, + [&](v5::pingreq_packet& p) { + con_.on_receive(p); + if constexpr(can_send_as_server(Role)) { + if (auto_ping_response_ && + status_ == connection_status::connected) { + con_.on_send( + v5::pingresp_packet{} + ); + } + } + return true; + }, + [&](v3_1_1::pingresp_packet& p) { + con_.on_receive(p); + con_.on_timer_op( + timer_op::cancel, + timer_kind::pingresp_recv + ); + return true; + }, + [&](v5::pingresp_packet& p) { + con_.on_receive(p); + con_.on_timer_op( + timer_op::cancel, + timer_kind::pingresp_recv + ); + return true; + }, + [&](v3_1_1::disconnect_packet& p) { + con_.on_receive(p); + status_ = connection_status::disconnected; + return true; + }, + [&](v5::disconnect_packet& p) { + con_.on_receive(p); + status_ = connection_status::disconnected; + return true; + }, + [&](v5::auth_packet& p) { + con_.on_receive(p); + return true; + }, + [&](std::monostate&) { + return false; + } + } + ); + + if (!result) return; + if (pingreq_recv_timeout_ms_) { + con_.on_timer_op( + timer_op::cancel, + timer_kind::pingreq_recv + ); + if (status_ == connection_status::connecting || + status_ == connection_status::connected + ) { + con_.on_timer_op( + timer_op::set, + timer_kind::pingreq_recv, + *pingreq_recv_timeout_ms_ + ); + } + } + } +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection_impl:: +initialize(bool is_client) { + publish_send_max_ = std::nullopt; + publish_recv_max_ = std::nullopt; + publish_send_count_ = 0; + topic_alias_send_ = std::nullopt; + topic_alias_recv_ = std::nullopt; + publish_recv_.clear(); + qos2_publish_processing_.clear(); + need_store_ = false; + pid_suback_.clear(); + pid_unsuback_.clear(); + is_client_ = is_client; +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +std::optional +basic_connection_impl:: +validate_topic_alias(std::optional ta_opt) { + if (!ta_opt) { + ASYNC_MQTT_LOG("mqtt_impl", error) + << "topic is empty but topic_alias isn't set"; + return std::nullopt; + } + + if (!validate_topic_alias_range(*ta_opt)) { + return std::nullopt; + } + + auto topic = topic_alias_send_->find(*ta_opt); + if (topic.empty()) { + ASYNC_MQTT_LOG("mqtt_impl", error) + << "topic is empty but topic_alias is not registered"; + return std::nullopt; + } + return topic; +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +bool +basic_connection_impl:: +validate_topic_alias_range(topic_alias_type ta) { + if (!topic_alias_send_) { + ASYNC_MQTT_LOG("mqtt_impl", error) + << "topic_alias is set but topic_alias_maximum is 0"; + return false; + } + if (ta == 0 || ta > topic_alias_send_->max()) { + ASYNC_MQTT_LOG("mqtt_impl", error) + << "topic_alias is set but out of range"; + return false; + } + return true; +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +bool +basic_connection_impl:: +validate_maximum_packet_size(std::size_t size) { + if (size > maximum_packet_size_send_) { + ASYNC_MQTT_LOG("mqtt_impl", error) + << "packet size over maximum_packet_size for sending"; + return false; + } + return true; +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +std::optional +basic_connection_impl:: +get_topic_alias(properties const& props) { + std::optional ta_opt; + for (auto const& prop : props) { + prop.visit( + overload { + [&](property::topic_alias const& p) { + ta_opt.emplace(p.val()); + }, + [](auto const&) { + } + } + ); + if (ta_opt) return ta_opt; + } + return ta_opt; +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +connection_status +basic_connection_impl:: +get_connection_status() const { + return status_; +} + +} // namespace detail + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +basic_connection:: +basic_connection(protocol_version ver) + : + impl_{ + std::make_shared( + ver, + *this + ) + } +{ +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection:: +recv(std::istream& is) { + BOOST_ASSERT(impl_); + return impl_->recv(is); +} + + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection:: +notify_timer_fired(timer_kind kind) { + BOOST_ASSERT(impl_); + return impl_->notify_timer_fired(kind); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection:: +notify_closed() { + BOOST_ASSERT(impl_); + return impl_->notify_closed(); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection:: +set_pingreq_send_interval( + std::chrono::milliseconds duration +) { + BOOST_ASSERT(impl_); + impl_->set_pingreq_send_interval(duration); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +std::optional +basic_connection:: +get_receive_maximum_vacancy_for_send() const { + BOOST_ASSERT(impl_); + return impl_->get_receive_maximum_vacancy_for_send(); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection:: +set_offline_publish( + bool val +) { + BOOST_ASSERT(impl_); + impl_->set_offline_publish(val); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection:: +set_auto_pub_response( + bool val +) { + BOOST_ASSERT(impl_); + impl_->set_auto_pub_response(val); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection:: +set_auto_ping_response( + bool val +) { + BOOST_ASSERT(impl_); + impl_->set_auto_ping_response(val); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection:: +set_auto_map_topic_alias_send( + bool val +) { + BOOST_ASSERT(impl_); + impl_->set_auto_map_topic_alias_send(val); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection:: +set_auto_replace_topic_alias_send( + bool val +) { + BOOST_ASSERT(impl_); + impl_->set_auto_replace_topic_alias_send(val); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection:: +set_pingresp_recv_timeout( + std::chrono::milliseconds duration +) { + BOOST_ASSERT(impl_); + impl_->set_pingresp_recv_timeout(duration); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +std::optional::type> +basic_connection:: +acquire_unique_packet_id() { + BOOST_ASSERT(impl_); + return impl_->acquire_unique_packet_id(); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +bool +basic_connection:: +register_packet_id( + typename basic_packet_id_type::type packet_id +) { + BOOST_ASSERT(impl_); + return impl_->register_packet_id(packet_id); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection:: +release_packet_id( + typename basic_packet_id_type::type packet_id +) { + BOOST_ASSERT(impl_); + return impl_->release_packet_id(packet_id); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +std::set::type> +basic_connection:: +get_qos2_publish_handled_pids() const { + BOOST_ASSERT(impl_); + return impl_->get_qos2_publish_handled_pids(); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection:: +restore_qos2_publish_handled_pids( + std::set::type> pids +) { + BOOST_ASSERT(impl_); + impl_->restore_qos2_publish_handled_pids(force_move(pids)); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection:: +restore_packets( + std::vector> pvs +) { + BOOST_ASSERT(impl_); + impl_->restore_packets(force_move(pvs)); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +std::vector> +basic_connection:: +get_stored_packets() const { + BOOST_ASSERT(impl_); + return impl_->get_stored_packets(); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +protocol_version +basic_connection:: +get_protocol_version() const { + BOOST_ASSERT(impl_); + return impl_->get_protocol_version(); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +bool +basic_connection:: +is_publish_processing(typename basic_packet_id_type::type pid) const { + BOOST_ASSERT(impl_); + return impl_->is_publish_processing(pid); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +error_code +basic_connection:: +regulate_for_store( + v5::basic_publish_packet& packet +) const { + BOOST_ASSERT(impl_); + return impl_->regulate_for_store(packet); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +connection_status +basic_connection:: +get_connection_status() const { + BOOST_ASSERT(impl_); + return impl_->get_connection_status(); +} + +} // namespace async_mqtt + +#include + +#endif // ASYNC_MQTT_PROTOCOL_IMPL_CONNECTION_IMPL_IPP diff --git a/include/async_mqtt/protocol/impl/connection_instantiate.hpp b/include/async_mqtt/protocol/impl/connection_instantiate.hpp new file mode 100644 index 000000000..801496644 --- /dev/null +++ b/include/async_mqtt/protocol/impl/connection_instantiate.hpp @@ -0,0 +1,39 @@ +// Copyright Takatoshi Kondo 2024 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_PROTOCOL_IMPL_CONNECTION_INSTANTIATE_HPP) +#define ASYNC_MQTT_PROTOCOL_IMPL_CONNECTION_INSTANTIATE_HPP + +#if defined(ASYNC_MQTT_SEPARATE_COMPILATION) + +#include + +#define ASYNC_MQTT_INSTANTIATE_EACH(a_role, a_size) \ +namespace async_mqtt { \ +namespace detail { \ +template \ +class basic_connection_impl; \ +} \ +template \ +class basic_connection; \ +} // namespace async_mqtt + +#define ASYNC_MQTT_PP_GENERATE(r, product) \ + BOOST_PP_EXPAND( \ + ASYNC_MQTT_INSTANTIATE_EACH \ + BOOST_PP_SEQ_TO_TUPLE( \ + product \ + ) \ + ) + +BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_ROLE)(ASYNC_MQTT_PP_SIZE)) + +#undef ASYNC_MQTT_PP_GENERATE +#undef ASYNC_MQTT_INSTANTIATE_EACH + +#endif // defined(ASYNC_MQTT_SEPARATE_COMPILATION) + +#endif // ASYNC_MQTT_PROTOCOL_IMPL_CONNECTION_INSTANTIATE_HPP diff --git a/include/async_mqtt/protocol/impl/connection_send.ipp b/include/async_mqtt/protocol/impl/connection_send.ipp new file mode 100644 index 000000000..20f76d8bf --- /dev/null +++ b/include/async_mqtt/protocol/impl/connection_send.ipp @@ -0,0 +1,690 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_PROTOCOL_IMPL_CONNECTION_SEND_IPP) +#define ASYNC_MQTT_PROTOCOL_IMPL_CONNECTION_SEND_IPP + +#include +#include +#include + +namespace async_mqtt { + +namespace detail { + +template +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection_impl:: +send(Packet packet) { + auto send_and_post_process = + [&](auto&& actual_packet) { + if (process_send_packet(actual_packet)) { + if constexpr(is_connack>()) { + // server send stored packets after connack sent + send_stored(); + } + if constexpr(Role == role::client || Role == role::any) { + if (is_client_ && pingreq_send_interval_ms_) { + if (status_ == connection_status::disconnected) return; + con_.on_timer_op( + timer_op::reset, + timer_kind::pingreq_send, + *pingreq_send_interval_ms_ + ); + } + } + } + }; + + if constexpr( + std::is_same_v, basic_packet_variant> || + std::is_same_v, basic_store_packet_variant> + ) { + force_move(packet).visit( + overload{ + [&](auto actual_packet) { + send_and_post_process(force_move(actual_packet)); + }, + [&](std::monostate const&) {} + } + ); + } + else { + send_and_post_process(std::forward(packet)); + } +} + +template +template +ASYNC_MQTT_HEADER_ONLY_INLINE +bool +basic_connection_impl:: +process_send_packet( + ActualPacket actual_packet +) { + std::optional::type> release_packet_id_if_send_error; + // MQTT protocol sendable packet check + if ( + !( + (can_send_as_client(Role) && is_client_sendable>()) || + (can_send_as_server(Role) && is_server_sendable>()) + ) + ) { + con_.on_error( + make_error_code( + mqtt_error::packet_not_allowed_to_send + ) + ); + return false; + } + + auto version_check = + [&] { + if (protocol_version_ == protocol_version::v3_1_1 && is_v3_1_1()) { + return true; + } + if (protocol_version_ == protocol_version::v5 && is_v5()) { + return true; + } + return false;; + }; + + // connection status check + if constexpr(is_connect()) { + if (status_ != connection_status::disconnected) { + con_.on_error( + make_error_code( + mqtt_error::packet_not_allowed_to_send + ) + ); + return false; + } + if (!version_check()) { + con_.on_error( + make_error_code( + mqtt_error::packet_not_allowed_to_send + ) + ); + return false; + } + } + else if constexpr(is_connack()) { + if (status_ != connection_status::connecting) { + con_.on_error( + make_error_code( + mqtt_error::packet_not_allowed_to_send + ) + ); + return false; + } + if (!version_check()) { + con_.on_error( + make_error_code( + mqtt_error::packet_not_allowed_to_send + ) + ); + return false; + } + } + else if constexpr(std::is_same_v) { + if (status_ == connection_status::disconnected) { + con_.on_error( + make_error_code( + mqtt_error::packet_not_allowed_to_send + ) + ); + return false; + } + if (!version_check()) { + con_.on_error( + make_error_code( + mqtt_error::packet_not_allowed_to_send + ) + ); + return false; + } + } + else { + if (status_ != connection_status::connected) { + if constexpr(!is_publish>()) { + con_.on_error( + make_error_code( + mqtt_error::packet_not_allowed_to_send + ) + ); + return false; + } + } + if (!version_check()) { + con_.on_error( + make_error_code( + mqtt_error::packet_not_allowed_to_send + ) + ); + return false; + } + } + + // sending process + bool topic_alias_validated = false; + + if (!validate_maximum_packet_size(actual_packet.size())) { + con_.on_error( + make_error_code( + mqtt_error::packet_not_allowed_to_send + ) + ); + if constexpr(own_packet_id>()) { + auto packet_id = actual_packet.packet_id(); + if (packet_id != 0) { + pid_man_.release_id(packet_id); + con_.on_packet_id_release(packet_id); + } + } + return false; + } + + if constexpr(std::is_same_v>) { + initialize(true); + status_ = connection_status::connecting; + auto keep_alive = actual_packet.keep_alive(); + if (keep_alive != 0 && !pingreq_send_interval_ms_) { + pingreq_send_interval_ms_.emplace(keep_alive * 1000); + } + if (actual_packet.clean_session()) { + pid_man_.clear(); + store_.clear(); + need_store_ = false; + pid_puback_.clear(); + pid_pubrec_.clear(); + pid_pubcomp_.clear(); + } + else { + need_store_ = true; + } + topic_alias_send_ = std::nullopt; + } + + if constexpr(std::is_same_v>) { + initialize(true); + status_ = connection_status::connecting; + auto keep_alive = actual_packet.keep_alive(); + if (keep_alive != 0 && !pingreq_send_interval_ms_) { + pingreq_send_interval_ms_.emplace(std::chrono::seconds{keep_alive}); + } + if (actual_packet.clean_start()) { + pid_man_.clear(); + store_.clear(); + pid_puback_.clear(); + pid_pubrec_.clear(); + pid_pubcomp_.clear(); + } + for (auto const& prop : actual_packet.props()) { + prop.visit( + overload { + [&](property::topic_alias_maximum const& p) { + if (p.val() != 0) { + topic_alias_recv_.emplace(p.val()); + } + }, + [&](property::receive_maximum const& p) { + BOOST_ASSERT(p.val() != 0); + publish_recv_max_.emplace(p.val()); + }, + [&](property::maximum_packet_size const& p) { + BOOST_ASSERT(p.val() != 0); + maximum_packet_size_recv_ = p.val(); + }, + [&](property::session_expiry_interval const& p) { + if (p.val() != 0) { + need_store_ = true; + } + }, + [](auto const&){} + } + ); + } + } + + if constexpr(std::is_same_v>) { + if (actual_packet.code() == connect_return_code::accepted) { + status_ = connection_status::connected; + } + else { + status_ = connection_status::disconnected; + } + } + + if constexpr(std::is_same_v>) { + if (actual_packet.code() == connect_reason_code::success) { + status_ = connection_status::connected; + for (auto const& prop : actual_packet.props()) { + prop.visit( + overload { + [&](property::topic_alias_maximum const& p) { + if (p.val() != 0) { + topic_alias_recv_.emplace(p.val()); + } + }, + [&](property::receive_maximum const& p) { + BOOST_ASSERT(p.val() != 0); + publish_recv_max_.emplace(p.val()); + }, + [&](property::maximum_packet_size const& p) { + BOOST_ASSERT(p.val() != 0); + maximum_packet_size_recv_ = p.val(); + }, + [](auto const&){} + } + ); + } + } + else { + status_ = connection_status::disconnected; + } + } + + // store publish/pubrel packet + if constexpr(is_publish>()) { + if (actual_packet.opts().get_qos() == qos::at_least_once || + actual_packet.opts().get_qos() == qos::exactly_once + ) { + auto packet_id = actual_packet.packet_id(); + // TBD use error report instead of assert + BOOST_ASSERT(pid_man_.is_used_id(packet_id)); + if (need_store_ && + ( + status_ != connection_status::disconnected || + offline_publish_ + ) + ) { + if constexpr(is_instance_of>::value) { + auto ta_opt = get_topic_alias(actual_packet.props()); + if (actual_packet.topic().empty()) { + auto topic_opt = validate_topic_alias(ta_opt); + if (!topic_opt) { + con_.on_error( + make_error_code( + mqtt_error::packet_not_allowed_to_send + ) + ); + if (packet_id != 0) { + pid_man_.release_id(packet_id); + con_.on_packet_id_release(packet_id); + } + return false; + } + topic_alias_validated = true; + auto props = actual_packet.props(); + auto it = props.cbegin(); + auto end = props.cend(); + for (; it != end; ++it) { + if (it->id() == property::id::topic_alias) { + props.erase(it); + break; + } + } + + auto store_packet = + ActualPacket( + packet_id, + force_move(*topic_opt), + actual_packet.payload_as_buffer(), + actual_packet.opts(), + force_move(props) + ); + if (!validate_maximum_packet_size(store_packet.size())) { + con_.on_error( + make_error_code( + mqtt_error::packet_not_allowed_to_send + ) + ); + if (packet_id != 0) { + pid_man_.release_id(packet_id); + con_.on_packet_id_release(packet_id); + } + return false; + } + // add new packet that doesn't have topic_aliass to store + // the original packet still use topic alias to send + store_packet.set_dup(true); + store_.add(force_move(store_packet)); + } + else { + auto props = actual_packet.props(); + auto it = props.cbegin(); + auto end = props.cend(); + for (; it != end; ++it) { + if (it->id() == property::id::topic_alias) { + props.erase(it); + break; + } + } + + auto store_packet = + ActualPacket( + packet_id, + actual_packet.topic(), + actual_packet.payload_as_buffer(), + actual_packet.opts(), + force_move(props) + ); + if (!validate_maximum_packet_size(store_packet.size())) { + con_.on_error( + make_error_code( + mqtt_error::packet_not_allowed_to_send + ) + ); + if (packet_id != 0) { + pid_man_.release_id(packet_id); + con_.on_packet_id_release(packet_id); + } + return false; + } + store_packet.set_dup(true); + store_.add(force_move(store_packet)); + } + } + else { + // v3_1_1 publish_packet + auto store_packet{actual_packet}; + store_packet.set_dup(true); + store_.add(force_move(store_packet)); + } + } + else { + // QoS1, 2 but not stored + release_packet_id_if_send_error.emplace(packet_id); + } + if (actual_packet.opts().get_qos() == qos::exactly_once) { + qos2_publish_processing_.insert(packet_id); + pid_pubrec_.insert(packet_id); + } + else { + pid_puback_.insert(packet_id); + } + } + } + + if constexpr(is_instance_of>::value) { + auto packet_id = actual_packet.packet_id(); + // apply topic_alias + auto ta_opt = get_topic_alias(actual_packet.props()); + if (actual_packet.topic().empty()) { + if (!topic_alias_validated && + !validate_topic_alias(ta_opt)) { + con_.on_error( + make_error_code( + mqtt_error::packet_not_allowed_to_send + ) + ); + if (packet_id != 0) { + pid_man_.release_id(packet_id); + con_.on_packet_id_release(packet_id); + } + return false; + } + // use topic_alias set by user + } + else { + if (ta_opt) { + if (validate_topic_alias_range(*ta_opt)) { + ASYNC_MQTT_LOG("mqtt_impl", trace) + << "topia alias : " + << actual_packet.topic() << " - " << *ta_opt + << " is registered." ; + BOOST_ASSERT(topic_alias_send_); + topic_alias_send_->insert_or_update(actual_packet.topic(), *ta_opt); + } + else { + auto packet_id = actual_packet.packet_id(); + con_.on_error( + make_error_code( + mqtt_error::packet_not_allowed_to_send + ) + ); + if (packet_id != 0) { + pid_man_.release_id(packet_id); + con_.on_packet_id_release(packet_id); + } + return false; + } + } + else if (auto_map_topic_alias_send_) { + if (topic_alias_send_) { + if (auto ta_opt = topic_alias_send_->find(actual_packet.topic())) { + ASYNC_MQTT_LOG("mqtt_impl", trace) + << "topia alias : " << actual_packet.topic() << " - " << *ta_opt + << " is found." ; + actual_packet.remove_topic_add_topic_alias(*ta_opt); + } + else { + auto lru_ta = topic_alias_send_->get_lru_alias(); + topic_alias_send_->insert_or_update(actual_packet.topic(), lru_ta); // remap topic alias + actual_packet.add_topic_alias(lru_ta); + } + } + } + else if (auto_replace_topic_alias_send_) { + if (topic_alias_send_) { + if (auto ta_opt = topic_alias_send_->find(actual_packet.topic())) { + ASYNC_MQTT_LOG("mqtt_impl", trace) + << "topia alias : " << actual_packet.topic() << " - " << *ta_opt + << " is found." ; + actual_packet.remove_topic_add_topic_alias(*ta_opt); + } + } + } + } + + // receive_maximum for sending + if (actual_packet.opts().get_qos() == qos::at_least_once || + actual_packet.opts().get_qos() == qos::exactly_once + ) { + if (publish_send_max_) { + if (publish_send_count_ == *publish_send_max_) { + con_.on_error( + make_error_code( + disconnect_reason_code::receive_maximum_exceeded + ) + ); + if (packet_id != 0) { + pid_man_.release_id(packet_id); + con_.on_packet_id_release(packet_id); + } + return false; + } + ++publish_send_count_; + } + } + } + + if constexpr(is_instance_of>::value) { + publish_recv_.erase(actual_packet.packet_id()); + } + + if constexpr(is_instance_of>::value) { + if (make_error_code(actual_packet.code())) { + publish_recv_.erase(actual_packet.packet_id()); + qos2_publish_handled_.erase(actual_packet.packet_id()); + } + } + + if constexpr(is_pubrel>()) { + auto packet_id = actual_packet.packet_id(); + BOOST_ASSERT(pid_man_.is_used_id(packet_id)); + if (need_store_) store_.add(actual_packet); + pid_pubcomp_.insert(packet_id); + } + + if constexpr(is_instance_of>::value) { + publish_recv_.erase(actual_packet.packet_id()); + } + + if constexpr(is_subscribe>()) { + auto packet_id = actual_packet.packet_id(); + BOOST_ASSERT(pid_man_.is_used_id(packet_id)); + pid_suback_.insert(packet_id); + release_packet_id_if_send_error.emplace(packet_id); + } + + if constexpr(is_unsubscribe>()) { + auto packet_id = actual_packet.packet_id(); + BOOST_ASSERT(pid_man_.is_used_id(packet_id)); + pid_unsuback_.insert(packet_id); + release_packet_id_if_send_error.emplace(packet_id); + } + + if constexpr(is_pingreq>()) { + // handler call order + // pingreq packet send + // if success, pingresp timer set + con_.on_send( + force_move(actual_packet), + release_packet_id_if_send_error + ); + if (pingresp_recv_timeout_ms_) { + con_.on_timer_op( + timer_op::reset, + timer_kind::pingresp_recv, + *pingresp_recv_timeout_ms_ + ); + } + return true; + } + + if constexpr(is_disconnect>()) { + status_ = connection_status::disconnected; + con_.on_send( + force_move(actual_packet), + release_packet_id_if_send_error + ); + con_.on_close(); + return true; + } + + if constexpr(is_publish>()) { + if (status_ != connection_status::connected) { + if (offline_publish_) { + ASYNC_MQTT_LOG("mqtt_impl", trace) + << "publish message is not sent but stored"; + + return true; + } + else { + ASYNC_MQTT_LOG("mqtt_impl", error) + << "publish message try to send but not connected"; + con_.on_error( + make_error_code( + mqtt_error::packet_not_allowed_to_send + ) + ); + if constexpr(own_packet_id>()) { + auto packet_id = actual_packet.packet_id(); + if (packet_id != 0) { + pid_man_.release_id(packet_id); + con_.on_packet_id_release(packet_id); + } + } + return false; + } + } + } + + con_.on_send( + force_move(actual_packet), + release_packet_id_if_send_error + ); + return true; +} + +} // namespace detail + +// connection public member functions + +template +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_connection:: +send(Packet packet) { + BOOST_ASSERT(impl_); + if constexpr(std::is_same_v>) { + return impl_->send(static_cast>(packet)); + } + return impl_->send(std::forward(packet)); +} + +} // namespace async_mqtt + +#include + +#if defined(ASYNC_MQTT_SEPARATE_COMPILATION) + +#include + +#define ASYNC_MQTT_INSTANTIATE_EACH_PACKET(a_role, a_size, a_packet) \ +namespace async_mqtt { \ +namespace detail { \ +template \ +void \ +basic_connection_impl:: \ +send(a_packet); \ +\ +template \ +bool \ +basic_connection_impl:: \ +process_send_packet(a_packet); \ +} \ +template \ +void \ +basic_connection:: \ +send(a_packet); \ +} + +#define ASYNC_MQTT_PP_GENERATE(r, product) \ + BOOST_PP_EXPAND( \ + ASYNC_MQTT_INSTANTIATE_EACH_PACKET \ + BOOST_PP_SEQ_TO_TUPLE( \ + product \ + ) \ + ) + +BOOST_PP_SEQ_FOR_EACH_PRODUCT( + ASYNC_MQTT_PP_GENERATE, + (ASYNC_MQTT_PP_ROLE)(ASYNC_MQTT_PP_SIZE)(ASYNC_MQTT_PP_PACKET) +) + +#define ASYNC_MQTT_PP_GENERATE_BASIC(r, product) \ + BOOST_PP_EXPAND( \ + ASYNC_MQTT_INSTANTIATE_EACH_PACKET \ + BOOST_PP_SEQ_TO_TUPLE( \ + BOOST_PP_SEQ_REPLACE( \ + product, \ + BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(product)), \ + ASYNC_MQTT_PP_BASIC_PACKET_INSTANTIATE( \ + BOOST_PP_SEQ_ELEM(BOOST_PP_DEC(BOOST_PP_SEQ_SIZE(product)), product), \ + BOOST_PP_SEQ_ELEM(1, product) \ + ) \ + ) \ + ) \ + ) + +BOOST_PP_SEQ_FOR_EACH_PRODUCT( + ASYNC_MQTT_PP_GENERATE_BASIC, + (ASYNC_MQTT_PP_ROLE)(ASYNC_MQTT_PP_SIZE)(ASYNC_MQTT_PP_BASIC_PACKET) +) + + +#undef ASYNC_MQTT_PP_GENERATE +#undef ASYNC_MQTT_PP_GENERATE_BASIC +#undef ASYNC_MQTT_INSTANTIATE_EACH_PACKET + +#endif // defined(ASYNC_MQTT_SEPARATE_COMPILATION) + +#endif // ASYNC_MQTT_PROTOCOL_IMPL_CONNECTION_SEND_IPP diff --git a/include/async_mqtt/impl/error.hpp b/include/async_mqtt/protocol/impl/error.hpp similarity index 99% rename from include/async_mqtt/impl/error.hpp rename to include/async_mqtt/protocol/impl/error.hpp index 9b53c2c5b..bd2085bd4 100644 --- a/include/async_mqtt/impl/error.hpp +++ b/include/async_mqtt/protocol/impl/error.hpp @@ -16,7 +16,7 @@ #include #include -#include +#include namespace async_mqtt { diff --git a/include/async_mqtt/util/packet_id_manager.hpp b/include/async_mqtt/protocol/impl/packet_id_manager.hpp similarity index 100% rename from include/async_mqtt/util/packet_id_manager.hpp rename to include/async_mqtt/protocol/impl/packet_id_manager.hpp diff --git a/include/async_mqtt/protocol/impl/rv_connection.hpp b/include/async_mqtt/protocol/impl/rv_connection.hpp new file mode 100644 index 000000000..1c8a50ddd --- /dev/null +++ b/include/async_mqtt/protocol/impl/rv_connection.hpp @@ -0,0 +1,29 @@ +// Copyright Takatoshi Kondo 2024 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_PROTOCOL_IMPL_RV_CONNECTION_HPP) +#define ASYNC_MQTT_PROTOCOL_IMPL_RV_CONNECTION_HPP + +#include +#include + +namespace async_mqtt { + +// public + +template +template +inline +std::vector> +basic_rv_connection:: +send(Packet packet) { + base_type::send(std::forward(packet)); + return force_move(events_); +} + +} // namespace async_mqtt + +#endif // ASYNC_MQTT_PROTOCOL_IMPL_RV_CONNECTION_HPP diff --git a/include/async_mqtt/protocol/impl/rv_connection.ipp b/include/async_mqtt/protocol/impl/rv_connection.ipp new file mode 100644 index 000000000..b79437014 --- /dev/null +++ b/include/async_mqtt/protocol/impl/rv_connection.ipp @@ -0,0 +1,132 @@ +// Copyright Takatoshi Kondo 2024 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_PROTOCOL_IMPL_RV_CONNECTION_IPP) +#define ASYNC_MQTT_PROTOCOL_IMPL_RV_CONNECTION_IPP + +#include +#include +#include +#include +#include +#include +#include + +namespace async_mqtt { + +// public + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +basic_rv_connection:: +basic_rv_connection(protocol_version ver) + :base_type{ver} +{ +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +std::vector> +basic_rv_connection:: +recv(std::istream& is) { + base_type::recv(is); + return force_move(events_); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +std::vector> +basic_rv_connection:: +notify_timer_fired(timer_kind kind) { + base_type::notify_timer_fired(kind); + return force_move(events_); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +std::vector> +basic_rv_connection:: +set_pingreq_send_interval( + std::chrono::milliseconds duration +) { + base_type::set_pingreq_send_interval(duration); + return force_move(events_); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +std::vector> +basic_rv_connection:: +release_packet_id(typename basic_packet_id_type::type packet_id) { + base_type::release_packet_id(packet_id); + return force_move(events_); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_rv_connection:: +on_error(error_code ec) { + events_.emplace_back(ec); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_rv_connection:: +on_send( + basic_packet_variant packet, + std::optional::type> + release_packet_id_if_send_error +) { + events_.emplace_back(event::basic_send{force_move(packet), release_packet_id_if_send_error}); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_rv_connection:: +on_packet_id_release( + typename basic_packet_id_type::type packet_id +) { + events_.emplace_back(event::basic_packet_id_released{packet_id}); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_rv_connection:: +on_receive( + basic_packet_variant packet +) { + events_.emplace_back(event::basic_packet_received{force_move(packet)}); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_rv_connection:: +on_timer_op( + timer_op op, + timer_kind kind, + std::optional ms +) { + events_.emplace_back(event::timer{op, kind, ms}); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +void +basic_rv_connection:: +on_close() { + events_.emplace_back(event::close{}); +} + +} // namespace async_mqtt + +#include + +#endif // ASYNC_MQTT_PROTOCOL_IMPL_RV_CONNECTION_IPP diff --git a/include/async_mqtt/protocol/impl/rv_connection_instantiate.hpp b/include/async_mqtt/protocol/impl/rv_connection_instantiate.hpp new file mode 100644 index 000000000..bfd61c256 --- /dev/null +++ b/include/async_mqtt/protocol/impl/rv_connection_instantiate.hpp @@ -0,0 +1,35 @@ +// Copyright Takatoshi Kondo 2024 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_PROTOCOL_IMPL_RV_CONNECTION_INSTANTIATE_HPP) +#define ASYNC_MQTT_PROTOCOL_IMPL_RV_CONNECTION_INSTANTIATE_HPP + +#if defined(ASYNC_MQTT_SEPARATE_COMPILATION) + +#include + +#define ASYNC_MQTT_INSTANTIATE_EACH(a_role, a_size) \ +namespace async_mqtt { \ +template \ +class basic_rv_connection; \ +} // namespace async_mqtt + +#define ASYNC_MQTT_PP_GENERATE(r, product) \ + BOOST_PP_EXPAND( \ + ASYNC_MQTT_INSTANTIATE_EACH \ + BOOST_PP_SEQ_TO_TUPLE( \ + product \ + ) \ + ) + +BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_ROLE)(ASYNC_MQTT_PP_SIZE)) + +#undef ASYNC_MQTT_PP_GENERATE +#undef ASYNC_MQTT_INSTANTIATE_EACH + +#endif // defined(ASYNC_MQTT_SEPARATE_COMPILATION) + +#endif // ASYNC_MQTT_PROTOCOL_IMPL_RV_CONNECTION_INSTANTIATE_HPP diff --git a/include/async_mqtt/util/store.hpp b/include/async_mqtt/protocol/impl/store.hpp similarity index 66% rename from include/async_mqtt/util/store.hpp rename to include/async_mqtt/protocol/impl/store.hpp index 91b7d7753..2aba69445 100644 --- a/include/async_mqtt/util/store.hpp +++ b/include/async_mqtt/protocol/impl/store.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_UTIL_STORE_HPP) -#define ASYNC_MQTT_UTIL_STORE_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_IMPL_STORE_HPP) +#define ASYNC_MQTT_PROTOCOL_IMPL_STORE_HPP #include #include @@ -15,8 +15,8 @@ #include #include -#include -#include +#include +#include namespace async_mqtt { @@ -29,24 +29,28 @@ class store { public: using store_packet_type = basic_store_packet_variant; - explicit store(as::any_io_executor exe):exe_{exe}{} + explicit store() = default; template bool add(Packet const& packet) { if constexpr(is_publish()) { if (packet.opts().get_qos() == qos::at_least_once || packet.opts().get_qos() == qos::exactly_once) { + ASYNC_MQTT_LOG("mqtt_impl", trace) + << "[store] add pid:" << packet.packet_id(); return elems_.emplace_back(packet).second; } } else if constexpr(is_pubrel()) { + ASYNC_MQTT_LOG("mqtt_impl", trace) + << "[store] add pid:" << packet.packet_id(); return elems_.emplace_back(packet).second; } return false; } bool erase(response_packet r, typename basic_packet_id_type::type packet_id) { - ASYNC_MQTT_LOG("mqtt_impl", info) + ASYNC_MQTT_LOG("mqtt_impl", trace) << "[store] erase pid:" << packet_id; auto& idx = elems_.template get(); auto it = idx.find(std::make_tuple(r, packet_id)); @@ -55,15 +59,36 @@ class store { return true; } + bool erase_publish(typename basic_packet_id_type::type packet_id) { + ASYNC_MQTT_LOG("mqtt_impl", trace) + << "[store] erase_publish pid:" << packet_id; + auto& idx = elems_.template get(); + auto [b, e] = idx.equal_range(packet_id); + for (; b != e; ++b) { + if (b->packet_id() == packet_id && + ( + b->response_packet() == response_packet::v3_1_1_puback || + b->response_packet() == response_packet::v3_1_1_pubrec || + b->response_packet() == response_packet::v5_puback || + b->response_packet() == response_packet::v5_pubrec + ) + ) { + b = idx.erase(b); + return true; + } + } + return false; + } + void clear() { - ASYNC_MQTT_LOG("mqtt_impl", info) + ASYNC_MQTT_LOG("mqtt_impl", trace) << "[store] clear"; elems_.clear(); } template - void for_each(Func const& func) { - ASYNC_MQTT_LOG("mqtt_impl", info) + void for_each(Func func) { + ASYNC_MQTT_LOG("mqtt_impl", trace) << "[store] for_each"; for (auto it = elems_.begin(); it != elems_.end();) { if (func(it->packet)) { @@ -76,7 +101,7 @@ class store { } std::vector get_stored() const { - ASYNC_MQTT_LOG("mqtt_impl", info) + ASYNC_MQTT_LOG("mqtt_impl", trace) << "[store] get_stored"; std::vector ret; ret.reserve(elems_.size()); @@ -103,6 +128,7 @@ class store { store_packet_type packet; }; struct tag_seq{}; + struct tag_id{}; struct tag_res_id{}; using mi_elem = mi::multi_index_container< elem_t, @@ -121,9 +147,8 @@ class store { >; mi_elem elems_; - as::any_io_executor exe_; }; } // namespace async_mqtt -#endif // ASYNC_MQTT_UTIL_STORE_HPP +#endif // ASYNC_MQTT_PROTOCOL_IMPL_STORE_HPP diff --git a/include/async_mqtt/protocol/impl/timer_impl.ipp b/include/async_mqtt/protocol/impl/timer_impl.ipp new file mode 100644 index 000000000..d2c5c8554 --- /dev/null +++ b/include/async_mqtt/protocol/impl/timer_impl.ipp @@ -0,0 +1,51 @@ +// Copyright Takatoshi Kondo 2024 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_PROTOCOL_IMPL_TIMER_IMPL_IPP) +#define ASYNC_MQTT_PROTOCOL_IMPL_TIMER_IMPL_IPP + +#include +#include +namespace async_mqtt { + +ASYNC_MQTT_HEADER_ONLY_INLINE +constexpr +char const* timer_kind_to_string(timer_kind v) { + switch (v) { + case timer_kind::pingreq_send: return "pingreq_send"; + case timer_kind::pingreq_recv: return "pingreq_recv"; + case timer_kind::pingresp_recv: return "pingresp_recv"; + default: return "unknown_timer"; + } +} + +inline +std::ostream& operator<<(std::ostream& o, timer_kind v) +{ + o << timer_kind_to_string(v); + return o; +} + +constexpr +char const* event_timer_op_to_string(timer_op const& v) { + switch (v) { + case timer_op::set: return "set"; + case timer_op::reset: return "reset"; + case timer_op::cancel: return "cancel"; + default: return "unknown_event_timer"; + } +} + +inline +std::ostream& operator<<(std::ostream& o, timer_op v) +{ + o << event_timer_op_to_string(v); + return o; +} + +} // namespace async_mqtt + +#endif // ASYNC_MQTT_PROTOCOL_IMPL_TIMER_IMPL_IPP diff --git a/include/async_mqtt/packet/control_packet_type.hpp b/include/async_mqtt/protocol/packet/control_packet_type.hpp similarity index 93% rename from include/async_mqtt/packet/control_packet_type.hpp rename to include/async_mqtt/protocol/packet/control_packet_type.hpp index 7331b003e..292bbd3dc 100644 --- a/include/async_mqtt/packet/control_packet_type.hpp +++ b/include/async_mqtt/protocol/packet/control_packet_type.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_CONTROL_PACKET_TYPE_HPP) -#define ASYNC_MQTT_PACKET_CONTROL_PACKET_TYPE_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_CONTROL_PACKET_TYPE_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_CONTROL_PACKET_TYPE_HPP #include #include @@ -19,7 +19,7 @@ namespace async_mqtt { * @brief MQTT control packet type * * #### Requirements - * @li Header: async_mqtt/packet/control_packet_type.hpp + * @li Header: async_mqtt/protocol/packet/control_packet_type.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -51,7 +51,7 @@ enum class control_packet_type : std::uint8_t { * @return control_packet_type * * #### Requirements - * @li Header: async_mqtt/packet/control_packet_type.hpp + * @li Header: async_mqtt/protocol/packet/control_packet_type.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -87,7 +87,7 @@ char const* control_packet_type_to_str(control_packet_type v) { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/control_packet_type.hpp + * @li Header: async_mqtt/protocol/packet/control_packet_type.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -166,4 +166,4 @@ inline std::optional get_control_packet_type_with_check(std } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_CONTROL_PACKET_TYPE_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_CONTROL_PACKET_TYPE_HPP diff --git a/include/async_mqtt/packet/detail/base_property.hpp b/include/async_mqtt/protocol/packet/detail/base_property.hpp similarity index 97% rename from include/async_mqtt/packet/detail/base_property.hpp rename to include/async_mqtt/protocol/packet/detail/base_property.hpp index 48849da67..7b6a4a2a8 100644 --- a/include/async_mqtt/packet/detail/base_property.hpp +++ b/include/async_mqtt/protocol/packet/detail/base_property.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_DETAIL_BASE_PROPERTY_HPP) -#define ASYNC_MQTT_PACKET_DETAIL_BASE_PROPERTY_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_DETAIL_BASE_PROPERTY_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_DETAIL_BASE_PROPERTY_HPP #include #include @@ -15,8 +15,8 @@ #include #include -#include -#include +#include +#include #include #include @@ -381,4 +381,4 @@ struct len_str { } // namespace async_mqtt::property::detail -#endif // ASYNC_MQTT_PACKET_DETAIL_BASE_PROPERTY_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_DETAIL_BASE_PROPERTY_HPP diff --git a/include/async_mqtt/packet/detail/fixed_header.hpp b/include/async_mqtt/protocol/packet/detail/fixed_header.hpp similarity index 62% rename from include/async_mqtt/packet/detail/fixed_header.hpp rename to include/async_mqtt/protocol/packet/detail/fixed_header.hpp index 1148c0f02..56356fc5c 100644 --- a/include/async_mqtt/packet/detail/fixed_header.hpp +++ b/include/async_mqtt/protocol/packet/detail/fixed_header.hpp @@ -4,10 +4,10 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_DETAIL_FIXED_HEADER_HPP) -#define ASYNC_MQTT_PACKET_DETAIL_FIXED_HEADER_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_DETAIL_FIXED_HEADER_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_DETAIL_FIXED_HEADER_HPP -#include +#include namespace async_mqtt::detail { @@ -17,4 +17,4 @@ constexpr std::uint8_t make_fixed_header(control_packet_type type, std::uint8_t } // namespace async_mqtt::detail -#endif // ASYNC_MQTT_PACKET_DETAIL_FIXED_HEADER_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_DETAIL_FIXED_HEADER_HPP diff --git a/include/async_mqtt/packet/detail/is_payload.hpp b/include/async_mqtt/protocol/packet/detail/is_payload.hpp similarity index 83% rename from include/async_mqtt/packet/detail/is_payload.hpp rename to include/async_mqtt/protocol/packet/detail/is_payload.hpp index 7583798a0..2cda881e3 100644 --- a/include/async_mqtt/packet/detail/is_payload.hpp +++ b/include/async_mqtt/protocol/packet/detail/is_payload.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_DETAIL_IS_PAYLOAD_HPP) -#define ASYNC_MQTT_PACKET_DETAIL_IS_PAYLOAD_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_DETAIL_IS_PAYLOAD_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_DETAIL_IS_PAYLOAD_HPP #include #include @@ -40,4 +40,4 @@ constexpr bool is_payload() { } // namespace async_mqtt::detail -#endif // ASYNC_MQTT_PACKET_DETAIL_IS_PAYLOAD_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_DETAIL_IS_PAYLOAD_HPP diff --git a/include/async_mqtt/packet/impl/connect_flags.hpp b/include/async_mqtt/protocol/packet/impl/connect_flags.hpp similarity index 86% rename from include/async_mqtt/packet/impl/connect_flags.hpp rename to include/async_mqtt/protocol/packet/impl/connect_flags.hpp index 1eb66b376..9a553af4a 100644 --- a/include/async_mqtt/packet/impl/connect_flags.hpp +++ b/include/async_mqtt/protocol/packet/impl/connect_flags.hpp @@ -4,11 +4,11 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_CONNECT_FLAGS_HPP) -#define ASYNC_MQTT_PACKET_IMPL_CONNECT_FLAGS_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_CONNECT_FLAGS_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_CONNECT_FLAGS_HPP #include -#include +#include namespace async_mqtt { @@ -61,4 +61,4 @@ constexpr qos will_qos(char v) { } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_IMPL_CONNECT_FLAGS_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_CONNECT_FLAGS_HPP diff --git a/include/async_mqtt/packet/impl/copy_to_static_vector.hpp b/include/async_mqtt/protocol/packet/impl/copy_to_static_vector.hpp similarity index 89% rename from include/async_mqtt/packet/impl/copy_to_static_vector.hpp rename to include/async_mqtt/protocol/packet/impl/copy_to_static_vector.hpp index 60170c478..ff1efaf72 100644 --- a/include/async_mqtt/packet/impl/copy_to_static_vector.hpp +++ b/include/async_mqtt/protocol/packet/impl/copy_to_static_vector.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_COPY_TO_STATIC_VECTOR_HPP) -#define ASYNC_MQTT_PACKET_IMPL_COPY_TO_STATIC_VECTOR_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_COPY_TO_STATIC_VECTOR_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_COPY_TO_STATIC_VECTOR_HPP #include @@ -62,4 +62,4 @@ std::optional insert_advance_variable_length(buffer& buf, static_ } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_IMPL_COPY_TO_STATIC_VECTOR_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_COPY_TO_STATIC_VECTOR_HPP diff --git a/include/async_mqtt/packet/impl/get_protocol_version.hpp b/include/async_mqtt/protocol/packet/impl/get_protocol_version.hpp similarity index 64% rename from include/async_mqtt/packet/impl/get_protocol_version.hpp rename to include/async_mqtt/protocol/packet/impl/get_protocol_version.hpp index d96a18f7b..e1935562a 100644 --- a/include/async_mqtt/packet/impl/get_protocol_version.hpp +++ b/include/async_mqtt/protocol/packet/impl/get_protocol_version.hpp @@ -4,11 +4,11 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_GET_PROTOCOL_VERSION_HPP) -#define ASYNC_MQTT_PACKET_IMPL_GET_PROTOCOL_VERSION_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_GET_PROTOCOL_VERSION_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_GET_PROTOCOL_VERSION_HPP -#include -#include +#include +#include namespace async_mqtt { @@ -27,4 +27,4 @@ protocol_version get_protocol_version(buffer buf) { } // async_mqtt -#endif // ASYNC_MQTT_PACKET_IMPL_GET_PROTOCOL_VERSION_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_GET_PROTOCOL_VERSION_HPP diff --git a/include/async_mqtt/packet/impl/packet_helper.hpp b/include/async_mqtt/protocol/packet/impl/packet_helper.hpp similarity index 81% rename from include/async_mqtt/packet/impl/packet_helper.hpp rename to include/async_mqtt/protocol/packet/impl/packet_helper.hpp index 16699ad43..8bd527691 100644 --- a/include/async_mqtt/packet/impl/packet_helper.hpp +++ b/include/async_mqtt/protocol/packet/impl/packet_helper.hpp @@ -4,18 +4,18 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_PACKET_HELPER_HPP) -#define ASYNC_MQTT_PACKET_IMPL_PACKET_HELPER_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_PACKET_HELPER_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_PACKET_HELPER_HPP #include #include #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include namespace async_mqtt { @@ -75,4 +75,4 @@ inline std::ostream& operator<< (std::ostream& o, hex_dump_t const& v) { } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_IMPL_PACKET_HELPER_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_PACKET_HELPER_HPP diff --git a/include/async_mqtt/packet/impl/packet_variant.hpp b/include/async_mqtt/protocol/packet/impl/packet_variant.hpp similarity index 81% rename from include/async_mqtt/packet/impl/packet_variant.hpp rename to include/async_mqtt/protocol/packet/impl/packet_variant.hpp index 1e0c78e2a..b18497033 100644 --- a/include/async_mqtt/packet/impl/packet_variant.hpp +++ b/include/async_mqtt/protocol/packet/impl/packet_variant.hpp @@ -4,10 +4,11 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_PACKET_VARIANT_HPP) -#define ASYNC_MQTT_PACKET_IMPL_PACKET_VARIANT_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_PACKET_VARIANT_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_PACKET_VARIANT_HPP -#include +#include +#include namespace async_mqtt { @@ -18,6 +19,10 @@ template < !std::is_same_v< std::decay_t, basic_packet_variant + > && + !std::is_same_v< + std::decay_t, + basic_store_packet_variant >, std::nullptr_t > @@ -89,4 +94,4 @@ decltype(auto) basic_packet_variant::get_if() const { } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_IMPL_PACKET_VARIANT_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_PACKET_VARIANT_HPP diff --git a/include/async_mqtt/packet/impl/packet_variant.ipp b/include/async_mqtt/protocol/packet/impl/packet_variant.ipp similarity index 68% rename from include/async_mqtt/packet/impl/packet_variant.ipp rename to include/async_mqtt/protocol/packet/impl/packet_variant.ipp index c13510a68..f5ea5ea64 100644 --- a/include/async_mqtt/packet/impl/packet_variant.ipp +++ b/include/async_mqtt/protocol/packet/impl/packet_variant.ipp @@ -4,10 +4,11 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_PACKET_VARIANT_IPP) -#define ASYNC_MQTT_PACKET_IMPL_PACKET_VARIANT_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_PACKET_VARIANT_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_PACKET_VARIANT_IPP -#include +#include +#include #include #if defined(ASYNC_MQTT_SEPARATE_COMPILATION) @@ -18,15 +19,20 @@ namespace async_mqtt { template ASYNC_MQTT_HEADER_ONLY_INLINE -std::optional basic_packet_variant::type() const { +control_packet_type basic_packet_variant::type() const { return visit( - overload { - [] (auto const& p) -> std::optional{ - return p.type(); - }, - [] (std::monostate const&) -> std::optional{ - return std::nullopt; - } + [] (auto const& p) { + return p.type(); + } + ); +} + +template +ASYNC_MQTT_HEADER_ONLY_INLINE +std::size_t basic_packet_variant::size() const { + return visit( + [] (auto const& p) { + return p.size(); } ); } @@ -38,20 +44,11 @@ std::vector basic_packet_variant::const_buffer_ overload { [] (auto const& p) { return p.const_buffer_sequence(); - }, - [] (std::monostate const&) { - return std::vector{}; } } ); } -template -ASYNC_MQTT_HEADER_ONLY_INLINE -basic_packet_variant::operator bool() const { - return var_.index() != 0; -} - template ASYNC_MQTT_HEADER_ONLY_INLINE std::ostream& operator<<(std::ostream& o, basic_packet_variant const& v) { @@ -59,8 +56,6 @@ std::ostream& operator<<(std::ostream& o, basic_packet_variant co overload { [&] (auto const& p) { o << p; - }, - [&] (std::monostate const&) { } } ); @@ -90,4 +85,4 @@ BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_SIZE)) } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_IMPL_PACKET_VARIANT_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_PACKET_VARIANT_IPP diff --git a/include/async_mqtt/packet/impl/property.hpp b/include/async_mqtt/protocol/packet/impl/property.hpp similarity index 98% rename from include/async_mqtt/packet/impl/property.hpp rename to include/async_mqtt/protocol/packet/impl/property.hpp index 376d2b682..66be98faa 100644 --- a/include/async_mqtt/packet/impl/property.hpp +++ b/include/async_mqtt/protocol/packet/impl/property.hpp @@ -4,10 +4,10 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_PROPERTY_HPP) -#define ASYNC_MQTT_PACKET_IMPL_PROPERTY_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_PROPERTY_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_PROPERTY_HPP -#include +#include namespace async_mqtt::property { @@ -606,4 +606,4 @@ shared_subscription_available::shared_subscription_available(It b, End e) } // namespace async_mqtt::property -#endif // ASYNC_MQTT_PACKET_PROPERTY_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_PROPERTY_HPP diff --git a/include/async_mqtt/packet/impl/property.ipp b/include/async_mqtt/protocol/packet/impl/property.ipp similarity index 96% rename from include/async_mqtt/packet/impl/property.ipp rename to include/async_mqtt/protocol/packet/impl/property.ipp index b879d5f63..31dfef8d5 100644 --- a/include/async_mqtt/packet/impl/property.ipp +++ b/include/async_mqtt/protocol/packet/impl/property.ipp @@ -4,10 +4,10 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_PROPERTY_IPP) -#define ASYNC_MQTT_PACKET_IMPL_PROPERTY_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_PROPERTY_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_PROPERTY_IPP -#include +#include #include namespace async_mqtt::property { @@ -197,4 +197,4 @@ std::ostream& operator<<(std::ostream& o, shared_subscription_available const& v } // namespace async_mqtt::property -#endif // ASYNC_MQTT_PACKET_IMPL_PROPERTY_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_PROPERTY_IPP diff --git a/include/async_mqtt/packet/impl/property_variant.hpp b/include/async_mqtt/protocol/packet/impl/property_variant.hpp similarity index 82% rename from include/async_mqtt/packet/impl/property_variant.hpp rename to include/async_mqtt/protocol/packet/impl/property_variant.hpp index dbcae27ca..464b3fd3a 100644 --- a/include/async_mqtt/packet/impl/property_variant.hpp +++ b/include/async_mqtt/protocol/packet/impl/property_variant.hpp @@ -4,15 +4,15 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_PROPERTY_VARIANT_HPP) -#define ASYNC_MQTT_PACKET_IMPL_PROPERTY_VARIANT_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_PROPERTY_VARIANT_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_PROPERTY_VARIANT_HPP #include #include -#include -#include -#include +#include +#include +#include namespace async_mqtt { @@ -81,11 +81,6 @@ decltype(auto) property_variant::get_if() const { return std::get_if(&var_); } -inline -property_variant::operator bool() { - return var_.index() != 0; -} - property_variant make_property_variant(buffer& buf, property_location loc, error_code& ec); properties make_properties(buffer buf, property_location loc, error_code& ec); std::vector const_buffer_sequence(properties const& props); @@ -95,7 +90,7 @@ std::size_t num_of_const_buffer_sequence(properties const& props); } // namespace async_mqtt #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_IMPL_PROPERTY_VARIANT_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_PROPERTY_VARIANT_HPP diff --git a/include/async_mqtt/packet/impl/property_variant.ipp b/include/async_mqtt/protocol/packet/impl/property_variant.ipp similarity index 97% rename from include/async_mqtt/packet/impl/property_variant.ipp rename to include/async_mqtt/protocol/packet/impl/property_variant.ipp index c4390b47e..78f7ad3c2 100644 --- a/include/async_mqtt/packet/impl/property_variant.ipp +++ b/include/async_mqtt/protocol/packet/impl/property_variant.ipp @@ -4,17 +4,17 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_PROPERTY_VARIANT_IPP) -#define ASYNC_MQTT_PACKET_IMPL_PROPERTY_VARIANT_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_PROPERTY_VARIANT_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_PROPERTY_VARIANT_IPP #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include namespace async_mqtt { @@ -587,4 +587,4 @@ std::size_t num_of_const_buffer_sequence(properties const& props) { } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_IMPL_PROPERTY_VARIANT_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_PROPERTY_VARIANT_IPP diff --git a/include/async_mqtt/packet/impl/session_present.hpp b/include/async_mqtt/protocol/packet/impl/session_present.hpp similarity index 63% rename from include/async_mqtt/packet/impl/session_present.hpp rename to include/async_mqtt/protocol/packet/impl/session_present.hpp index fa2743efd..e7806402a 100644 --- a/include/async_mqtt/packet/impl/session_present.hpp +++ b/include/async_mqtt/protocol/packet/impl/session_present.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_SESSION_PRESENT_HPP) -#define ASYNC_MQTT_PACKET_IMPL_SESSION_PRESENT_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_SESSION_PRESENT_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_SESSION_PRESENT_HPP namespace async_mqtt { @@ -16,4 +16,4 @@ constexpr bool is_session_present(char v) { } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_IMPL_SESSION_PRESENT_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_SESSION_PRESENT_HPP diff --git a/include/async_mqtt/packet/impl/v3_1_1_connack.ipp b/include/async_mqtt/protocol/packet/impl/v3_1_1_connack.ipp similarity index 89% rename from include/async_mqtt/packet/impl/v3_1_1_connack.ipp rename to include/async_mqtt/protocol/packet/impl/v3_1_1_connack.ipp index 67424105d..372c74ea8 100644 --- a/include/async_mqtt/packet/impl/v3_1_1_connack.ipp +++ b/include/async_mqtt/protocol/packet/impl/v3_1_1_connack.ipp @@ -4,21 +4,21 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V3_1_1_CONNACK_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V3_1_1_CONNACK_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_CONNACK_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_CONNACK_IPP #include #include -#include -#include +#include +#include #include #include #include -#include -#include +#include +#include namespace async_mqtt::v3_1_1 { @@ -143,4 +143,4 @@ std::ostream& operator<<(std::ostream& o, connack_packet const& v) { } // namespace async_mqtt::v3_1_1 -#endif // ASYNC_MQTT_PACKET_IMPL_V3_1_1_CONNACK_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_CONNACK_IPP diff --git a/include/async_mqtt/packet/impl/v3_1_1_connect.ipp b/include/async_mqtt/protocol/packet/impl/v3_1_1_connect.ipp similarity index 97% rename from include/async_mqtt/packet/impl/v3_1_1_connect.ipp rename to include/async_mqtt/protocol/packet/impl/v3_1_1_connect.ipp index f0d2923e5..bb640c459 100644 --- a/include/async_mqtt/packet/impl/v3_1_1_connect.ipp +++ b/include/async_mqtt/protocol/packet/impl/v3_1_1_connect.ipp @@ -4,16 +4,16 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V3_1_1_CONNECT_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V3_1_1_CONNECT_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_CONNECT_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_CONNECT_IPP #include #include #include -#include -#include +#include +#include #include #include @@ -22,10 +22,10 @@ #include #include -#include -#include +#include +#include -#include +#include namespace async_mqtt::v3_1_1 { @@ -526,4 +526,4 @@ std::ostream& operator<<(std::ostream& o, connect_packet const& v) { } // namespace async_mqtt::v3_1_1 -#endif // ASYNC_MQTT_PACKET_IMPL_V3_1_1_CONNECT_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_CONNECT_IPP diff --git a/include/async_mqtt/packet/impl/v3_1_1_disconnect.ipp b/include/async_mqtt/protocol/packet/impl/v3_1_1_disconnect.ipp similarity index 87% rename from include/async_mqtt/packet/impl/v3_1_1_disconnect.ipp rename to include/async_mqtt/protocol/packet/impl/v3_1_1_disconnect.ipp index 8d1e4c77f..6f16824e9 100644 --- a/include/async_mqtt/packet/impl/v3_1_1_disconnect.ipp +++ b/include/async_mqtt/protocol/packet/impl/v3_1_1_disconnect.ipp @@ -4,23 +4,23 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V3_1_1_DISCONNECT_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V3_1_1_DISCONNECT_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_DISCONNECT_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_DISCONNECT_IPP #include #include #include -#include -#include +#include +#include #include #include #include #include -#include +#include namespace async_mqtt::v3_1_1 { @@ -103,4 +103,4 @@ std::ostream& operator<<(std::ostream& o, disconnect_packet const& /*v*/) { } // namespace async_mqtt::v3_1_1 -#endif // ASYNC_MQTT_PACKET_IMPL_V3_1_1_DISCONNECT_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_DISCONNECT_IPP diff --git a/include/async_mqtt/packet/impl/v3_1_1_pingreq.ipp b/include/async_mqtt/protocol/packet/impl/v3_1_1_pingreq.ipp similarity index 87% rename from include/async_mqtt/packet/impl/v3_1_1_pingreq.ipp rename to include/async_mqtt/protocol/packet/impl/v3_1_1_pingreq.ipp index 435c00cea..82815d488 100644 --- a/include/async_mqtt/packet/impl/v3_1_1_pingreq.ipp +++ b/include/async_mqtt/protocol/packet/impl/v3_1_1_pingreq.ipp @@ -4,16 +4,16 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V3_1_1_PINGREQ_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V3_1_1_PINGREQ_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PINGREQ_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PINGREQ_IPP #include #include #include -#include -#include +#include +#include #include #include @@ -21,7 +21,7 @@ #include #include -#include +#include namespace async_mqtt::v3_1_1 { @@ -102,4 +102,4 @@ std::ostream& operator<<(std::ostream& o, pingreq_packet const& v) { } // namespace async_mqtt::v3_1_1 -#endif // ASYNC_MQTT_PACKET_IMPL_V3_1_1_PINGREQ_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PINGREQ_IPP diff --git a/include/async_mqtt/packet/impl/v3_1_1_pingresp.ipp b/include/async_mqtt/protocol/packet/impl/v3_1_1_pingresp.ipp similarity index 87% rename from include/async_mqtt/packet/impl/v3_1_1_pingresp.ipp rename to include/async_mqtt/protocol/packet/impl/v3_1_1_pingresp.ipp index ae9197db2..75a917956 100644 --- a/include/async_mqtt/packet/impl/v3_1_1_pingresp.ipp +++ b/include/async_mqtt/protocol/packet/impl/v3_1_1_pingresp.ipp @@ -4,16 +4,16 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V3_1_1_PINGRESP_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V3_1_1_PINGRESP_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PINGRESP_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PINGRESP_IPP #include #include #include -#include -#include +#include +#include #include #include @@ -21,7 +21,7 @@ #include #include -#include +#include namespace async_mqtt::v3_1_1 { @@ -104,4 +104,4 @@ std::ostream& operator<<(std::ostream& o, pingresp_packet const& v) { } // namespace async_mqtt::v3_1_1 -#endif // ASYNC_MQTT_PACKET_IMPL_V3_1_1_PINGRESP_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PINGRESP_IPP diff --git a/include/async_mqtt/packet/impl/v3_1_1_puback.ipp b/include/async_mqtt/protocol/packet/impl/v3_1_1_puback.ipp similarity index 91% rename from include/async_mqtt/packet/impl/v3_1_1_puback.ipp rename to include/async_mqtt/protocol/packet/impl/v3_1_1_puback.ipp index 94f7e5582..4fa833796 100644 --- a/include/async_mqtt/packet/impl/v3_1_1_puback.ipp +++ b/include/async_mqtt/protocol/packet/impl/v3_1_1_puback.ipp @@ -4,16 +4,16 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V3_1_1_PUBACK_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V3_1_1_PUBACK_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PUBACK_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PUBACK_IPP #include #include #include -#include -#include +#include +#include #include #include @@ -21,8 +21,8 @@ #include #include -#include -#include +#include +#include #if defined(ASYNC_MQTT_SEPARATE_COMPILATION) #include @@ -158,4 +158,4 @@ BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_SIZE)) } // namespace async_mqtt::v3_1_1 -#endif // ASYNC_MQTT_PACKET_IMPL_V3_1_1_PUBACK_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PUBACK_IPP diff --git a/include/async_mqtt/packet/impl/v3_1_1_pubcomp.ipp b/include/async_mqtt/protocol/packet/impl/v3_1_1_pubcomp.ipp similarity index 91% rename from include/async_mqtt/packet/impl/v3_1_1_pubcomp.ipp rename to include/async_mqtt/protocol/packet/impl/v3_1_1_pubcomp.ipp index 69f1ab181..dea714a2b 100644 --- a/include/async_mqtt/packet/impl/v3_1_1_pubcomp.ipp +++ b/include/async_mqtt/protocol/packet/impl/v3_1_1_pubcomp.ipp @@ -4,16 +4,16 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V3_1_1_PUBCOMP_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V3_1_1_PUBCOMP_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PUBCOMP_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PUBCOMP_IPP #include #include #include -#include -#include +#include +#include #include #include @@ -21,8 +21,8 @@ #include #include -#include -#include +#include +#include #if defined(ASYNC_MQTT_SEPARATE_COMPILATION) #include @@ -159,4 +159,4 @@ BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_SIZE)) } // namespace async_mqtt::v3_1_1 -#endif // ASYNC_MQTT_PACKET_IMPL_V3_1_1_PUBCOMP_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PUBCOMP_IPP diff --git a/include/async_mqtt/packet/impl/v3_1_1_publish.hpp b/include/async_mqtt/protocol/packet/impl/v3_1_1_publish.hpp similarity index 91% rename from include/async_mqtt/packet/impl/v3_1_1_publish.hpp rename to include/async_mqtt/protocol/packet/impl/v3_1_1_publish.hpp index 10bb91fab..7d2541120 100644 --- a/include/async_mqtt/packet/impl/v3_1_1_publish.hpp +++ b/include/async_mqtt/protocol/packet/impl/v3_1_1_publish.hpp @@ -4,11 +4,11 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V3_1_1_PUBLISH_HPP) -#define ASYNC_MQTT_PACKET_IMPL_V3_1_1_PUBLISH_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PUBLISH_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PUBLISH_HPP #include -#include +#include #include namespace async_mqtt::v3_1_1 { @@ -94,4 +94,4 @@ basic_publish_packet::basic_publish_packet( } // namespace async_mqtt::v3_1_1 -#endif // ASYNC_MQTT_PACKET_IMPL_V3_1_1_PUBLISH_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PUBLISH_HPP diff --git a/include/async_mqtt/packet/impl/v3_1_1_publish.ipp b/include/async_mqtt/protocol/packet/impl/v3_1_1_publish.ipp similarity index 94% rename from include/async_mqtt/packet/impl/v3_1_1_publish.ipp rename to include/async_mqtt/protocol/packet/impl/v3_1_1_publish.ipp index aa5a511cb..b22399318 100644 --- a/include/async_mqtt/packet/impl/v3_1_1_publish.ipp +++ b/include/async_mqtt/protocol/packet/impl/v3_1_1_publish.ipp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V3_1_1_PUBLISH_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V3_1_1_PUBLISH_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PUBLISH_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PUBLISH_IPP #include #include @@ -19,14 +19,14 @@ #include #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include -#include +#include #if defined(ASYNC_MQTT_PRINT_PAYLOAD) #include @@ -355,4 +355,4 @@ BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_SIZE)) } // namespace async_mqtt::v3_1_1 -#endif // ASYNC_MQTT_PACKET_IMPL_V3_1_1_PUBLISH_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PUBLISH_IPP diff --git a/include/async_mqtt/packet/impl/v3_1_1_pubrec.ipp b/include/async_mqtt/protocol/packet/impl/v3_1_1_pubrec.ipp similarity index 91% rename from include/async_mqtt/packet/impl/v3_1_1_pubrec.ipp rename to include/async_mqtt/protocol/packet/impl/v3_1_1_pubrec.ipp index 84166229d..737b05569 100644 --- a/include/async_mqtt/packet/impl/v3_1_1_pubrec.ipp +++ b/include/async_mqtt/protocol/packet/impl/v3_1_1_pubrec.ipp @@ -4,16 +4,16 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V3_1_1_PUBREC_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V3_1_1_PUBREC_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PUBREC_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PUBREC_IPP #include #include #include -#include -#include +#include +#include #include #include @@ -21,8 +21,8 @@ #include #include -#include -#include +#include +#include #if defined(ASYNC_MQTT_SEPARATE_COMPILATION) #include @@ -158,4 +158,4 @@ BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_SIZE)) } // namespace async_mqtt::v3_1_1 -#endif // ASYNC_MQTT_PACKET_IMPL_V3_1_1_PUBREC_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PUBREC_IPP diff --git a/include/async_mqtt/packet/impl/v3_1_1_pubrel.ipp b/include/async_mqtt/protocol/packet/impl/v3_1_1_pubrel.ipp similarity index 91% rename from include/async_mqtt/packet/impl/v3_1_1_pubrel.ipp rename to include/async_mqtt/protocol/packet/impl/v3_1_1_pubrel.ipp index 5bd0df17b..47ab90e17 100644 --- a/include/async_mqtt/packet/impl/v3_1_1_pubrel.ipp +++ b/include/async_mqtt/protocol/packet/impl/v3_1_1_pubrel.ipp @@ -4,16 +4,16 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V3_1_1_PUBREL_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V3_1_1_PUBREL_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PUBREL_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PUBREL_IPP #include #include #include -#include -#include +#include +#include #include #include @@ -21,8 +21,8 @@ #include #include -#include -#include +#include +#include #if defined(ASYNC_MQTT_SEPARATE_COMPILATION) #include @@ -158,4 +158,4 @@ BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_SIZE)) } // namespace async_mqtt::v3_1_1 -#endif // ASYNC_MQTT_PACKET_IMPL_V3_1_1_PUBREL_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_PUBREL_IPP diff --git a/include/async_mqtt/packet/impl/v3_1_1_suback.ipp b/include/async_mqtt/protocol/packet/impl/v3_1_1_suback.ipp similarity index 92% rename from include/async_mqtt/packet/impl/v3_1_1_suback.ipp rename to include/async_mqtt/protocol/packet/impl/v3_1_1_suback.ipp index e6850ba36..36e1c683e 100644 --- a/include/async_mqtt/packet/impl/v3_1_1_suback.ipp +++ b/include/async_mqtt/protocol/packet/impl/v3_1_1_suback.ipp @@ -4,16 +4,16 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V3_1_1_SUBACK_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V3_1_1_SUBACK_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_SUBACK_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_SUBACK_IPP #include #include #include -#include -#include +#include +#include #include #include @@ -21,10 +21,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include #if defined(ASYNC_MQTT_SEPARATE_COMPILATION) #include @@ -211,4 +211,4 @@ BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_SIZE)) } // namespace async_mqtt::v3_1_1 -#endif // ASYNC_MQTT_PACKET_IMPL_V3_1_1_SUBACK_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_SUBACK_IPP diff --git a/include/async_mqtt/packet/impl/v3_1_1_subscribe.ipp b/include/async_mqtt/protocol/packet/impl/v3_1_1_subscribe.ipp similarity index 94% rename from include/async_mqtt/packet/impl/v3_1_1_subscribe.ipp rename to include/async_mqtt/protocol/packet/impl/v3_1_1_subscribe.ipp index 89ab37196..61590d58a 100644 --- a/include/async_mqtt/packet/impl/v3_1_1_subscribe.ipp +++ b/include/async_mqtt/protocol/packet/impl/v3_1_1_subscribe.ipp @@ -4,13 +4,13 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V3_1_1_SUBSCRIBE_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V3_1_1_SUBSCRIBE_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_SUBSCRIBE_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_SUBSCRIBE_IPP #include -#include -#include +#include +#include #include #include @@ -19,11 +19,11 @@ #include #include -#include -#include -#include +#include +#include +#include #include -#include +#include #if defined(ASYNC_MQTT_SEPARATE_COMPILATION) #include @@ -339,4 +339,4 @@ BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_SIZE)) } // namespace async_mqtt::v3_1_1 -#endif // ASYNC_MQTT_PACKET_IMPL_V3_1_1_SUBSCRIBE_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_SUBSCRIBE_IPP diff --git a/include/async_mqtt/packet/impl/v3_1_1_unsuback.ipp b/include/async_mqtt/protocol/packet/impl/v3_1_1_unsuback.ipp similarity index 91% rename from include/async_mqtt/packet/impl/v3_1_1_unsuback.ipp rename to include/async_mqtt/protocol/packet/impl/v3_1_1_unsuback.ipp index 50f535100..0fd4d5e0a 100644 --- a/include/async_mqtt/packet/impl/v3_1_1_unsuback.ipp +++ b/include/async_mqtt/protocol/packet/impl/v3_1_1_unsuback.ipp @@ -4,16 +4,16 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V3_1_1_UNSUBACK_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V3_1_1_UNSUBACK_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_UNSUBACK_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_UNSUBACK_IPP #include #include #include -#include -#include +#include +#include #include #include @@ -21,8 +21,8 @@ #include #include -#include -#include +#include +#include #if defined(ASYNC_MQTT_SEPARATE_COMPILATION) #include @@ -158,4 +158,4 @@ BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_SIZE)) } // namespace async_mqtt::v3_1_1 -#endif // ASYNC_MQTT_PACKET_IMPL_V3_1_1_UNSUBACK_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_UNSUBACK_IPP diff --git a/include/async_mqtt/packet/impl/v3_1_1_unsubscribe.ipp b/include/async_mqtt/protocol/packet/impl/v3_1_1_unsubscribe.ipp similarity index 93% rename from include/async_mqtt/packet/impl/v3_1_1_unsubscribe.ipp rename to include/async_mqtt/protocol/packet/impl/v3_1_1_unsubscribe.ipp index 8c478b60e..718f1c9fc 100644 --- a/include/async_mqtt/packet/impl/v3_1_1_unsubscribe.ipp +++ b/include/async_mqtt/protocol/packet/impl/v3_1_1_unsubscribe.ipp @@ -4,13 +4,13 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V3_1_1_UNSUBSCRIBE_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V3_1_1_UNSUBSCRIBE_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_UNSUBSCRIBE_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_UNSUBSCRIBE_IPP #include -#include -#include +#include +#include #include #include @@ -19,11 +19,11 @@ #include #include -#include -#include -#include +#include +#include +#include #include -#include +#include #if defined(ASYNC_MQTT_SEPARATE_COMPILATION) #include @@ -276,4 +276,4 @@ BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_SIZE)) } // namespace async_mqtt::v3_1_1 -#endif // ASYNC_MQTT_PACKET_IMPL_V3_1_1_UNSUBSCRIBE_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V3_1_1_UNSUBSCRIBE_IPP diff --git a/include/async_mqtt/packet/impl/v5_auth.ipp b/include/async_mqtt/protocol/packet/impl/v5_auth.ipp similarity index 93% rename from include/async_mqtt/packet/impl/v5_auth.ipp rename to include/async_mqtt/protocol/packet/impl/v5_auth.ipp index 30837fc43..753e340bc 100644 --- a/include/async_mqtt/packet/impl/v5_auth.ipp +++ b/include/async_mqtt/protocol/packet/impl/v5_auth.ipp @@ -4,16 +4,16 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V5_AUTH_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V5_AUTH_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_AUTH_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_AUTH_IPP #include #include #include -#include -#include +#include +#include #include #include @@ -22,10 +22,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include namespace async_mqtt::v5 { @@ -272,4 +272,4 @@ bool operator<(auth_packet const& lhs, auth_packet const& rhs) { } // namespace async_mqtt::v5 -#endif // ASYNC_MQTT_PACKET_IMPL_V5_AUTH_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_AUTH_IPP diff --git a/include/async_mqtt/packet/impl/v5_connack.ipp b/include/async_mqtt/protocol/packet/impl/v5_connack.ipp similarity index 92% rename from include/async_mqtt/packet/impl/v5_connack.ipp rename to include/async_mqtt/protocol/packet/impl/v5_connack.ipp index 783820ccc..ea721fa1a 100644 --- a/include/async_mqtt/packet/impl/v5_connack.ipp +++ b/include/async_mqtt/protocol/packet/impl/v5_connack.ipp @@ -4,25 +4,25 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V5_CONNACK_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V5_CONNACK_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_CONNACK_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_CONNACK_IPP #include #include -#include -#include +#include +#include #include #include #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include namespace async_mqtt::v5 { @@ -266,4 +266,4 @@ std::ostream& operator<<(std::ostream& o, connack_packet const& v) { } // namespace async_mqtt::v5 -#endif // ASYNC_MQTT_PACKET_IMPL_V5_CONNACK_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_CONNACK_IPP diff --git a/include/async_mqtt/packet/impl/v5_connect.ipp b/include/async_mqtt/protocol/packet/impl/v5_connect.ipp similarity index 96% rename from include/async_mqtt/packet/impl/v5_connect.ipp rename to include/async_mqtt/protocol/packet/impl/v5_connect.ipp index 1cb580034..14fdabf2c 100644 --- a/include/async_mqtt/packet/impl/v5_connect.ipp +++ b/include/async_mqtt/protocol/packet/impl/v5_connect.ipp @@ -4,16 +4,16 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V5_CONNECT_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V5_CONNECT_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_CONNECT_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_CONNECT_IPP #include #include #include -#include -#include +#include +#include #include #include @@ -23,13 +23,13 @@ #include #include -#include -#include -#include +#include +#include +#include -#include -#include -#include +#include +#include +#include namespace async_mqtt::v5 { @@ -643,4 +643,4 @@ std::ostream& operator<<(std::ostream& o, connect_packet const& v) { } // namespace async_mqtt::v5 -#endif // ASYNC_MQTT_PACKET_IMPL_V5_CONNECT_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_CONNECT_IPP diff --git a/include/async_mqtt/packet/impl/v5_disconnect.ipp b/include/async_mqtt/protocol/packet/impl/v5_disconnect.ipp similarity index 94% rename from include/async_mqtt/packet/impl/v5_disconnect.ipp rename to include/async_mqtt/protocol/packet/impl/v5_disconnect.ipp index 728015d26..315f1fb85 100644 --- a/include/async_mqtt/packet/impl/v5_disconnect.ipp +++ b/include/async_mqtt/protocol/packet/impl/v5_disconnect.ipp @@ -4,16 +4,16 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V5_DISCONNECT_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V5_DISCONNECT_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_DISCONNECT_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_DISCONNECT_IPP #include #include #include -#include -#include +#include +#include #include #include @@ -22,10 +22,10 @@ #include #include -#include -#include -#include -#include +#include +#include +#include +#include namespace async_mqtt::v5 { @@ -298,4 +298,4 @@ bool operator<(disconnect_packet const& lhs, disconnect_packet const& rhs) { } // namespace async_mqtt::v5 -#endif // ASYNC_MQTT_PACKET_IMPL_V5_DISCONNECT_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_DISCONNECT_IPP diff --git a/include/async_mqtt/packet/impl/v5_pingreq.ipp b/include/async_mqtt/protocol/packet/impl/v5_pingreq.ipp similarity index 87% rename from include/async_mqtt/packet/impl/v5_pingreq.ipp rename to include/async_mqtt/protocol/packet/impl/v5_pingreq.ipp index 0439b3ffa..c77d18b95 100644 --- a/include/async_mqtt/packet/impl/v5_pingreq.ipp +++ b/include/async_mqtt/protocol/packet/impl/v5_pingreq.ipp @@ -4,16 +4,16 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V5_PINGREQ_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V5_PINGREQ_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PINGREQ_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PINGREQ_IPP #include #include #include -#include -#include +#include +#include #include #include @@ -21,7 +21,7 @@ #include #include -#include +#include namespace async_mqtt::v5 { @@ -104,4 +104,4 @@ std::ostream& operator<<(std::ostream& o, pingreq_packet const& v) { } // namespace async_mqtt::v5 -#endif // ASYNC_MQTT_PACKET_IMPL_V5_PINGREQ_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PINGREQ_IPP diff --git a/include/async_mqtt/packet/impl/v5_pingresp.ipp b/include/async_mqtt/protocol/packet/impl/v5_pingresp.ipp similarity index 87% rename from include/async_mqtt/packet/impl/v5_pingresp.ipp rename to include/async_mqtt/protocol/packet/impl/v5_pingresp.ipp index ab3944775..78a3e573b 100644 --- a/include/async_mqtt/packet/impl/v5_pingresp.ipp +++ b/include/async_mqtt/protocol/packet/impl/v5_pingresp.ipp @@ -4,16 +4,16 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V5_PINGRESP_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V5_PINGRESP_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PINGRESP_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PINGRESP_IPP #include #include #include -#include -#include +#include +#include #include #include @@ -21,7 +21,7 @@ #include #include -#include +#include namespace async_mqtt::v5 { @@ -104,4 +104,4 @@ std::ostream& operator<<(std::ostream& o, pingresp_packet const& v) { } // namespace async_mqtt::v5 -#endif // ASYNC_MQTT_PACKET_IMPL_V5_PINGRESP_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PINGRESP_IPP diff --git a/include/async_mqtt/packet/impl/v5_puback.ipp b/include/async_mqtt/protocol/packet/impl/v5_puback.ipp similarity index 94% rename from include/async_mqtt/packet/impl/v5_puback.ipp rename to include/async_mqtt/protocol/packet/impl/v5_puback.ipp index 5f1a59d2e..5f947aab9 100644 --- a/include/async_mqtt/packet/impl/v5_puback.ipp +++ b/include/async_mqtt/protocol/packet/impl/v5_puback.ipp @@ -4,16 +4,16 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V5_PUBACK_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V5_PUBACK_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PUBACK_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PUBACK_IPP #include #include #include -#include -#include +#include +#include #include #include @@ -22,11 +22,11 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #if defined(ASYNC_MQTT_SEPARATE_COMPILATION) #include @@ -341,4 +341,4 @@ BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_SIZE)) } // namespace async_mqtt::v5 -#endif // ASYNC_MQTT_PACKET_IMPL_V5_PUBACK_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PUBACK_IPP diff --git a/include/async_mqtt/packet/impl/v5_pubcomp.ipp b/include/async_mqtt/protocol/packet/impl/v5_pubcomp.ipp similarity index 94% rename from include/async_mqtt/packet/impl/v5_pubcomp.ipp rename to include/async_mqtt/protocol/packet/impl/v5_pubcomp.ipp index 715c0b3c3..afdeb238e 100644 --- a/include/async_mqtt/packet/impl/v5_pubcomp.ipp +++ b/include/async_mqtt/protocol/packet/impl/v5_pubcomp.ipp @@ -4,16 +4,16 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V5_PUBCOMP_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V5_PUBCOMP_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PUBCOMP_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PUBCOMP_IPP #include #include #include -#include -#include +#include +#include #include #include @@ -22,11 +22,11 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #if defined(ASYNC_MQTT_SEPARATE_COMPILATION) #include @@ -335,4 +335,4 @@ BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_SIZE)) } // namespace async_mqtt::v5 -#endif // ASYNC_MQTT_PACKET_IMPL_V5_PUBCOMP_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PUBCOMP_IPP diff --git a/include/async_mqtt/packet/impl/v5_publish.hpp b/include/async_mqtt/protocol/packet/impl/v5_publish.hpp similarity index 91% rename from include/async_mqtt/packet/impl/v5_publish.hpp rename to include/async_mqtt/protocol/packet/impl/v5_publish.hpp index bda13a937..e672f97d8 100644 --- a/include/async_mqtt/packet/impl/v5_publish.hpp +++ b/include/async_mqtt/protocol/packet/impl/v5_publish.hpp @@ -4,11 +4,11 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V5_PUBLISH_HPP) -#define ASYNC_MQTT_PACKET_IMPL_V5_PUBLISH_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PUBLISH_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PUBLISH_HPP #include -#include +#include #include namespace async_mqtt::v5 { @@ -98,4 +98,4 @@ basic_publish_packet::basic_publish_packet( } // namespace async_mqtt::v5 -#endif // ASYNC_MQTT_PACKET_IMPL_V5_PUBLISH_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PUBLISH_HPP diff --git a/include/async_mqtt/packet/impl/v5_publish.ipp b/include/async_mqtt/protocol/packet/impl/v5_publish.ipp similarity index 96% rename from include/async_mqtt/packet/impl/v5_publish.ipp rename to include/async_mqtt/protocol/packet/impl/v5_publish.ipp index deff8e086..7cec04803 100644 --- a/include/async_mqtt/packet/impl/v5_publish.ipp +++ b/include/async_mqtt/protocol/packet/impl/v5_publish.ipp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V5_PUBLISH_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V5_PUBLISH_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PUBLISH_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PUBLISH_IPP #include #include @@ -19,16 +19,16 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include -#include -#include +#include +#include #if defined(ASYNC_MQTT_PRINT_PAYLOAD) #include @@ -556,4 +556,4 @@ BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_SIZE)) } // namespace async_mqtt::v5 -#endif // ASYNC_MQTT_PACKET_IMPL_V5_PUBLISH_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PUBLISH_IPP diff --git a/include/async_mqtt/packet/impl/v5_pubrec.ipp b/include/async_mqtt/protocol/packet/impl/v5_pubrec.ipp similarity index 94% rename from include/async_mqtt/packet/impl/v5_pubrec.ipp rename to include/async_mqtt/protocol/packet/impl/v5_pubrec.ipp index 2ee6bf109..837fdddbb 100644 --- a/include/async_mqtt/packet/impl/v5_pubrec.ipp +++ b/include/async_mqtt/protocol/packet/impl/v5_pubrec.ipp @@ -4,16 +4,16 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V5_PUBREC_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V5_PUBREC_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PUBREC_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PUBREC_IPP #include #include #include -#include -#include +#include +#include #include #include @@ -22,11 +22,11 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #if defined(ASYNC_MQTT_SEPARATE_COMPILATION) #include @@ -343,4 +343,4 @@ BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_SIZE)) } // namespace async_mqtt::v5 -#endif // ASYNC_MQTT_PACKET_IMPL_V5_PUBREC_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PUBREC_IPP diff --git a/include/async_mqtt/packet/impl/v5_pubrel.ipp b/include/async_mqtt/protocol/packet/impl/v5_pubrel.ipp similarity index 94% rename from include/async_mqtt/packet/impl/v5_pubrel.ipp rename to include/async_mqtt/protocol/packet/impl/v5_pubrel.ipp index d0d2fe85d..04bd6b171 100644 --- a/include/async_mqtt/packet/impl/v5_pubrel.ipp +++ b/include/async_mqtt/protocol/packet/impl/v5_pubrel.ipp @@ -4,16 +4,16 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V5_PUBREL_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V5_PUBREL_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PUBREL_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PUBREL_IPP #include #include #include -#include -#include +#include +#include #include #include @@ -22,11 +22,11 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #if defined(ASYNC_MQTT_SEPARATE_COMPILATION) #include @@ -331,4 +331,4 @@ BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_SIZE)) } // namespace async_mqtt::v5 -#endif // ASYNC_MQTT_PACKET_IMPL_V5_PUBREL_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_PUBREL_IPP diff --git a/include/async_mqtt/packet/impl/v5_suback.ipp b/include/async_mqtt/protocol/packet/impl/v5_suback.ipp similarity index 93% rename from include/async_mqtt/packet/impl/v5_suback.ipp rename to include/async_mqtt/protocol/packet/impl/v5_suback.ipp index 40828f970..39f6a86bc 100644 --- a/include/async_mqtt/packet/impl/v5_suback.ipp +++ b/include/async_mqtt/protocol/packet/impl/v5_suback.ipp @@ -4,11 +4,11 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V5_SUBACK_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V5_SUBACK_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_SUBACK_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_SUBACK_IPP -#include -#include +#include +#include #include #include @@ -16,12 +16,12 @@ #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #if defined(ASYNC_MQTT_SEPARATE_COMPILATION) #include @@ -293,4 +293,4 @@ BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_SIZE)) } // namespace async_mqtt::v5 -#endif // ASYNC_MQTT_PACKET_IMPL_V5_SUBACK_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_SUBACK_IPP diff --git a/include/async_mqtt/packet/impl/v5_subscribe.ipp b/include/async_mqtt/protocol/packet/impl/v5_subscribe.ipp similarity index 95% rename from include/async_mqtt/packet/impl/v5_subscribe.ipp rename to include/async_mqtt/protocol/packet/impl/v5_subscribe.ipp index 98eaf64d6..08fdaae63 100644 --- a/include/async_mqtt/packet/impl/v5_subscribe.ipp +++ b/include/async_mqtt/protocol/packet/impl/v5_subscribe.ipp @@ -4,13 +4,13 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V5_SUBSCRIBE_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V5_SUBSCRIBE_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_SUBSCRIBE_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_SUBSCRIBE_IPP #include -#include -#include +#include +#include #include #include @@ -19,12 +19,12 @@ #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #if defined(ASYNC_MQTT_SEPARATE_COMPILATION) #include @@ -446,4 +446,4 @@ BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_SIZE)) } // namespace async_mqtt::v5 -#endif // ASYNC_MQTT_PACKET_IMPL_V5_SUBSCRIBE_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_SUBSCRIBE_IPP diff --git a/include/async_mqtt/packet/impl/v5_unsuback.ipp b/include/async_mqtt/protocol/packet/impl/v5_unsuback.ipp similarity index 93% rename from include/async_mqtt/packet/impl/v5_unsuback.ipp rename to include/async_mqtt/protocol/packet/impl/v5_unsuback.ipp index 1352e7b12..d154fabfa 100644 --- a/include/async_mqtt/packet/impl/v5_unsuback.ipp +++ b/include/async_mqtt/protocol/packet/impl/v5_unsuback.ipp @@ -4,11 +4,11 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V5_UNSUBACK_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V5_UNSUBACK_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_UNSUBACK_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_UNSUBACK_IPP -#include -#include +#include +#include #include #include @@ -16,11 +16,11 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #if defined(ASYNC_MQTT_SEPARATE_COMPILATION) #include @@ -287,4 +287,4 @@ BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_SIZE)) } // namespace async_mqtt::v5 -#endif // ASYNC_MQTT_PACKET_IMPL_V5_UNSUBACK_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_UNSUBACK_IPP diff --git a/include/async_mqtt/packet/impl/v5_unsubscribe.ipp b/include/async_mqtt/protocol/packet/impl/v5_unsubscribe.ipp similarity index 94% rename from include/async_mqtt/packet/impl/v5_unsubscribe.ipp rename to include/async_mqtt/protocol/packet/impl/v5_unsubscribe.ipp index ac614975a..1a0603505 100644 --- a/include/async_mqtt/packet/impl/v5_unsubscribe.ipp +++ b/include/async_mqtt/protocol/packet/impl/v5_unsubscribe.ipp @@ -4,13 +4,13 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_V5_UNSUBSCRIBE_IPP) -#define ASYNC_MQTT_PACKET_IMPL_V5_UNSUBSCRIBE_IPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_UNSUBSCRIBE_IPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_UNSUBSCRIBE_IPP #include -#include -#include +#include +#include #include #include @@ -19,12 +19,12 @@ #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #if defined(ASYNC_MQTT_SEPARATE_COMPILATION) #include @@ -343,4 +343,4 @@ BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_SIZE)) } // namespace async_mqtt::v5 -#endif // ASYNC_MQTT_PACKET_IMPL_V5_UNSUBSCRIBE_IPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_V5_UNSUBSCRIBE_IPP diff --git a/include/async_mqtt/packet/impl/validate_property.hpp b/include/async_mqtt/protocol/packet/impl/validate_property.hpp similarity index 96% rename from include/async_mqtt/packet/impl/validate_property.hpp rename to include/async_mqtt/protocol/packet/impl/validate_property.hpp index 8fffee1a8..0cf3ea253 100644 --- a/include/async_mqtt/packet/impl/validate_property.hpp +++ b/include/async_mqtt/protocol/packet/impl/validate_property.hpp @@ -4,11 +4,11 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_IMPL_VALIDATE_PROPERTY_HPP) -#define ASYNC_MQTT_PACKET_IMPL_VALIDATE_PROPERTY_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_VALIDATE_PROPERTY_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_VALIDATE_PROPERTY_HPP -#include +#include namespace async_mqtt { @@ -221,4 +221,4 @@ constexpr bool validate_property(property_location loc, property::id id) { } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_IMPL_VALIDATE_PROPERTY_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_VALIDATE_PROPERTY_HPP diff --git a/include/async_mqtt/packet/packet_fwd.hpp b/include/async_mqtt/protocol/packet/packet_fwd.hpp similarity index 94% rename from include/async_mqtt/packet/packet_fwd.hpp rename to include/async_mqtt/protocol/packet/packet_fwd.hpp index f0f278372..14db57302 100644 --- a/include/async_mqtt/packet/packet_fwd.hpp +++ b/include/async_mqtt/protocol/packet/packet_fwd.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_PACKET_FWD_HPP) -#define ASYNC_MQTT_PACKET_PACKET_FWD_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_PACKET_FWD_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_PACKET_FWD_HPP #include @@ -89,4 +89,4 @@ using unsuback_packet = basic_unsuback_packet<2>; } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_PACKET_FWD_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_PACKET_FWD_HPP diff --git a/include/async_mqtt/packet/packet_helper.hpp b/include/async_mqtt/protocol/packet/packet_helper.hpp similarity index 66% rename from include/async_mqtt/packet/packet_helper.hpp rename to include/async_mqtt/protocol/packet/packet_helper.hpp index 2d9bc69ab..f9813082e 100644 --- a/include/async_mqtt/packet/packet_helper.hpp +++ b/include/async_mqtt/protocol/packet/packet_helper.hpp @@ -4,13 +4,13 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_PACKET_HELPER_HPP) -#define ASYNC_MQTT_PACKET_PACKET_HELPER_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_PACKET_HELPER_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_PACKET_HELPER_HPP #include -#include -#include -#include +#include +#include +#include namespace async_mqtt { @@ -32,7 +32,7 @@ std::ostream& operator<< (std::ostream& o, hex_dump_t const& v); * @return id * * #### Requirements - * @li Header: async_mqtt/packet/packet_helper.hpp + * @li Header: async_mqtt/protocol/packet/packet_helper.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -43,6 +43,6 @@ hex_dump_t hex_dump(Packet const& p) { } // namespace async_mqtt -#include +#include -#endif // ASYNC_MQTT_PACKET_PACKET_HELPER_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_PACKET_HELPER_HPP diff --git a/include/async_mqtt/packet/packet_id_type.hpp b/include/async_mqtt/protocol/packet/packet_id_type.hpp similarity index 78% rename from include/async_mqtt/packet/packet_id_type.hpp rename to include/async_mqtt/protocol/packet/packet_id_type.hpp index 0ee4c039e..6d8c85862 100644 --- a/include/async_mqtt/packet/packet_id_type.hpp +++ b/include/async_mqtt/protocol/packet/packet_id_type.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_PACKET_ID_TYPE_HPP) -#define ASYNC_MQTT_PACKET_PACKET_ID_TYPE_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_PACKET_ID_TYPE_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_PACKET_ID_TYPE_HPP #include #include @@ -21,7 +21,7 @@ namespace async_mqtt { * @li `std::uint32_t` if PacketIdBytes is 4. For expanded specification for inter broker communication. * * #### Requirements - * @li Header: async_mqtt/packet/packet_id_type.hpp + * @li Header: async_mqtt/protocol/packet/packet_id_type.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -43,7 +43,7 @@ struct basic_packet_id_type<4> { * @brief packet idenfitifer type * * #### Requirements - * @li Header: async_mqtt/packet/packet_id_type.hpp + * @li Header: async_mqtt/protocol/packet/packet_id_type.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -51,4 +51,4 @@ using packet_id_type = typename basic_packet_id_type<2>::type; } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_PACKET_ID_TYPE_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_PACKET_ID_TYPE_HPP diff --git a/include/async_mqtt/packet/packet_iterator.hpp b/include/async_mqtt/protocol/packet/packet_iterator.hpp similarity index 82% rename from include/async_mqtt/packet/packet_iterator.hpp rename to include/async_mqtt/protocol/packet/packet_iterator.hpp index ceaff17b8..da6675236 100644 --- a/include/async_mqtt/packet/packet_iterator.hpp +++ b/include/async_mqtt/protocol/packet/packet_iterator.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_PACKET_ITERATOR_HPP) -#define ASYNC_MQTT_PACKET_PACKET_ITERATOR_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_PACKET_ITERATOR_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_PACKET_ITERATOR_HPP #include #include @@ -25,7 +25,7 @@ namespace as = boost::asio; * @brief iterator type of buffer sequence * * #### Requirements - * @li Header: async_mqtt/packet/packet_iteratore.hpp + * @li Header: async_mqtt/protocol/packet/packet_iteratore.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -39,7 +39,7 @@ using packet_iterator = as::buffers_iterator>; * @return the pair of packet_iterator * * #### Requirements - * @li Header: async_mqtt/packet/packet_iteratore.hpp + * @li Header: async_mqtt/protocol/packet/packet_iteratore.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -59,7 +59,7 @@ make_packet_range(Container const& cbs) { * @return string that all buffers are concatenated * * #### Requirements - * @li Header: async_mqtt/packet/packet_iteratore.hpp + * @li Header: async_mqtt/protocol/packet/packet_iteratore.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -72,4 +72,4 @@ to_string(Container const& cbs) { } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_PACKET_ITERATOR_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_PACKET_ITERATOR_HPP diff --git a/include/async_mqtt/packet/packet_traits.hpp b/include/async_mqtt/protocol/packet/packet_traits.hpp similarity index 96% rename from include/async_mqtt/packet/packet_traits.hpp rename to include/async_mqtt/protocol/packet/packet_traits.hpp index 96cb84bb7..9a6290ff7 100644 --- a/include/async_mqtt/packet/packet_traits.hpp +++ b/include/async_mqtt/protocol/packet/packet_traits.hpp @@ -4,15 +4,15 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_PACKET_TRAITS_HPP) -#define ASYNC_MQTT_PACKET_PACKET_TRAITS_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_PACKET_TRAITS_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_PACKET_TRAITS_HPP #include #include -#include -#include -#include +#include +#include +#include namespace async_mqtt { @@ -236,4 +236,4 @@ constexpr bool own_packet_id() { } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_PACKET_TRAITS_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_PACKET_TRAITS_HPP diff --git a/include/async_mqtt/packet/packet_variant.hpp b/include/async_mqtt/protocol/packet/packet_variant.hpp similarity index 65% rename from include/async_mqtt/packet/packet_variant.hpp rename to include/async_mqtt/protocol/packet/packet_variant.hpp index 781fdbea6..d0c079b37 100644 --- a/include/async_mqtt/packet/packet_variant.hpp +++ b/include/async_mqtt/protocol/packet/packet_variant.hpp @@ -4,46 +4,46 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_PACKET_VARIANT_HPP) -#define ASYNC_MQTT_PACKET_PACKET_VARIANT_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_PACKET_VARIANT_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_PACKET_VARIANT_HPP #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include namespace async_mqtt { @@ -53,12 +53,6 @@ template class basic_packet_variant { public: - /** - * @brief constructor - * the variant value is monostate - */ - explicit basic_packet_variant() = default; - /** * @brief constructor * @param packet packet @@ -69,6 +63,10 @@ class basic_packet_variant { !std::is_same_v< std::decay_t, basic_packet_variant + > && + !std::is_same_v< + std::decay_t, + basic_store_packet_variant >, std::nullptr_t > = nullptr @@ -126,9 +124,15 @@ class basic_packet_variant { /** * @brief Get control_packet_type. - * @return If packet is stored then return its control_packet_type, If error then return std::nullopt. + * @return control_packet_type. */ - std::optional type() const; + control_packet_type type() const; + + /** + * @brief Get the size of the packet. + * @return the size of the packet. + */ + std::size_t size() const; /** * @brief Create const buffer sequence @@ -137,12 +141,6 @@ class basic_packet_variant { */ std::vector const_buffer_sequence() const; - /** - * @brief bool conversion - * @return true if has value, otherwise (std::monostate) false. - */ - operator bool() const; - private: /** @@ -166,7 +164,6 @@ class basic_packet_variant { } using variant_t = std::variant< - std::monostate, v3_1_1::connect_packet, v3_1_1::connack_packet, v3_1_1::basic_publish_packet, @@ -213,10 +210,10 @@ std::ostream& operator<<(std::ostream& o, basic_packet_variant co } // namespace async_mqtt -#include +#include #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_PACKET_VARIANT_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_PACKET_VARIANT_HPP diff --git a/include/async_mqtt/packet/packet_variant_fwd.hpp b/include/async_mqtt/protocol/packet/packet_variant_fwd.hpp similarity index 88% rename from include/async_mqtt/packet/packet_variant_fwd.hpp rename to include/async_mqtt/protocol/packet/packet_variant_fwd.hpp index 451569e5d..246a6974a 100644 --- a/include/async_mqtt/packet/packet_variant_fwd.hpp +++ b/include/async_mqtt/protocol/packet/packet_variant_fwd.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_PACKET_VARIANT_FWD_HPP) -#define ASYNC_MQTT_PACKET_PACKET_VARIANT_FWD_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_PACKET_VARIANT_FWD_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_PACKET_VARIANT_FWD_HPP #include @@ -62,7 +62,7 @@ namespace async_mqtt { * @li @ref v5::auth_packet * * #### Requirements - * @li Header: async_mqtt/packet/packet_variant.hpp + * @li Header: async_mqtt/protocol/packet/packet_variant.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -75,7 +75,7 @@ class basic_packet_variant; * @brief type alias of basic_packet_variant (PacketIdBytes=2). * * #### Requirements - * @li Header: async_mqtt/packet/packet_variant.hpp + * @li Header: async_mqtt/protocol/packet/packet_variant.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -83,4 +83,4 @@ using packet_variant = basic_packet_variant<2>; } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_PACKET_VARIANT_FWD_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_PACKET_VARIANT_FWD_HPP diff --git a/include/async_mqtt/packet/property.hpp b/include/async_mqtt/protocol/packet/property.hpp similarity index 89% rename from include/async_mqtt/packet/property.hpp rename to include/async_mqtt/protocol/packet/property.hpp index 5185d168b..77ef29aa2 100644 --- a/include/async_mqtt/packet/property.hpp +++ b/include/async_mqtt/protocol/packet/property.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_PROPERTY_HPP) -#define ASYNC_MQTT_PACKET_PROPERTY_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_PROPERTY_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_PROPERTY_HPP #include #include @@ -22,8 +22,8 @@ #include -#include -#include +#include +#include /** * @defgroup property Property for MQTT v5.0 packets @@ -49,7 +49,7 @@ property_variant make_property_variant(buffer& buf, property_location loc, error * @brief payload_format * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -63,7 +63,7 @@ enum class payload_format { * @brief type of the session expiry interval (seconds) * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -74,7 +74,7 @@ using session_expiry_interval_type = std::uint32_t; * @brief type of the topic alias value * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -85,7 +85,7 @@ using topic_alias_type = std::uint16_t; * @brief type of the receive maximum value * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -96,7 +96,7 @@ using receive_maximum_type = std::uint16_t; * @brief the special session_expiry_interval value that session is never expire. * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -107,7 +107,7 @@ static constexpr session_expiry_interval_type session_never_expire = 0xffffffffU * @brief the maximum topic_alias value * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -118,7 +118,7 @@ static constexpr topic_alias_type topic_alias_max = 0xffff; * @brief the maximum receive_maximum value * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -129,7 +129,7 @@ static constexpr receive_maximum_type receive_maximum_max = 0xffff; * @brief the maximum maximum_packet_size value * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -149,7 +149,7 @@ namespace property { * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -184,7 +184,7 @@ class payload_format_indicator : public detail::n_bytes_property<1> { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -199,7 +199,7 @@ std::ostream& operator<<(std::ostream& o, payload_format_indicator const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -233,7 +233,7 @@ class message_expiry_interval : public detail::n_bytes_property<4> { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -248,7 +248,7 @@ std::ostream& operator<<(std::ostream& o, message_expiry_interval const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -279,7 +279,7 @@ class content_type : public detail::string_property { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -294,7 +294,7 @@ std::ostream& operator<<(std::ostream& o, content_type const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -325,7 +325,7 @@ class response_topic : public detail::string_property { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -340,7 +340,7 @@ std::ostream& operator<<(std::ostream& o, response_topic const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -371,7 +371,7 @@ class correlation_data : public detail::binary_property { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -386,7 +386,7 @@ std::ostream& operator<<(std::ostream& o, correlation_data const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -412,7 +412,7 @@ class subscription_identifier : public detail::variable_property { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -427,7 +427,7 @@ std::ostream& operator<<(std::ostream& o, subscription_identifier const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -461,7 +461,7 @@ class session_expiry_interval : public detail::n_bytes_property<4> { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -476,7 +476,7 @@ std::ostream& operator<<(std::ostream& o, session_expiry_interval const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -507,7 +507,7 @@ class assigned_client_identifier : public detail::string_property { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -522,7 +522,7 @@ std::ostream& operator<<(std::ostream& o, assigned_client_identifier const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -556,7 +556,7 @@ class server_keep_alive : public detail::n_bytes_property<2> { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -571,7 +571,7 @@ std::ostream& operator<<(std::ostream& o, server_keep_alive const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -602,7 +602,7 @@ class authentication_method : public detail::string_property { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -617,7 +617,7 @@ std::ostream& operator<<(std::ostream& o, authentication_method const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -648,7 +648,7 @@ class authentication_data : public detail::binary_property { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -663,7 +663,7 @@ std::ostream& operator<<(std::ostream& o, authentication_data const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -697,7 +697,7 @@ class request_problem_information : public detail::n_bytes_property<1> { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -712,7 +712,7 @@ std::ostream& operator<<(std::ostream& o, request_problem_information const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -746,7 +746,7 @@ class will_delay_interval : public detail::n_bytes_property<4> { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -761,7 +761,7 @@ std::ostream& operator<<(std::ostream& o, will_delay_interval const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -795,7 +795,7 @@ class request_response_information : public detail::n_bytes_property<1> { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -810,7 +810,7 @@ std::ostream& operator<<(std::ostream& o, request_response_information const& v) * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -841,7 +841,7 @@ class response_information : public detail::string_property { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -856,7 +856,7 @@ std::ostream& operator<<(std::ostream& o, response_information const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -887,7 +887,7 @@ class server_reference : public detail::string_property { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -902,7 +902,7 @@ std::ostream& operator<<(std::ostream& o, server_reference const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -933,7 +933,7 @@ class reason_string : public detail::string_property { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -948,7 +948,7 @@ std::ostream& operator<<(std::ostream& o, reason_string const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -982,7 +982,7 @@ class receive_maximum : public detail::n_bytes_property<2> { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -997,7 +997,7 @@ std::ostream& operator<<(std::ostream& o, receive_maximum const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1031,7 +1031,7 @@ class topic_alias_maximum : public detail::n_bytes_property<2> { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1046,7 +1046,7 @@ std::ostream& operator<<(std::ostream& o, topic_alias_maximum const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1080,7 +1080,7 @@ class topic_alias : public detail::n_bytes_property<2> { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1095,7 +1095,7 @@ std::ostream& operator<<(std::ostream& o, topic_alias const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1129,7 +1129,7 @@ class maximum_qos : public detail::n_bytes_property<1> { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1144,7 +1144,7 @@ std::ostream& operator<<(std::ostream& o, maximum_qos const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1178,7 +1178,7 @@ class retain_available : public detail::n_bytes_property<1> { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1193,7 +1193,7 @@ std::ostream& operator<<(std::ostream& o, retain_available const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1286,7 +1286,7 @@ class user_property : private boost::totally_ordered { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1301,7 +1301,7 @@ std::ostream& operator<<(std::ostream& o, user_property const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1335,7 +1335,7 @@ class maximum_packet_size : public detail::n_bytes_property<4> { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1350,7 +1350,7 @@ std::ostream& operator<<(std::ostream& o, maximum_packet_size const& v); * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1384,7 +1384,7 @@ class wildcard_subscription_available : public detail::n_bytes_property<1> { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1399,7 +1399,7 @@ std::ostream& operator<<(std::ostream& o, wildcard_subscription_available const& * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1433,7 +1433,7 @@ class subscription_identifier_available : public detail::n_bytes_property<1> { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1448,7 +1448,7 @@ std::ostream& operator<<(std::ostream& o, subscription_identifier_available cons * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1482,7 +1482,7 @@ class shared_subscription_available : public detail::n_bytes_property<1> { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property.hpp + * @li Header: async_mqtt/protocol/packet/property.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -1492,10 +1492,10 @@ std::ostream& operator<<(std::ostream& o, shared_subscription_available const& v } // namespace async_mqtt -#include +#include #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_PROPERTY_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_PROPERTY_HPP diff --git a/include/async_mqtt/packet/property_id.hpp b/include/async_mqtt/protocol/packet/property_id.hpp similarity index 94% rename from include/async_mqtt/packet/property_id.hpp rename to include/async_mqtt/protocol/packet/property_id.hpp index 0e2ebad88..259d7264a 100644 --- a/include/async_mqtt/packet/property_id.hpp +++ b/include/async_mqtt/protocol/packet/property_id.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_PROPERTY_ID_HPP) -#define ASYNC_MQTT_PACKET_PROPERTY_ID_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_PROPERTY_ID_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_PROPERTY_ID_HPP #include #include @@ -21,7 +21,7 @@ namespace property { * \n See * * #### Requirements - * @li Header: async_mqtt/packet/property_id.hpp + * @li Header: async_mqtt/protocol/packet/property_id.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -62,7 +62,7 @@ enum class id { * @return packet identifier * * #### Requirements - * @li Header: async_mqtt/packet/property_id.hpp + * @li Header: async_mqtt/protocol/packet/property_id.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -107,7 +107,7 @@ constexpr char const* id_to_str(id v) { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property_id.hpp + * @li Header: async_mqtt/protocol/packet/property_id.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -122,4 +122,4 @@ std::ostream& operator<<(std::ostream& o, id v) } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_PROPERTY_ID_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_PROPERTY_ID_HPP diff --git a/include/async_mqtt/packet/property_variant.hpp b/include/async_mqtt/protocol/packet/property_variant.hpp similarity index 89% rename from include/async_mqtt/packet/property_variant.hpp rename to include/async_mqtt/protocol/packet/property_variant.hpp index 6ad77e0ed..0c2fd7051 100644 --- a/include/async_mqtt/packet/property_variant.hpp +++ b/include/async_mqtt/protocol/packet/property_variant.hpp @@ -4,13 +4,13 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_PROPERTY_VARIANT_HPP) -#define ASYNC_MQTT_PACKET_PROPERTY_VARIANT_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_PROPERTY_VARIANT_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_PROPERTY_VARIANT_HPP #include #include -#include +#include namespace async_mqtt { @@ -26,7 +26,7 @@ namespace async_mqtt { * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/property_variant.hpp + * @li Header: async_mqtt/protocol/packet/property_variant.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -39,7 +39,7 @@ bool operator==(property_variant const& lhs, property_variant const& rhs); * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/property_variant.hpp + * @li Header: async_mqtt/protocol/packet/property_variant.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -52,7 +52,7 @@ bool operator<(property_variant const& lhs, property_variant const& rhs); * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property_variant.hpp + * @li Header: async_mqtt/protocol/packet/property_variant.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -68,7 +68,6 @@ std::ostream& operator<<(std::ostream& o, property_variant const& v); * @li Shared objects: Unsafe * * #### variants - * @li @ref std::monostate * @li @ref property::payload_format_indicator * @li @ref property::message_expiry_interval * @li @ref property::content_type @@ -98,7 +97,7 @@ std::ostream& operator<<(std::ostream& o, property_variant const& v); * @li @ref property::shared_subscription_available * * #### Requirements - * @li Header: async_mqtt/packet/property_variant.hpp + * @li Header: async_mqtt/protocol/packet/property_variant.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -198,19 +197,12 @@ class property_variant { template decltype(auto) get_if() const; - /** - * @brief Check the property is valid - * @return true if the property is valid, other - */ - operator bool(); - friend bool operator==(property_variant const& lhs, property_variant const& rhs); friend bool operator<(property_variant const& lhs, property_variant const& rhs); friend std::ostream& operator<<(std::ostream& o, property_variant const& v); private: using variant_t = std::variant< - std::monostate, property::payload_format_indicator, property::message_expiry_interval, property::content_type, @@ -248,7 +240,7 @@ class property_variant { * @brief property variant collection type * * #### Requirements - * @li Header: async_mqtt/packet/property_variant.hpp + * @li Header: async_mqtt/protocol/packet/property_variant.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -262,7 +254,7 @@ using properties = std::vector; * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property_variant.hpp + * @li Header: async_mqtt/protocol/packet/property_variant.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -276,7 +268,7 @@ std::ostream& operator<<(std::ostream& o, properties const& props); * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/property_variant.hpp + * @li Header: async_mqtt/protocol/packet/property_variant.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -290,7 +282,7 @@ bool operator<(property_variant const& lhs, property_variant const& rhs); * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/property_variant.hpp + * @li Header: async_mqtt/protocol/packet/property_variant.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -304,7 +296,7 @@ bool operator==(property_variant const& lhs, property_variant const& rhs); * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/property_variant.hpp + * @li Header: async_mqtt/protocol/packet/property_variant.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -312,6 +304,6 @@ std::ostream& operator<<(std::ostream& o, property_variant const& v); } // namespace async_mqtt -#include +#include -#endif // ASYNC_MQTT_PACKET_PROPERTY_VARIANT_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_PROPERTY_VARIANT_HPP diff --git a/include/async_mqtt/packet/pubopts.hpp b/include/async_mqtt/protocol/packet/pubopts.hpp similarity index 89% rename from include/async_mqtt/packet/pubopts.hpp rename to include/async_mqtt/protocol/packet/pubopts.hpp index 497dfac36..491240777 100644 --- a/include/async_mqtt/packet/pubopts.hpp +++ b/include/async_mqtt/protocol/packet/pubopts.hpp @@ -4,12 +4,12 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_PUBOPTS_HPP) -#define ASYNC_MQTT_PACKET_PUBOPTS_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_PUBOPTS_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_PUBOPTS_HPP #include -#include +#include /** * @defgroup publish_options PUBLISH packet flags @@ -29,7 +29,7 @@ namespace pub { * @return If DUP return true, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/pubopts.hpp + * @li Header: async_mqtt/protocol/packet/pubopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -45,7 +45,7 @@ constexpr bool is_dup(std::uint8_t v) { * @return qos * * #### Requirements - * @li Header: async_mqtt/packet/pubopts.hpp + * @li Header: async_mqtt/protocol/packet/pubopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -61,7 +61,7 @@ constexpr qos get_qos(std::uint8_t v) { * @return If RETAIN return true, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/pubopts.hpp + * @li Header: async_mqtt/protocol/packet/pubopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -77,7 +77,7 @@ constexpr bool is_retain(std::uint8_t v) { * @param dup DUP to set * * #### Requirements - * @li Header: async_mqtt/packet/pubopts.hpp + * @li Header: async_mqtt/protocol/packet/pubopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -93,7 +93,7 @@ constexpr void set_dup(std::uint8_t& fixed_header, bool dup) { * \n See * * #### Requirements - * @li Header: async_mqtt/packet/pubopts.hpp + * @li Header: async_mqtt/protocol/packet/pubopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -110,7 +110,7 @@ enum class retain : std::uint8_t { * \n See * * #### Requirements - * @li Header: async_mqtt/packet/pubopts.hpp + * @li Header: async_mqtt/protocol/packet/pubopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -130,7 +130,7 @@ enum class dup : std::uint8_t { * \n See * * #### Requirements - * @li Header: async_mqtt/packet/pubopts.hpp + * @li Header: async_mqtt/protocol/packet/pubopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -282,7 +282,7 @@ struct opts final { * @return conbined opts * * #### Requirements - * @li Header: async_mqtt/packet/pubopts.hpp + * @li Header: async_mqtt/protocol/packet/pubopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -296,7 +296,7 @@ constexpr opts operator|(retain lhs, dup rhs) { return opts(lhs) | rhs; } * @return conbined opts * * #### Requirements - * @li Header: async_mqtt/packet/pubopts.hpp + * @li Header: async_mqtt/protocol/packet/pubopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -310,7 +310,7 @@ constexpr opts operator|(retain lhs, qos rhs) { return opts(lhs) | rhs; } * @return conbined opts * * #### Requirements - * @li Header: async_mqtt/packet/pubopts.hpp + * @li Header: async_mqtt/protocol/packet/pubopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -324,7 +324,7 @@ constexpr opts operator|(dup lhs, retain rhs) { return opts(lhs) | rhs; } * @return conbined opts * * #### Requirements - * @li Header: async_mqtt/packet/pubopts.hpp + * @li Header: async_mqtt/protocol/packet/pubopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -338,7 +338,7 @@ constexpr opts operator|(dup lhs, qos rhs) { return opts(lhs) | rhs; } * @return conbined opts * * #### Requirements - * @li Header: async_mqtt/packet/pubopts.hpp + * @li Header: async_mqtt/protocol/packet/pubopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -352,7 +352,7 @@ constexpr opts operator|(qos lhs, retain rhs) { return opts(lhs) | rhs; } * @return conbined opts * * #### Requirements - * @li Header: async_mqtt/packet/pubopts.hpp + * @li Header: async_mqtt/protocol/packet/pubopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -367,7 +367,7 @@ constexpr opts operator|(qos lhs, dup rhs) { return opts(lhs) | rhs; } * @return retain string * * #### Requirements - * @li Header: async_mqtt/packet/pubopts.hpp + * @li Header: async_mqtt/protocol/packet/pubopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -388,7 +388,7 @@ constexpr char const* retain_to_str(retain v) { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/pubopts.hpp + * @li Header: async_mqtt/protocol/packet/pubopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -407,7 +407,7 @@ std::ostream& operator<<(std::ostream& o, retain v) * @return dup string * * #### Requirements - * @li Header: async_mqtt/packet/pubopts.hpp + * @li Header: async_mqtt/protocol/packet/pubopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -428,7 +428,7 @@ constexpr char const* dup_to_str(dup v) { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/pubopts.hpp + * @li Header: async_mqtt/protocol/packet/pubopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -443,4 +443,4 @@ std::ostream& operator<<(std::ostream& o, dup v) } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_PUBOPTS_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_PUBOPTS_HPP diff --git a/include/async_mqtt/packet/qos.hpp b/include/async_mqtt/protocol/packet/qos.hpp similarity index 84% rename from include/async_mqtt/packet/qos.hpp rename to include/async_mqtt/protocol/packet/qos.hpp index 9f54f7b84..db532cfc9 100644 --- a/include/async_mqtt/packet/qos.hpp +++ b/include/async_mqtt/protocol/packet/qos.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_QOS_HPP) -#define ASYNC_MQTT_PACKET_QOS_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_QOS_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_QOS_HPP #include #include @@ -27,7 +27,7 @@ namespace async_mqtt { * \n See * * #### Requirements - * @li Header: async_mqtt/packet/qos.hpp + * @li Header: async_mqtt/protocol/packet/qos.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -45,7 +45,7 @@ enum class qos : std::uint8_t * @return QoS string * * #### Requirements - * @li Header: async_mqtt/packet/qos.hpp + * @li Header: async_mqtt/protocol/packet/qos.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -66,7 +66,7 @@ constexpr char const* qos_to_str(qos v) { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/qos.hpp + * @li Header: async_mqtt/protocol/packet/qos.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -79,4 +79,4 @@ std::ostream& operator<<(std::ostream& o, qos v) } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_QOS_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_QOS_HPP diff --git a/include/async_mqtt/packet/qos_util.hpp b/include/async_mqtt/protocol/packet/qos_util.hpp similarity index 72% rename from include/async_mqtt/packet/qos_util.hpp rename to include/async_mqtt/protocol/packet/qos_util.hpp index 3fab18961..f665a5c44 100644 --- a/include/async_mqtt/packet/qos_util.hpp +++ b/include/async_mqtt/protocol/packet/qos_util.hpp @@ -4,11 +4,11 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_QOS_UTIL_HPP) -#define ASYNC_MQTT_PACKET_QOS_UTIL_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_QOS_UTIL_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_QOS_UTIL_HPP -#include -#include +#include +#include namespace async_mqtt { @@ -19,7 +19,7 @@ namespace async_mqtt { * @return suback_retun_code * * #### Requirements - * @li Header: async_mqtt/packet/qos_util.hpp + * @li Header: async_mqtt/protocol/packet/qos_util.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -34,7 +34,7 @@ constexpr suback_return_code qos_to_suback_return_code(qos q) { * @return suback_reason_code * * #### Requirements - * @li Header: async_mqtt/packet/qos_util.hpp + * @li Header: async_mqtt/protocol/packet/qos_util.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -44,4 +44,4 @@ constexpr suback_reason_code qos_to_suback_reason_code(qos q) { } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_QOS_UTIL_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_QOS_UTIL_HPP diff --git a/include/async_mqtt/packet/store_packet_variant.hpp b/include/async_mqtt/protocol/packet/store_packet_variant.hpp similarity index 90% rename from include/async_mqtt/packet/store_packet_variant.hpp rename to include/async_mqtt/protocol/packet/store_packet_variant.hpp index 4a42c6845..b18020692 100644 --- a/include/async_mqtt/packet/store_packet_variant.hpp +++ b/include/async_mqtt/protocol/packet/store_packet_variant.hpp @@ -4,18 +4,19 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_STORE_PACKET_VARIANT_HPP) -#define ASYNC_MQTT_PACKET_STORE_PACKET_VARIANT_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_STORE_PACKET_VARIANT_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_STORE_PACKET_VARIANT_HPP #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include namespace async_mqtt { @@ -24,7 +25,7 @@ namespace async_mqtt { * @brief corresponding response packet * * #### Requirements - * @li Header: async_mqtt/packet/store_packet_variant.hpp + * @li Header: async_mqtt/protocol/packet/store_packet_variant.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -262,6 +263,14 @@ class basic_store_packet_variant { return res_; } + operator basic_packet_variant() const { + return visit( + [](auto const& p) { + return basic_packet_variant(p); + } + ); + } + private: using variant_t = std::variant< v3_1_1::basic_publish_packet, @@ -288,4 +297,4 @@ inline std::ostream& operator<<(std::ostream& o, basic_store_packet_variant @@ -33,7 +33,7 @@ namespace async_mqtt { * @li @ref v5::basic_pubrel_packet * * #### Requirements - * @li Header: async_mqtt/packet/store_packet_variant.hpp + * @li Header: async_mqtt/protocol/packet/store_packet_variant.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -45,7 +45,7 @@ class basic_store_packet_variant; * @brief Type alias of basic_store_packet_variant (PacketIdBytes=2). * * #### Requirements - * @li Header: async_mqtt/packet/store_packet_variant.hpp + * @li Header: async_mqtt/protocol/packet/store_packet_variant.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -53,4 +53,4 @@ using store_packet_variant = basic_store_packet_variant<2>; } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_STORE_PACKET_VARIANT_FWD_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_STORE_PACKET_VARIANT_FWD_HPP diff --git a/include/async_mqtt/packet/subopts.hpp b/include/async_mqtt/protocol/packet/subopts.hpp similarity index 90% rename from include/async_mqtt/packet/subopts.hpp rename to include/async_mqtt/protocol/packet/subopts.hpp index 65ca55147..8e19e5804 100644 --- a/include/async_mqtt/packet/subopts.hpp +++ b/include/async_mqtt/protocol/packet/subopts.hpp @@ -4,13 +4,13 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_SUBOPTS_HPP) -#define ASYNC_MQTT_PACKET_SUBOPTS_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_SUBOPTS_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_SUBOPTS_HPP #include #include -#include +#include /** * @defgroup subscribe_options SUBSCRIBE packet flags @@ -28,7 +28,7 @@ namespace sub { * \n See * * #### Requirements - * @li Header: async_mqtt/packet/subopts.hpp + * @li Header: async_mqtt/protocol/packet/subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -46,7 +46,7 @@ enum class retain_handling : std::uint8_t * \n See * * #### Requirements - * @li Header: async_mqtt/packet/subopts.hpp + * @li Header: async_mqtt/protocol/packet/subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -63,7 +63,7 @@ enum class rap : std::uint8_t * \n See * * #### Requirements - * @li Header: async_mqtt/packet/subopts.hpp + * @li Header: async_mqtt/protocol/packet/subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -84,7 +84,7 @@ enum class nl : std::uint8_t * \n See * * #### Requirements - * @li Header: async_mqtt/packet/subopts.hpp + * @li Header: async_mqtt/protocol/packet/subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -261,7 +261,7 @@ struct opts final { * @return conbined opts * * #### Requirements - * @li Header: async_mqtt/packet/subopts.hpp + * @li Header: async_mqtt/protocol/packet/subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -275,7 +275,7 @@ constexpr opts operator|(retain_handling lhs, rap rhs) { return opts(lhs) | rhs; * @return conbined opts * * #### Requirements - * @li Header: async_mqtt/packet/subopts.hpp + * @li Header: async_mqtt/protocol/packet/subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -289,7 +289,7 @@ constexpr opts operator|(retain_handling lhs, nl rhs) { return opts(lhs) | rhs; * @return conbined opts * * #### Requirements - * @li Header: async_mqtt/packet/subopts.hpp + * @li Header: async_mqtt/protocol/packet/subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -303,7 +303,7 @@ constexpr opts operator|(retain_handling lhs, qos rhs) { return opts(lhs) | rhs; * @return conbined opts * * #### Requirements - * @li Header: async_mqtt/packet/subopts.hpp + * @li Header: async_mqtt/protocol/packet/subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -317,7 +317,7 @@ constexpr opts operator|(rap lhs, retain_handling rhs) { return opts(lhs) | rhs; * @return conbined opts * * #### Requirements - * @li Header: async_mqtt/packet/subopts.hpp + * @li Header: async_mqtt/protocol/packet/subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -331,7 +331,7 @@ constexpr opts operator|(rap lhs, nl rhs) { return opts(lhs) | rhs; * @return conbined opts * * #### Requirements - * @li Header: async_mqtt/packet/subopts.hpp + * @li Header: async_mqtt/protocol/packet/subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -345,7 +345,7 @@ constexpr opts operator|(rap lhs, qos rhs) { return opts(lhs) | rhs; * @return conbined opts * * #### Requirements - * @li Header: async_mqtt/packet/subopts.hpp + * @li Header: async_mqtt/protocol/packet/subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -359,7 +359,7 @@ constexpr opts operator|(nl lhs, retain_handling rhs) { return opts(lhs) | rhs; * @return conbined opts * * #### Requirements - * @li Header: async_mqtt/packet/subopts.hpp + * @li Header: async_mqtt/protocol/packet/subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -373,7 +373,7 @@ constexpr opts operator|(nl lhs, rap rhs) { return opts(lhs) | rhs; * @return conbined opts * * #### Requirements - * @li Header: async_mqtt/packet/subopts.hpp + * @li Header: async_mqtt/protocol/packet/subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -387,7 +387,7 @@ constexpr opts operator|(nl lhs, qos rhs) { return opts(lhs) | rhs; * @return conbined opts * * #### Requirements - * @li Header: async_mqtt/packet/subopts.hpp + * @li Header: async_mqtt/protocol/packet/subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -401,7 +401,7 @@ constexpr opts operator|(qos lhs, retain_handling rhs) { return opts(lhs) | rhs; * @return conbined opts * * #### Requirements - * @li Header: async_mqtt/packet/subopts.hpp + * @li Header: async_mqtt/protocol/packet/subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -415,7 +415,7 @@ constexpr opts operator|(qos lhs, rap rhs) { return opts(lhs) | rhs; * @return conbined opts * * #### Requirements - * @li Header: async_mqtt/packet/subopts.hpp + * @li Header: async_mqtt/protocol/packet/subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -429,7 +429,7 @@ constexpr opts operator|(qos lhs, nl rhs) { return opts(lhs) | rhs; * @return retain_handling string * * #### Requirements - * @li Header: async_mqtt/packet/subopts.hpp + * @li Header: async_mqtt/protocol/packet/subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -451,7 +451,7 @@ constexpr char const* retain_handling_to_str(retain_handling v) { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/subopts.hpp + * @li Header: async_mqtt/protocol/packet/subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -470,7 +470,7 @@ std::ostream& operator<<(std::ostream& o, retain_handling v) * @return rap(retain as published) string * * #### Requirements - * @li Header: async_mqtt/packet/subopts.hpp + * @li Header: async_mqtt/protocol/packet/subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -491,7 +491,7 @@ constexpr char const* rap_to_str(rap v) { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/subopts.hpp + * @li Header: async_mqtt/protocol/packet/subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -510,7 +510,7 @@ std::ostream& operator<<(std::ostream& o, rap v) * @return nl(no local) string * * #### Requirements - * @li Header: async_mqtt/packet/subopts.hpp + * @li Header: async_mqtt/protocol/packet/subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -531,7 +531,7 @@ constexpr char const* nl_to_str(nl v) { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/subopts.hpp + * @li Header: async_mqtt/protocol/packet/subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -546,4 +546,4 @@ std::ostream& operator<<(std::ostream& o, nl v) } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_SUBOPTS_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_SUBOPTS_HPP diff --git a/include/async_mqtt/packet/topic_sharename.hpp b/include/async_mqtt/protocol/packet/topic_sharename.hpp similarity index 93% rename from include/async_mqtt/packet/topic_sharename.hpp rename to include/async_mqtt/protocol/packet/topic_sharename.hpp index 85ecdcdcd..c3b0ceaad 100644 --- a/include/async_mqtt/packet/topic_sharename.hpp +++ b/include/async_mqtt/protocol/packet/topic_sharename.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_TOPIC_SHARENAME_HPP) -#define ASYNC_MQTT_PACKET_TOPIC_SHARENAME_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_TOPIC_SHARENAME_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_TOPIC_SHARENAME_HPP #include @@ -20,7 +20,7 @@ namespace async_mqtt { * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/topic_sharename.hpp + * @li Header: async_mqtt/protocol/packet/topic_sharename.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -126,4 +126,4 @@ class topic_sharename { } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_TOPIC_SHARENAME_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_TOPIC_SHARENAME_HPP diff --git a/include/async_mqtt/packet/topic_subopts.hpp b/include/async_mqtt/protocol/packet/topic_subopts.hpp similarity index 89% rename from include/async_mqtt/packet/topic_subopts.hpp rename to include/async_mqtt/protocol/packet/topic_subopts.hpp index 8a20b7cf3..382e03ca1 100644 --- a/include/async_mqtt/packet/topic_subopts.hpp +++ b/include/async_mqtt/protocol/packet/topic_subopts.hpp @@ -4,11 +4,11 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_TOPIC_SUBOPTS_HPP) -#define ASYNC_MQTT_PACKET_TOPIC_SUBOPTS_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_TOPIC_SUBOPTS_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_TOPIC_SUBOPTS_HPP -#include -#include +#include +#include namespace async_mqtt { @@ -21,7 +21,7 @@ namespace async_mqtt { * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/topic_subopts.hpp + * @li Header: async_mqtt/protocol/packet/topic_subopts.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -117,4 +117,4 @@ class topic_subopts { } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_TOPIC_SUBOPTS_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_TOPIC_SUBOPTS_HPP diff --git a/include/async_mqtt/packet/v3_1_1_connack.hpp b/include/async_mqtt/protocol/packet/v3_1_1_connack.hpp similarity index 84% rename from include/async_mqtt/packet/v3_1_1_connack.hpp rename to include/async_mqtt/protocol/packet/v3_1_1_connack.hpp index ced496c87..c1f92a3eb 100644 --- a/include/async_mqtt/packet/v3_1_1_connack.hpp +++ b/include/async_mqtt/protocol/packet/v3_1_1_connack.hpp @@ -4,17 +4,17 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V3_1_1_CONNACK_HPP) -#define ASYNC_MQTT_PACKET_V3_1_1_CONNACK_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_CONNACK_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_CONNACK_HPP -#include -#include +#include +#include #include #include -#include +#include /** * @defgroup connack_v3_1_1 CONNACK packet (v3.1.1) @@ -37,7 +37,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_connack.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_connack.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -100,7 +100,7 @@ class connack_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -123,7 +123,7 @@ class connack_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_connack.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_connack.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -137,7 +137,7 @@ bool operator<(connack_packet const& lhs, connack_packet const& rhs); * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_connack.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_connack.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -151,7 +151,7 @@ bool operator==(connack_packet const& lhs, connack_packet const& rhs); * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_connack.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_connack.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -160,7 +160,7 @@ std::ostream& operator<<(std::ostream& o, connack_packet const& v); } // namespace async_mqtt::v3_1_1 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V3_1_1_CONNACK_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_CONNACK_HPP diff --git a/include/async_mqtt/packet/v3_1_1_connect.hpp b/include/async_mqtt/protocol/packet/v3_1_1_connect.hpp similarity index 93% rename from include/async_mqtt/packet/v3_1_1_connect.hpp rename to include/async_mqtt/protocol/packet/v3_1_1_connect.hpp index 95230ee5a..b3e238181 100644 --- a/include/async_mqtt/packet/v3_1_1_connect.hpp +++ b/include/async_mqtt/protocol/packet/v3_1_1_connect.hpp @@ -4,16 +4,16 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V3_1_1_CONNECT_HPP) -#define ASYNC_MQTT_PACKET_V3_1_1_CONNECT_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_CONNECT_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_CONNECT_HPP -#include +#include #include #include -#include -#include +#include +#include /** * @defgroup connect_v3_1_1 CONNECT packet (v3.1.1) @@ -36,7 +36,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_connect.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_connect.hpp * @li Convenience header: async_mqtt/all.hpp */ class connect_packet { @@ -178,7 +178,7 @@ class connect_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -221,7 +221,7 @@ class connect_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_connect.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_connect.hpp * @li Convenience header: async_mqtt/all.hpp */ bool operator<(connect_packet const& lhs, connect_packet const& rhs); @@ -234,7 +234,7 @@ bool operator<(connect_packet const& lhs, connect_packet const& rhs); * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_connect.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_connect.hpp * @li Convenience header: async_mqtt/all.hpp */ bool operator==(connect_packet const& lhs, connect_packet const& rhs); @@ -247,7 +247,7 @@ bool operator==(connect_packet const& lhs, connect_packet const& rhs); * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_connect.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_connect.hpp * @li Convenience header: async_mqtt/all.hpp */ std::ostream& operator<<(std::ostream& o, connect_packet const& v); @@ -255,7 +255,7 @@ std::ostream& operator<<(std::ostream& o, connect_packet const& v); } // namespace async_mqtt::v3_1_1 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V3_1_1_CONNECT_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_CONNECT_HPP diff --git a/include/async_mqtt/packet/v3_1_1_disconnect.hpp b/include/async_mqtt/protocol/packet/v3_1_1_disconnect.hpp similarity index 85% rename from include/async_mqtt/packet/v3_1_1_disconnect.hpp rename to include/async_mqtt/protocol/packet/v3_1_1_disconnect.hpp index 7c0585838..b4d9c12b9 100644 --- a/include/async_mqtt/packet/v3_1_1_disconnect.hpp +++ b/include/async_mqtt/protocol/packet/v3_1_1_disconnect.hpp @@ -4,17 +4,17 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V3_1_1_DISCONNECT_HPP) -#define ASYNC_MQTT_PACKET_V3_1_1_DISCONNECT_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_DISCONNECT_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_DISCONNECT_HPP #include #include #include -#include +#include -#include +#include #include #include @@ -50,7 +50,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_disconnect.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_disconnect.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -93,7 +93,7 @@ class disconnect_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -116,7 +116,7 @@ class disconnect_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_disconnect.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_disconnect.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -130,7 +130,7 @@ bool operator<(disconnect_packet const& lhs, disconnect_packet const& rhs); * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_disconnect.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_disconnect.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -144,7 +144,7 @@ bool operator==(disconnect_packet const& lhs, disconnect_packet const& rhs); * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_disconnect.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_disconnect.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -153,7 +153,7 @@ std::ostream& operator<<(std::ostream& o, disconnect_packet const& v); } // namespace async_mqtt::v3_1_1 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V3_1_1_DISCONNECT_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_DISCONNECT_HPP diff --git a/include/async_mqtt/packet/v3_1_1_pingreq.hpp b/include/async_mqtt/protocol/packet/v3_1_1_pingreq.hpp similarity index 84% rename from include/async_mqtt/packet/v3_1_1_pingreq.hpp rename to include/async_mqtt/protocol/packet/v3_1_1_pingreq.hpp index d0d23ec4c..ff5e5b6ee 100644 --- a/include/async_mqtt/packet/v3_1_1_pingreq.hpp +++ b/include/async_mqtt/protocol/packet/v3_1_1_pingreq.hpp @@ -4,12 +4,12 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V3_1_1_PINGREQ_HPP) -#define ASYNC_MQTT_PACKET_V3_1_1_PINGREQ_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_PINGREQ_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_PINGREQ_HPP -#include +#include -#include +#include #include #include @@ -41,7 +41,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pingreq.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pingreq.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -85,7 +85,7 @@ class pingreq_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -108,7 +108,7 @@ class pingreq_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pingreq.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pingreq.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -122,7 +122,7 @@ bool operator<(pingreq_packet const& lhs, pingreq_packet const& rhs); * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pingreq.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pingreq.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -136,7 +136,7 @@ bool operator==(pingreq_packet const& lhs, pingreq_packet const& rhs); * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pingreq.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pingreq.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -145,7 +145,7 @@ std::ostream& operator<<(std::ostream& o, pingreq_packet const& v); } // namespace async_mqtt::v3_1_1 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V3_1_1_PINGREQ_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_PINGREQ_HPP diff --git a/include/async_mqtt/packet/v3_1_1_pingresp.hpp b/include/async_mqtt/protocol/packet/v3_1_1_pingresp.hpp similarity index 84% rename from include/async_mqtt/packet/v3_1_1_pingresp.hpp rename to include/async_mqtt/protocol/packet/v3_1_1_pingresp.hpp index 3b2ca55fb..4c021fc91 100644 --- a/include/async_mqtt/packet/v3_1_1_pingresp.hpp +++ b/include/async_mqtt/protocol/packet/v3_1_1_pingresp.hpp @@ -4,12 +4,12 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V3_1_1_PINGRESP_HPP) -#define ASYNC_MQTT_PACKET_V3_1_1_PINGRESP_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_PINGRESP_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_PINGRESP_HPP -#include +#include -#include +#include #include #include @@ -41,7 +41,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pingresp.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pingresp.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -85,7 +85,7 @@ class pingresp_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -109,7 +109,7 @@ class pingresp_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pingresp.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pingresp.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -123,7 +123,7 @@ bool operator<(pingresp_packet const& lhs, pingresp_packet const& rhs); * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pingresp.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pingresp.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -137,7 +137,7 @@ bool operator==(pingresp_packet const& lhs, pingresp_packet const& rhs); * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pingresp.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pingresp.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -146,7 +146,7 @@ std::ostream& operator<<(std::ostream& o, pingresp_packet const& v); } // namespace async_mqtt::v3_1_1 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V3_1_1_PINGRESP_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_PINGRESP_HPP diff --git a/include/async_mqtt/packet/v3_1_1_puback.hpp b/include/async_mqtt/protocol/packet/v3_1_1_puback.hpp similarity index 85% rename from include/async_mqtt/packet/v3_1_1_puback.hpp rename to include/async_mqtt/protocol/packet/v3_1_1_puback.hpp index 7bde60a18..51f4220be 100644 --- a/include/async_mqtt/packet/v3_1_1_puback.hpp +++ b/include/async_mqtt/protocol/packet/v3_1_1_puback.hpp @@ -4,13 +4,13 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V3_1_1_PUBACK_HPP) -#define ASYNC_MQTT_PACKET_V3_1_1_PUBACK_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_PUBACK_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_PUBACK_HPP -#include +#include -#include -#include +#include +#include #include #include @@ -46,7 +46,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_puback.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_puback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -100,7 +100,7 @@ class basic_puback_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -124,7 +124,7 @@ class basic_puback_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_puback.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_puback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -139,7 +139,7 @@ bool operator<(basic_puback_packet const& lhs, basic_puback_packe * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_puback.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_puback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -154,7 +154,7 @@ bool operator==(basic_puback_packet const& lhs, basic_puback_pack * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_puback.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_puback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -167,7 +167,7 @@ std::ostream& operator<<(std::ostream& o, basic_puback_packet con * @brief Type alias of basic_puback_packet (PacketIdBytes=2). * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_puback.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_puback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -176,7 +176,7 @@ using puback_packet = basic_puback_packet<2>; } // namespace async_mqtt::v3_1_1 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V3_1_1_PUBACK_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_PUBACK_HPP diff --git a/include/async_mqtt/packet/v3_1_1_pubcomp.hpp b/include/async_mqtt/protocol/packet/v3_1_1_pubcomp.hpp similarity index 85% rename from include/async_mqtt/packet/v3_1_1_pubcomp.hpp rename to include/async_mqtt/protocol/packet/v3_1_1_pubcomp.hpp index 05d2bfb41..6af1f20bf 100644 --- a/include/async_mqtt/packet/v3_1_1_pubcomp.hpp +++ b/include/async_mqtt/protocol/packet/v3_1_1_pubcomp.hpp @@ -4,13 +4,13 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V3_1_1_PUBCOMP_HPP) -#define ASYNC_MQTT_PACKET_V3_1_1_PUBCOMP_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_PUBCOMP_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_PUBCOMP_HPP -#include +#include -#include -#include +#include +#include #include #include @@ -46,7 +46,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pubcomp.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pubcomp.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -100,7 +100,7 @@ class basic_pubcomp_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -124,7 +124,7 @@ class basic_pubcomp_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pubcomp.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pubcomp.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -139,7 +139,7 @@ bool operator<(basic_pubcomp_packet const& lhs, basic_pubcomp_pac * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pubcomp.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pubcomp.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -154,7 +154,7 @@ bool operator==(basic_pubcomp_packet const& lhs, basic_pubcomp_pa * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pubcomp.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pubcomp.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -167,7 +167,7 @@ std::ostream& operator<<(std::ostream& o, basic_pubcomp_packet co * @brief Type alias of basic_pubcomp_packet (PacketIdBytes=2). * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pubcomp.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pubcomp.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -176,7 +176,7 @@ using pubcomp_packet = basic_pubcomp_packet<2>; } // namespace async_mqtt::v3_1_1 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V3_1_1_PUBCOMP_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_PUBCOMP_HPP diff --git a/include/async_mqtt/packet/v3_1_1_publish.hpp b/include/async_mqtt/protocol/packet/v3_1_1_publish.hpp similarity index 91% rename from include/async_mqtt/packet/v3_1_1_publish.hpp rename to include/async_mqtt/protocol/packet/v3_1_1_publish.hpp index a26c090c1..92cc5cb05 100644 --- a/include/async_mqtt/packet/v3_1_1_publish.hpp +++ b/include/async_mqtt/protocol/packet/v3_1_1_publish.hpp @@ -4,15 +4,15 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V3_1_1_PUBLISH_HPP) -#define ASYNC_MQTT_PACKET_V3_1_1_PUBLISH_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_PUBLISH_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_PUBLISH_HPP -#include +#include -#include -#include -#include -#include +#include +#include +#include +#include #include #include @@ -53,7 +53,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_publish.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_publish.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -207,7 +207,7 @@ class basic_publish_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -248,7 +248,7 @@ class basic_publish_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_publish.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_publish.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -263,7 +263,7 @@ bool operator<(basic_publish_packet const& lhs, basic_publish_pac * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_publish.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_publish.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -278,7 +278,7 @@ bool operator==(basic_publish_packet const& lhs, basic_publish_pa * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_publish.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_publish.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -291,7 +291,7 @@ std::ostream& operator<<(std::ostream& o, basic_publish_packet co * @brief Type alias of basic_publish_packet (PacketIdBytes=2). * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_publish.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_publish.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -299,10 +299,10 @@ using publish_packet = basic_publish_packet<2>; } // namespace async_mqtt::v3_1_1 -#include +#include #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V3_1_1_PUBLISH_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_PUBLISH_HPP diff --git a/include/async_mqtt/packet/v3_1_1_pubrec.hpp b/include/async_mqtt/protocol/packet/v3_1_1_pubrec.hpp similarity index 84% rename from include/async_mqtt/packet/v3_1_1_pubrec.hpp rename to include/async_mqtt/protocol/packet/v3_1_1_pubrec.hpp index fc2990336..e056bf48c 100644 --- a/include/async_mqtt/packet/v3_1_1_pubrec.hpp +++ b/include/async_mqtt/protocol/packet/v3_1_1_pubrec.hpp @@ -4,13 +4,13 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V3_1_1_PUBREC_HPP) -#define ASYNC_MQTT_PACKET_V3_1_1_PUBREC_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_PUBREC_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_PUBREC_HPP -#include +#include -#include -#include +#include +#include #include #include @@ -45,7 +45,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pubrec.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pubrec.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -99,7 +99,7 @@ class basic_pubrec_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -123,7 +123,7 @@ class basic_pubrec_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pubrec.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pubrec.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -138,7 +138,7 @@ bool operator<(basic_pubrec_packet const& lhs, basic_pubrec_packe * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pubrec.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pubrec.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -153,7 +153,7 @@ bool operator==(basic_pubrec_packet const& lhs, basic_pubrec_pack * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pubrec.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pubrec.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -166,7 +166,7 @@ std::ostream& operator<<(std::ostream& o, basic_pubrec_packet con * @brief Type alias of basic_pubrec_packet (PacketIdBytes=2). * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pubrec.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pubrec.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -175,7 +175,7 @@ using pubrec_packet = basic_pubrec_packet<2>; } // namespace async_mqtt::v3_1_1 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V3_1_1_PUBREC_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_PUBREC_HPP diff --git a/include/async_mqtt/packet/v3_1_1_pubrel.hpp b/include/async_mqtt/protocol/packet/v3_1_1_pubrel.hpp similarity index 85% rename from include/async_mqtt/packet/v3_1_1_pubrel.hpp rename to include/async_mqtt/protocol/packet/v3_1_1_pubrel.hpp index 89e5eccda..1680b566c 100644 --- a/include/async_mqtt/packet/v3_1_1_pubrel.hpp +++ b/include/async_mqtt/protocol/packet/v3_1_1_pubrel.hpp @@ -4,13 +4,13 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V3_1_1_PUBREL_HPP) -#define ASYNC_MQTT_PACKET_V3_1_1_PUBREL_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_PUBREL_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_PUBREL_HPP -#include +#include -#include -#include +#include +#include #include #include @@ -47,7 +47,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pubrel.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pubrel.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -101,7 +101,7 @@ class basic_pubrel_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -125,7 +125,7 @@ class basic_pubrel_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pubrel.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pubrel.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -140,7 +140,7 @@ bool operator<(basic_pubrel_packet const& lhs, basic_pubrel_packe * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pubrel.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pubrel.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -155,7 +155,7 @@ bool operator==(basic_pubrel_packet const& lhs, basic_pubrel_pack * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pubrel.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pubrel.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -168,7 +168,7 @@ std::ostream& operator<<(std::ostream& o, basic_pubrel_packet con * @brief Type alias of basic_pubrel_packet (PacketIdBytes=2). * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_pubrel.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_pubrel.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -177,7 +177,7 @@ using pubrel_packet = basic_pubrel_packet<2>; } // namespace async_mqtt::v3_1_1 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V3_1_1_PUBREL_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_PUBREL_HPP diff --git a/include/async_mqtt/packet/v3_1_1_suback.hpp b/include/async_mqtt/protocol/packet/v3_1_1_suback.hpp similarity index 84% rename from include/async_mqtt/packet/v3_1_1_suback.hpp rename to include/async_mqtt/protocol/packet/v3_1_1_suback.hpp index ff5c442ae..9e8864677 100644 --- a/include/async_mqtt/packet/v3_1_1_suback.hpp +++ b/include/async_mqtt/protocol/packet/v3_1_1_suback.hpp @@ -4,15 +4,15 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V3_1_1_SUBACK_HPP) -#define ASYNC_MQTT_PACKET_V3_1_1_SUBACK_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_SUBACK_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_SUBACK_HPP -#include -#include +#include +#include -#include -#include -#include +#include +#include +#include #include #include @@ -45,7 +45,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_suback.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_suback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -111,7 +111,7 @@ class basic_suback_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -139,7 +139,7 @@ class basic_suback_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_suback.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_suback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -154,7 +154,7 @@ bool operator<(basic_suback_packet const& lhs, basic_suback_packe * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_suback.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_suback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -169,7 +169,7 @@ bool operator==(basic_suback_packet const& lhs, basic_suback_pack * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_suback.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_suback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -182,7 +182,7 @@ std::ostream& operator<<(std::ostream& o, basic_suback_packet con * @brief Type alias of basic_suback_packet (PacketIdBytes=2). * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_suback.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_suback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -191,7 +191,7 @@ using suback_packet = basic_suback_packet<2>; } // namespace async_mqtt::v3_1_1 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V3_1_1_SUBACK_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_SUBACK_HPP diff --git a/include/async_mqtt/packet/v3_1_1_subscribe.hpp b/include/async_mqtt/protocol/packet/v3_1_1_subscribe.hpp similarity index 85% rename from include/async_mqtt/packet/v3_1_1_subscribe.hpp rename to include/async_mqtt/protocol/packet/v3_1_1_subscribe.hpp index 4391c0aaa..dcd8e6334 100644 --- a/include/async_mqtt/packet/v3_1_1_subscribe.hpp +++ b/include/async_mqtt/protocol/packet/v3_1_1_subscribe.hpp @@ -4,15 +4,15 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V3_1_1_SUBSCRIBE_HPP) -#define ASYNC_MQTT_PACKET_V3_1_1_SUBSCRIBE_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_SUBSCRIBE_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_SUBSCRIBE_HPP -#include +#include #include -#include -#include -#include +#include +#include +#include #include #include @@ -44,7 +44,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_subscribe.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_subscribe.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -105,7 +105,7 @@ class basic_subscribe_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -134,7 +134,7 @@ class basic_subscribe_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_subscribe.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_subscribe.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -149,7 +149,7 @@ bool operator<(basic_subscribe_packet const& lhs, basic_subscribe * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_subscribe.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_subscribe.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -164,7 +164,7 @@ bool operator==(basic_subscribe_packet const& lhs, basic_subscrib * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_subscribe.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_subscribe.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -177,7 +177,7 @@ std::ostream& operator<<(std::ostream& o, basic_subscribe_packet * @brief Type alias of basic_subscribe_packet (PacketIdBytes=2). * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_subscribe.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_subscribe.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -186,7 +186,7 @@ using subscribe_packet = basic_subscribe_packet<2>; } // namespace async_mqtt::v3_1_1 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V3_1_1_SUBSCRIBE_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_SUBSCRIBE_HPP diff --git a/include/async_mqtt/packet/v3_1_1_unsuback.hpp b/include/async_mqtt/protocol/packet/v3_1_1_unsuback.hpp similarity index 84% rename from include/async_mqtt/packet/v3_1_1_unsuback.hpp rename to include/async_mqtt/protocol/packet/v3_1_1_unsuback.hpp index a6943c17a..1b9840544 100644 --- a/include/async_mqtt/packet/v3_1_1_unsuback.hpp +++ b/include/async_mqtt/protocol/packet/v3_1_1_unsuback.hpp @@ -4,13 +4,13 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V3_1_1_UNSUBACK_HPP) -#define ASYNC_MQTT_PACKET_V3_1_1_UNSUBACK_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_UNSUBACK_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_UNSUBACK_HPP -#include +#include -#include -#include +#include +#include #include #include @@ -42,7 +42,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_unsuback.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_unsuback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -96,7 +96,7 @@ class basic_unsuback_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -120,7 +120,7 @@ class basic_unsuback_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_unsuback.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_unsuback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -135,7 +135,7 @@ bool operator<(basic_unsuback_packet const& lhs, basic_unsuback_p * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_unsuback.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_unsuback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -150,7 +150,7 @@ bool operator==(basic_unsuback_packet const& lhs, basic_unsuback_ * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_unsuback.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_unsuback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -163,7 +163,7 @@ std::ostream& operator<<(std::ostream& o, basic_unsuback_packet c * @brief Type alias of basic_unsuback_packet (PacketIdBytes=2). * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_unsuback.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_unsuback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -172,7 +172,7 @@ using unsuback_packet = basic_unsuback_packet<2>; } // namespace async_mqtt::v3_1_1 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V3_1_1_UNSUBACK_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_UNSUBACK_HPP diff --git a/include/async_mqtt/packet/v3_1_1_unsubscribe.hpp b/include/async_mqtt/protocol/packet/v3_1_1_unsubscribe.hpp similarity index 84% rename from include/async_mqtt/packet/v3_1_1_unsubscribe.hpp rename to include/async_mqtt/protocol/packet/v3_1_1_unsubscribe.hpp index 9b271e4a7..2772de2b6 100644 --- a/include/async_mqtt/packet/v3_1_1_unsubscribe.hpp +++ b/include/async_mqtt/protocol/packet/v3_1_1_unsubscribe.hpp @@ -4,19 +4,19 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V3_1_1_UNSUBSCRIBE_HPP) -#define ASYNC_MQTT_PACKET_V3_1_1_UNSUBSCRIBE_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_UNSUBSCRIBE_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_UNSUBSCRIBE_HPP -#include +#include #include #include #include -#include -#include -#include +#include +#include +#include /** * @defgroup unsubscribe_v3_1_1 UNSUBSCRIBE packet (v3.1.1) @@ -45,7 +45,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_unsubscribe.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_unsubscribe.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -106,7 +106,7 @@ class basic_unsubscribe_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -135,7 +135,7 @@ class basic_unsubscribe_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_unsubscribe.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_unsubscribe.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -150,7 +150,7 @@ bool operator<(basic_unsubscribe_packet const& lhs, basic_unsubsc * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_unsubscribe.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_unsubscribe.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -165,7 +165,7 @@ bool operator==(basic_unsubscribe_packet const& lhs, basic_unsubs * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v3_1_1_unsubscribe.hpp + * @li Header: async_mqtt/protocol/packet/v3_1_1_unsubscribe.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -178,7 +178,7 @@ std::ostream& operator<<(std::ostream& o, basic_unsubscribe_packet; } // namespace async_mqtt::v3_1_1 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V3_1_1_UNSUBSCRIBE_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V3_1_1_UNSUBSCRIBE_HPP diff --git a/include/async_mqtt/packet/v5_auth.hpp b/include/async_mqtt/protocol/packet/v5_auth.hpp similarity index 87% rename from include/async_mqtt/packet/v5_auth.hpp rename to include/async_mqtt/protocol/packet/v5_auth.hpp index 69b5b00b6..de59b5704 100644 --- a/include/async_mqtt/packet/v5_auth.hpp +++ b/include/async_mqtt/protocol/packet/v5_auth.hpp @@ -4,17 +4,17 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V5_AUTH_HPP) -#define ASYNC_MQTT_PACKET_V5_AUTH_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V5_AUTH_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V5_AUTH_HPP #include #include -#include -#include +#include +#include -#include -#include +#include +#include #include #include @@ -40,7 +40,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v5_auth.hpp + * @li Header: async_mqtt/protocol/packet/v5_auth.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -141,7 +141,7 @@ class auth_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -175,7 +175,7 @@ class auth_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_auth.hpp + * @li Header: async_mqtt/protocol/packet/v5_auth.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -189,7 +189,7 @@ bool operator<(auth_packet const& lhs, auth_packet const& rhs); * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_auth.hpp + * @li Header: async_mqtt/protocol/packet/v5_auth.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -198,7 +198,7 @@ bool operator==(auth_packet const& lhs, auth_packet const& rhs); } // namespace async_mqtt::v5 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V5_AUTH_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V5_AUTH_HPP diff --git a/include/async_mqtt/packet/v5_connack.hpp b/include/async_mqtt/protocol/packet/v5_connack.hpp similarity index 86% rename from include/async_mqtt/packet/v5_connack.hpp rename to include/async_mqtt/protocol/packet/v5_connack.hpp index 0a29e2044..89a0ffd16 100644 --- a/include/async_mqtt/packet/v5_connack.hpp +++ b/include/async_mqtt/protocol/packet/v5_connack.hpp @@ -4,14 +4,14 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V5_CONNACK_HPP) -#define ASYNC_MQTT_PACKET_V5_CONNACK_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V5_CONNACK_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V5_CONNACK_HPP -#include -#include +#include +#include -#include -#include +#include +#include #include #include @@ -37,7 +37,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v5_connack.hpp + * @li Header: async_mqtt/protocol/packet/v5_connack.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -108,7 +108,7 @@ class connack_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -142,7 +142,7 @@ class connack_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_connack.hpp + * @li Header: async_mqtt/protocol/packet/v5_connack.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -156,7 +156,7 @@ bool operator<(connack_packet const& lhs, connack_packet const& rhs); * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_connack.hpp + * @li Header: async_mqtt/protocol/packet/v5_connack.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -170,7 +170,7 @@ bool operator==(connack_packet const& lhs, connack_packet const& rhs); * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v5_connack.hpp + * @li Header: async_mqtt/protocol/packet/v5_connack.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -179,7 +179,7 @@ std::ostream& operator<<(std::ostream& o, connack_packet const& v); } // namespace async_mqtt::v5 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V5_CONNACK_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V5_CONNACK_HPP diff --git a/include/async_mqtt/packet/v5_connect.hpp b/include/async_mqtt/protocol/packet/v5_connect.hpp similarity index 92% rename from include/async_mqtt/packet/v5_connect.hpp rename to include/async_mqtt/protocol/packet/v5_connect.hpp index a2e8cc0eb..22cbd53a5 100644 --- a/include/async_mqtt/packet/v5_connect.hpp +++ b/include/async_mqtt/protocol/packet/v5_connect.hpp @@ -4,18 +4,18 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V5_CONNECT_HPP) -#define ASYNC_MQTT_PACKET_V5_CONNECT_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V5_CONNECT_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V5_CONNECT_HPP #include #include -#include -#include +#include +#include -#include -#include -#include +#include +#include +#include #include #include @@ -42,7 +42,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v5_connect.hpp + * @li Header: async_mqtt/protocol/packet/v5_connect.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -198,7 +198,7 @@ class connect_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -248,7 +248,7 @@ class connect_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_connect.hpp + * @li Header: async_mqtt/protocol/packet/v5_connect.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -262,7 +262,7 @@ bool operator<(connect_packet const& lhs, connect_packet const& rhs); * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_connect.hpp + * @li Header: async_mqtt/protocol/packet/v5_connect.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -276,7 +276,7 @@ bool operator==(connect_packet const& lhs, connect_packet const& rhs); * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v5_connect.hpp + * @li Header: async_mqtt/protocol/packet/v5_connect.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -285,7 +285,7 @@ std::ostream& operator<<(std::ostream& o, connect_packet const& v); } // namespace async_mqtt::v5 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V5_CONNECT_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V5_CONNECT_HPP diff --git a/include/async_mqtt/packet/v5_disconnect.hpp b/include/async_mqtt/protocol/packet/v5_disconnect.hpp similarity index 88% rename from include/async_mqtt/packet/v5_disconnect.hpp rename to include/async_mqtt/protocol/packet/v5_disconnect.hpp index 4e611f16a..6c586cdec 100644 --- a/include/async_mqtt/packet/v5_disconnect.hpp +++ b/include/async_mqtt/protocol/packet/v5_disconnect.hpp @@ -4,14 +4,14 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V5_DISCONNECT_HPP) -#define ASYNC_MQTT_PACKET_V5_DISCONNECT_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V5_DISCONNECT_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V5_DISCONNECT_HPP -#include -#include +#include +#include -#include -#include +#include +#include #include #include @@ -43,7 +43,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v5_disconnect.hpp + * @li Header: async_mqtt/protocol/packet/v5_disconnect.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -140,7 +140,7 @@ class disconnect_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -179,7 +179,7 @@ class disconnect_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_disconnect.hpp + * @li Header: async_mqtt/protocol/packet/v5_disconnect.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -193,7 +193,7 @@ bool operator<(disconnect_packet const& lhs, disconnect_packet const& rhs); * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_disconnect.hpp + * @li Header: async_mqtt/protocol/packet/v5_disconnect.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -202,7 +202,7 @@ bool operator==(disconnect_packet const& lhs, disconnect_packet const& rhs); } // namespace async_mqtt::v5 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V5_DISCONNECT_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V5_DISCONNECT_HPP diff --git a/include/async_mqtt/packet/v5_pingreq.hpp b/include/async_mqtt/protocol/packet/v5_pingreq.hpp similarity index 84% rename from include/async_mqtt/packet/v5_pingreq.hpp rename to include/async_mqtt/protocol/packet/v5_pingreq.hpp index 41e2ab824..283d9a61e 100644 --- a/include/async_mqtt/packet/v5_pingreq.hpp +++ b/include/async_mqtt/protocol/packet/v5_pingreq.hpp @@ -4,13 +4,13 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V5_PINGREQ_HPP) -#define ASYNC_MQTT_PACKET_V5_PINGREQ_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V5_PINGREQ_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V5_PINGREQ_HPP -#include -#include +#include +#include -#include +#include #include #include @@ -43,7 +43,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v5_pingreq.hpp + * @li Header: async_mqtt/protocol/packet/v5_pingreq.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -87,7 +87,7 @@ class pingreq_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -110,7 +110,7 @@ class pingreq_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_pingreq.hpp + * @li Header: async_mqtt/protocol/packet/v5_pingreq.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -124,7 +124,7 @@ bool operator<(pingreq_packet const& lhs, pingreq_packet const& rhs); * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_pingreq.hpp + * @li Header: async_mqtt/protocol/packet/v5_pingreq.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -138,7 +138,7 @@ bool operator==(pingreq_packet const& lhs, pingreq_packet const& rhs); * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v5_pingreq.hpp + * @li Header: async_mqtt/protocol/packet/v5_pingreq.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -147,7 +147,7 @@ std::ostream& operator<<(std::ostream& o, pingreq_packet const& v); } // namespace async_mqtt::v5 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V5_PINGREQ_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V5_PINGREQ_HPP diff --git a/include/async_mqtt/packet/v5_pingresp.hpp b/include/async_mqtt/protocol/packet/v5_pingresp.hpp similarity index 84% rename from include/async_mqtt/packet/v5_pingresp.hpp rename to include/async_mqtt/protocol/packet/v5_pingresp.hpp index 4e3be57c6..f121318b3 100644 --- a/include/async_mqtt/packet/v5_pingresp.hpp +++ b/include/async_mqtt/protocol/packet/v5_pingresp.hpp @@ -4,18 +4,18 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V5_PINGRESP_HPP) -#define ASYNC_MQTT_PACKET_V5_PINGRESP_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V5_PINGRESP_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V5_PINGRESP_HPP #include #include #include -#include -#include +#include +#include -#include +#include #include #include @@ -50,7 +50,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v5_pingresp.hpp + * @li Header: async_mqtt/protocol/packet/v5_pingresp.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -94,7 +94,7 @@ class pingresp_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -117,7 +117,7 @@ class pingresp_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_pingresp.hpp + * @li Header: async_mqtt/protocol/packet/v5_pingresp.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -131,7 +131,7 @@ bool operator<(pingresp_packet const& lhs, pingresp_packet const& rhs); * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_pingresp.hpp + * @li Header: async_mqtt/protocol/packet/v5_pingresp.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -145,7 +145,7 @@ bool operator==(pingresp_packet const& lhs, pingresp_packet const& rhs); * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v5_pingresp.hpp + * @li Header: async_mqtt/protocol/packet/v5_pingresp.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -154,7 +154,7 @@ std::ostream& operator<<(std::ostream& o, pingresp_packet const& v); } // namespace async_mqtt::v5 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V5_PINGRESP_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V5_PINGRESP_HPP diff --git a/include/async_mqtt/packet/v5_puback.hpp b/include/async_mqtt/protocol/packet/v5_puback.hpp similarity index 89% rename from include/async_mqtt/packet/v5_puback.hpp rename to include/async_mqtt/protocol/packet/v5_puback.hpp index 617a57197..07fdb4838 100644 --- a/include/async_mqtt/packet/v5_puback.hpp +++ b/include/async_mqtt/protocol/packet/v5_puback.hpp @@ -4,15 +4,15 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V5_PUBACK_HPP) -#define ASYNC_MQTT_PACKET_V5_PUBACK_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V5_PUBACK_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V5_PUBACK_HPP -#include -#include +#include +#include -#include -#include -#include +#include +#include +#include #include #include @@ -47,7 +47,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v5_puback.hpp + * @li Header: async_mqtt/protocol/packet/v5_puback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -160,7 +160,7 @@ class basic_puback_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -202,7 +202,7 @@ class basic_puback_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_puback.hpp + * @li Header: async_mqtt/protocol/packet/v5_puback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -217,7 +217,7 @@ bool operator<(basic_puback_packet const& lhs, basic_puback_packe * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_puback.hpp + * @li Header: async_mqtt/protocol/packet/v5_puback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -230,7 +230,7 @@ bool operator==(basic_puback_packet const& lhs, basic_puback_pack * @brief Type alias of basic_puback_packet (PacketIdBytes=2). * * #### Requirements - * @li Header: async_mqtt/packet/v5_puback.hpp + * @li Header: async_mqtt/protocol/packet/v5_puback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -239,7 +239,7 @@ using puback_packet = basic_puback_packet<2>; } // namespace async_mqtt::v5 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V5_PUBACK_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V5_PUBACK_HPP diff --git a/include/async_mqtt/packet/v5_pubcomp.hpp b/include/async_mqtt/protocol/packet/v5_pubcomp.hpp similarity index 89% rename from include/async_mqtt/packet/v5_pubcomp.hpp rename to include/async_mqtt/protocol/packet/v5_pubcomp.hpp index ce9ed637f..286123699 100644 --- a/include/async_mqtt/packet/v5_pubcomp.hpp +++ b/include/async_mqtt/protocol/packet/v5_pubcomp.hpp @@ -4,15 +4,15 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V5_PUBCOMP_HPP) -#define ASYNC_MQTT_PACKET_V5_PUBCOMP_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V5_PUBCOMP_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V5_PUBCOMP_HPP -#include -#include +#include +#include -#include -#include -#include +#include +#include +#include #include #include @@ -48,7 +48,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v5_pubcomp.hpp + * @li Header: async_mqtt/protocol/packet/v5_pubcomp.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -158,7 +158,7 @@ class basic_pubcomp_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -200,7 +200,7 @@ class basic_pubcomp_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_pubcomp.hpp + * @li Header: async_mqtt/protocol/packet/v5_pubcomp.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -215,7 +215,7 @@ bool operator<(basic_pubcomp_packet const& lhs, basic_pubcomp_pac * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_pubcomp.hpp + * @li Header: async_mqtt/protocol/packet/v5_pubcomp.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -228,7 +228,7 @@ bool operator==(basic_pubcomp_packet const& lhs, basic_pubcomp_pa * @brief Type alias of basic_pubcomp_packet (PacketIdBytes=2). * * #### Requirements - * @li Header: async_mqtt/packet/v5_pubcomp.hpp + * @li Header: async_mqtt/protocol/packet/v5_pubcomp.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -237,7 +237,7 @@ using pubcomp_packet = basic_pubcomp_packet<2>; } // namespace async_mqtt::v5 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V5_PUBCOMP_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V5_PUBCOMP_HPP diff --git a/include/async_mqtt/packet/v5_publish.hpp b/include/async_mqtt/protocol/packet/v5_publish.hpp similarity index 91% rename from include/async_mqtt/packet/v5_publish.hpp rename to include/async_mqtt/protocol/packet/v5_publish.hpp index 333ecb9d5..c90e7aa24 100644 --- a/include/async_mqtt/packet/v5_publish.hpp +++ b/include/async_mqtt/protocol/packet/v5_publish.hpp @@ -4,17 +4,17 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V5_PUBLISH_HPP) -#define ASYNC_MQTT_PACKET_V5_PUBLISH_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V5_PUBLISH_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V5_PUBLISH_HPP -#include -#include +#include +#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include #include #include @@ -55,7 +55,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v5_publish.hpp + * @li Header: async_mqtt/protocol/packet/v5_publish.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -269,7 +269,7 @@ class basic_publish_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -315,7 +315,7 @@ class basic_publish_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_publish.hpp + * @li Header: async_mqtt/protocol/packet/v5_publish.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -330,7 +330,7 @@ bool operator<(basic_publish_packet const& lhs, basic_publish_pac * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_publish.hpp + * @li Header: async_mqtt/protocol/packet/v5_publish.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -345,7 +345,7 @@ bool operator==(basic_publish_packet const& lhs, basic_publish_pa * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v5_publish.hpp + * @li Header: async_mqtt/protocol/packet/v5_publish.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -358,7 +358,7 @@ std::ostream& operator<<(std::ostream& o, basic_publish_packet co * @brief Type alias of basic_publish_packet (PacketIdBytes=2). * * #### Requirements - * @li Header: async_mqtt/packet/v5_publish.hpp + * @li Header: async_mqtt/protocol/packet/v5_publish.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -366,10 +366,10 @@ using publish_packet = basic_publish_packet<2>; } // namespace async_mqtt::v5 -#include +#include #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V5_PUBLISH_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V5_PUBLISH_HPP diff --git a/include/async_mqtt/packet/v5_pubrec.hpp b/include/async_mqtt/protocol/packet/v5_pubrec.hpp similarity index 89% rename from include/async_mqtt/packet/v5_pubrec.hpp rename to include/async_mqtt/protocol/packet/v5_pubrec.hpp index 2671d937f..59a303a1c 100644 --- a/include/async_mqtt/packet/v5_pubrec.hpp +++ b/include/async_mqtt/protocol/packet/v5_pubrec.hpp @@ -4,15 +4,15 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V5_PUBREC_HPP) -#define ASYNC_MQTT_PACKET_V5_PUBREC_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V5_PUBREC_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V5_PUBREC_HPP -#include -#include +#include +#include -#include -#include -#include +#include +#include +#include #include #include @@ -47,7 +47,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v5_pubrec.hpp + * @li Header: async_mqtt/protocol/packet/v5_pubrec.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -164,7 +164,7 @@ class basic_pubrec_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -200,7 +200,7 @@ class basic_pubrec_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_pubrec.hpp + * @li Header: async_mqtt/protocol/packet/v5_pubrec.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -215,7 +215,7 @@ bool operator<(basic_pubrec_packet const& lhs, basic_pubrec_packe * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_pubrec.hpp + * @li Header: async_mqtt/protocol/packet/v5_pubrec.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -228,7 +228,7 @@ bool operator==(basic_pubrec_packet const& lhs, basic_pubrec_pack * @brief Type alias of basic_pubrec_packet (PacketIdBytes=2). * * #### Requirements - * @li Header: async_mqtt/packet/v5_pubrec.hpp + * @li Header: async_mqtt/protocol/packet/v5_pubrec.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -237,7 +237,7 @@ using pubrec_packet = basic_pubrec_packet<2>; } // namespace async_mqtt::v5 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V5_PUBREC_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V5_PUBREC_HPP diff --git a/include/async_mqtt/packet/v5_pubrel.hpp b/include/async_mqtt/protocol/packet/v5_pubrel.hpp similarity index 89% rename from include/async_mqtt/packet/v5_pubrel.hpp rename to include/async_mqtt/protocol/packet/v5_pubrel.hpp index 88ec2b2b6..8e130762b 100644 --- a/include/async_mqtt/packet/v5_pubrel.hpp +++ b/include/async_mqtt/protocol/packet/v5_pubrel.hpp @@ -4,15 +4,15 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V5_PUBREL_HPP) -#define ASYNC_MQTT_PACKET_V5_PUBREL_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V5_PUBREL_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V5_PUBREL_HPP -#include -#include +#include +#include -#include -#include -#include +#include +#include +#include #include #include @@ -48,7 +48,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v5_pubrel.hpp + * @li Header: async_mqtt/protocol/packet/v5_pubrel.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -165,7 +165,7 @@ class basic_pubrel_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -201,7 +201,7 @@ class basic_pubrel_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_pubrel.hpp + * @li Header: async_mqtt/protocol/packet/v5_pubrel.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -216,7 +216,7 @@ bool operator<(basic_pubrel_packet const& lhs, basic_pubrel_packe * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_pubrel.hpp + * @li Header: async_mqtt/protocol/packet/v5_pubrel.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -229,7 +229,7 @@ bool operator==(basic_pubrel_packet const& lhs, basic_pubrel_pack * @brief Type alias of basic_pubrel_packet (PacketIdBytes=2). * * #### Requirements - * @li Header: async_mqtt/packet/v5_pubrel.hpp + * @li Header: async_mqtt/protocol/packet/v5_pubrel.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -238,7 +238,7 @@ using pubrel_packet = basic_pubrel_packet<2>; } // namespace async_mqtt::v5 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V5_PUBREL_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V5_PUBREL_HPP diff --git a/include/async_mqtt/packet/v5_suback.hpp b/include/async_mqtt/protocol/packet/v5_suback.hpp similarity index 84% rename from include/async_mqtt/packet/v5_suback.hpp rename to include/async_mqtt/protocol/packet/v5_suback.hpp index abb441bb6..2a77cdbce 100644 --- a/include/async_mqtt/packet/v5_suback.hpp +++ b/include/async_mqtt/protocol/packet/v5_suback.hpp @@ -4,16 +4,16 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V5_SUBACK_HPP) -#define ASYNC_MQTT_PACKET_V5_SUBACK_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V5_SUBACK_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V5_SUBACK_HPP -#include -#include +#include +#include -#include -#include -#include -#include +#include +#include +#include +#include #include #include @@ -45,7 +45,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v5_suback.hpp + * @li Header: async_mqtt/protocol/packet/v5_suback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -114,7 +114,7 @@ class basic_suback_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -146,7 +146,7 @@ class basic_suback_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_suback.hpp + * @li Header: async_mqtt/protocol/packet/v5_suback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -161,7 +161,7 @@ bool operator<(basic_suback_packet const& lhs, basic_suback_packe * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_suback.hpp + * @li Header: async_mqtt/protocol/packet/v5_suback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -176,7 +176,7 @@ bool operator==(basic_suback_packet const& lhs, basic_suback_pack * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v5_suback.hpp + * @li Header: async_mqtt/protocol/packet/v5_suback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -189,7 +189,7 @@ std::ostream& operator<<(std::ostream& o, basic_suback_packet con * @brief Type alias of basic_suback_packet (PacketIdBytes=2). * * #### Requirements - * @li Header: async_mqtt/packet/v5_suback.hpp + * @li Header: async_mqtt/protocol/packet/v5_suback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -198,7 +198,7 @@ using suback_packet = basic_suback_packet<2>; } // namespace async_mqtt::v5 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V5_SUBACK_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V5_SUBACK_HPP diff --git a/include/async_mqtt/packet/v5_subscribe.hpp b/include/async_mqtt/protocol/packet/v5_subscribe.hpp similarity index 84% rename from include/async_mqtt/packet/v5_subscribe.hpp rename to include/async_mqtt/protocol/packet/v5_subscribe.hpp index 3dcd50361..80f67bfc2 100644 --- a/include/async_mqtt/packet/v5_subscribe.hpp +++ b/include/async_mqtt/protocol/packet/v5_subscribe.hpp @@ -4,16 +4,16 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V5_SUBSCRIBE_HPP) -#define ASYNC_MQTT_PACKET_V5_SUBSCRIBE_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V5_SUBSCRIBE_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V5_SUBSCRIBE_HPP -#include -#include +#include +#include -#include -#include -#include -#include +#include +#include +#include +#include #include #include @@ -45,7 +45,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v5_subscribe.hpp + * @li Header: async_mqtt/protocol/packet/v5_subscribe.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -115,7 +115,7 @@ class basic_subscribe_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -148,7 +148,7 @@ class basic_subscribe_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_subscribe.hpp + * @li Header: async_mqtt/protocol/packet/v5_subscribe.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -163,7 +163,7 @@ bool operator<(basic_subscribe_packet const& lhs, basic_subscribe * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_subscribe.hpp + * @li Header: async_mqtt/protocol/packet/v5_subscribe.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -178,7 +178,7 @@ bool operator==(basic_subscribe_packet const& lhs, basic_subscrib * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v5_subscribe.hpp + * @li Header: async_mqtt/protocol/packet/v5_subscribe.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -191,7 +191,7 @@ std::ostream& operator<<(std::ostream& o, basic_subscribe_packet * @brief Type alias of basic_subscribe_packet (PacketIdBytes=2). * * #### Requirements - * @li Header: async_mqtt/packet/v5_subscribe.hpp + * @li Header: async_mqtt/protocol/packet/v5_subscribe.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -200,7 +200,7 @@ using subscribe_packet = basic_subscribe_packet<2>; } // namespace async_mqtt::v5 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V5_SUBSCRIBE_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V5_SUBSCRIBE_HPP diff --git a/include/async_mqtt/packet/v5_unsuback.hpp b/include/async_mqtt/protocol/packet/v5_unsuback.hpp similarity index 85% rename from include/async_mqtt/packet/v5_unsuback.hpp rename to include/async_mqtt/protocol/packet/v5_unsuback.hpp index 848a240ec..23c328e18 100644 --- a/include/async_mqtt/packet/v5_unsuback.hpp +++ b/include/async_mqtt/protocol/packet/v5_unsuback.hpp @@ -4,15 +4,15 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V5_UNSUBACK_HPP) -#define ASYNC_MQTT_PACKET_V5_UNSUBACK_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V5_UNSUBACK_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V5_UNSUBACK_HPP -#include -#include +#include +#include -#include -#include -#include +#include +#include +#include #include #include @@ -44,7 +44,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v5_unsuback.hpp + * @li Header: async_mqtt/protocol/packet/v5_unsuback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -113,7 +113,7 @@ class basic_unsuback_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -145,7 +145,7 @@ class basic_unsuback_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_unsuback.hpp + * @li Header: async_mqtt/protocol/packet/v5_unsuback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -160,7 +160,7 @@ bool operator<(basic_unsuback_packet const& lhs, basic_unsuback_p * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_unsuback.hpp + * @li Header: async_mqtt/protocol/packet/v5_unsuback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -175,7 +175,7 @@ bool operator==(basic_unsuback_packet const& lhs, basic_unsuback_ * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v5_unsuback.hpp + * @li Header: async_mqtt/protocol/packet/v5_unsuback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -188,7 +188,7 @@ std::ostream& operator<<(std::ostream& o, basic_unsuback_packet c * @brief Type alias of basic_unsuback_packet (PacketIdBytes=2). * * #### Requirements - * @li Header: async_mqtt/packet/v5_unsuback.hpp + * @li Header: async_mqtt/protocol/packet/v5_unsuback.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -197,7 +197,7 @@ using unsuback_packet = basic_unsuback_packet<2>; } // namespace async_mqtt::v5 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V5_UNSUBACK_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V5_UNSUBACK_HPP diff --git a/include/async_mqtt/packet/v5_unsubscribe.hpp b/include/async_mqtt/protocol/packet/v5_unsubscribe.hpp similarity index 84% rename from include/async_mqtt/packet/v5_unsubscribe.hpp rename to include/async_mqtt/protocol/packet/v5_unsubscribe.hpp index 24df91dab..9bfbbe123 100644 --- a/include/async_mqtt/packet/v5_unsubscribe.hpp +++ b/include/async_mqtt/protocol/packet/v5_unsubscribe.hpp @@ -4,17 +4,17 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_V5_UNSUBSCRIBE_HPP) -#define ASYNC_MQTT_PACKET_V5_UNSUBSCRIBE_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_V5_UNSUBSCRIBE_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_V5_UNSUBSCRIBE_HPP -#include -#include +#include +#include -#include -#include -#include -#include +#include +#include +#include +#include #include #include @@ -46,7 +46,7 @@ namespace as = boost::asio; * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/v5_unsubscribe.hpp + * @li Header: async_mqtt/protocol/packet/v5_unsubscribe.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -116,7 +116,7 @@ class basic_unsubscribe_packet { private: template - friend basic_packet_variant + friend std::optional> async_mqtt::buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); #if defined(ASYNC_MQTT_UNIT_TEST_FOR_PACKET) @@ -149,7 +149,7 @@ class basic_unsubscribe_packet { * @return true if the lhs less than the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_unsubscribe.hpp + * @li Header: async_mqtt/protocol/packet/v5_unsubscribe.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -164,7 +164,7 @@ bool operator<(basic_unsubscribe_packet const& lhs, basic_unsubsc * @return true if the lhs equal to the rhs, otherwise false. * * #### Requirements - * @li Header: async_mqtt/packet/v5_unsubscribe.hpp + * @li Header: async_mqtt/protocol/packet/v5_unsubscribe.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -179,7 +179,7 @@ bool operator==(basic_unsubscribe_packet const& lhs, basic_unsubs * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/v5_unsubscribe.hpp + * @li Header: async_mqtt/protocol/packet/v5_unsubscribe.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -192,7 +192,7 @@ std::ostream& operator<<(std::ostream& o, basic_unsubscribe_packet; } // namespace async_mqtt::v5 #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#include +#include #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) -#endif // ASYNC_MQTT_PACKET_V5_UNSUBSCRIBE_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_V5_UNSUBSCRIBE_HPP diff --git a/include/async_mqtt/packet/will.hpp b/include/async_mqtt/protocol/packet/will.hpp similarity index 92% rename from include/async_mqtt/packet/will.hpp rename to include/async_mqtt/protocol/packet/will.hpp index 49db746a4..a4e1aae77 100644 --- a/include/async_mqtt/packet/will.hpp +++ b/include/async_mqtt/protocol/packet/will.hpp @@ -4,12 +4,12 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PACKET_WILL_HPP) -#define ASYNC_MQTT_PACKET_WILL_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PACKET_WILL_HPP) +#define ASYNC_MQTT_PROTOCOL_PACKET_WILL_HPP #include -#include -#include +#include +#include #include namespace async_mqtt { @@ -24,7 +24,7 @@ namespace async_mqtt { * @li Shared objects: Unsafe * * #### Requirements - * @li Header: async_mqtt/packet/will.hpp + * @li Header: async_mqtt/protocol/packet/will.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -184,7 +184,7 @@ class will { * @return output stream * * #### Requirements - * @li Header: async_mqtt/packet/will.hpp + * @li Header: async_mqtt/protocol/packet/will.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -203,4 +203,4 @@ inline std::ostream& operator<<(std::ostream& o, will const& v) { } // namespace async_mqtt -#endif // ASYNC_MQTT_PACKET_WILL_HPP +#endif // ASYNC_MQTT_PROTOCOL_PACKET_WILL_HPP diff --git a/include/async_mqtt/protocol_version.hpp b/include/async_mqtt/protocol/protocol_version.hpp similarity index 82% rename from include/async_mqtt/protocol_version.hpp rename to include/async_mqtt/protocol/protocol_version.hpp index be462f173..3093a3c62 100644 --- a/include/async_mqtt/protocol_version.hpp +++ b/include/async_mqtt/protocol/protocol_version.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_PROTOCOL_VERSION_HPP) -#define ASYNC_MQTT_PROTOCOL_VERSION_HPP +#if !defined(ASYNC_MQTT_PROTOCOL_PROTOCOL_VERSION_HPP) +#define ASYNC_MQTT_PROTOCOL_PROTOCOL_VERSION_HPP #include #include @@ -22,7 +22,7 @@ namespace async_mqtt { * @brief MQTT protocol version * * #### Requirements - * @li Header: async_mqtt/protocol_version.hpp + * @li Header: async_mqtt/protocol/protocol_version.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -39,7 +39,7 @@ enum class protocol_version { * @return version string * * #### Requirements - * @li Header: async_mqtt/protocol_version.hpp + * @li Header: async_mqtt/protocol/protocol_version.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -60,7 +60,7 @@ constexpr char const* protocol_version_to_str(protocol_version v) { * @return output stream * * #### Requirements - * @li Header: async_mqtt/protocol_version.hpp + * @li Header: async_mqtt/protocol/protocol_version.hpp * @li Convenience header: async_mqtt/all.hpp * */ @@ -73,4 +73,4 @@ std::ostream& operator<<(std::ostream& os, protocol_version val) } // namespace async_mqtt -#endif // ASYNC_MQTT_PROTOCOL_VERSION_HPP +#endif // ASYNC_MQTT_PROTOCOL_PROTOCOL_VERSION_HPP diff --git a/include/async_mqtt/role.hpp b/include/async_mqtt/protocol/role.hpp similarity index 87% rename from include/async_mqtt/role.hpp rename to include/async_mqtt/protocol/role.hpp index 21a54b7dd..d92c2ae87 100644 --- a/include/async_mqtt/role.hpp +++ b/include/async_mqtt/protocol/role.hpp @@ -4,8 +4,8 @@ // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#if !defined(ASYNC_MQTT_ROLE_HPP) -#define ASYNC_MQTT_ROLE_HPP +#if !defined(ASYNC_MQTT_ASYNC_MQTT_ROLE_HPP) +#define ASYNC_MQTT_ASYNC_MQTT_ROLE_HPP /** * @defgroup role MQTT connection role (client, server or both) @@ -32,4 +32,4 @@ enum class role { } // namespace async_mqtt -#endif // ASYNC_MQTT_ROLE_HPP +#endif // ASYNC_MQTT_ASYNC_MQTT_ROLE_HPP diff --git a/include/async_mqtt/protocol/rv_connection.hpp b/include/async_mqtt/protocol/rv_connection.hpp new file mode 100644 index 000000000..146a41589 --- /dev/null +++ b/include/async_mqtt/protocol/rv_connection.hpp @@ -0,0 +1,85 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_PROTOCOL_RV_CONNECTION_HPP) +#define ASYNC_MQTT_PROTOCOL_RV_CONNECTION_HPP + +#include +#include + +namespace async_mqtt { + +template +class basic_rv_connection : public basic_connection { + using base_type = basic_connection; + +public: + basic_rv_connection(protocol_version ver); + + template + std::vector> + send(Packet packet); + + std::vector> + recv(std::istream& is); + + std::vector> + notify_timer_fired(timer_kind kind); + + std::vector> + set_pingreq_send_interval( + std::chrono::milliseconds duration + ); + + /** + * @brief release packet_id. + * @param packet_id packet_id to release + * @return event list + */ + std::vector> + release_packet_id(typename basic_packet_id_type::type packet_id); + +private: + + void on_error(error_code ec) override final; + + void on_send( + basic_packet_variant packet, + std::optional::type> + release_packet_id_if_send_error = std::nullopt + ) override final; + + void on_packet_id_release( + typename basic_packet_id_type::type packet_id + ) override final; + + void on_receive( + basic_packet_variant packet + ) override final; + + void on_timer_op( + timer_op op, + timer_kind kind, + std::optional ms = std::nullopt + ) override final; + + void on_close() override final; + +private: + std::vector> events_; +}; + +template +using rv_connection = basic_rv_connection; + +} // namespace async_mqtt + +#include +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + +#endif // ASYNC_MQTT_PROTOCOL_RV_CONNECTION_HPP diff --git a/include/async_mqtt/protocol/timer.hpp b/include/async_mqtt/protocol/timer.hpp new file mode 100644 index 000000000..53badc76e --- /dev/null +++ b/include/async_mqtt/protocol/timer.hpp @@ -0,0 +1,42 @@ +// Copyright Takatoshi Kondo 2024 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_PROTOCOL_TIMER_HPP) +#define ASYNC_MQTT_PROTOCOL_TIMER_HPP + +#include + +namespace async_mqtt { + +enum class timer_kind { + pingreq_send, + pingreq_recv, + pingresp_recv, +}; + +enum class timer_op { + set, + reset, + cancel +}; + +constexpr +char const* timer_kind_to_string(timer_kind v); + +std::ostream& operator<<(std::ostream& o, timer_kind v); + +constexpr +char const* timer_op_to_string(timer_op v); + +std::ostream& operator<<(std::ostream& o, timer_op v); + +} // namespace async_mqtt + +#if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) +#include +#endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) + +#endif // ASYNC_MQTT_PROTOCOL_TIMER_HPP diff --git a/include/async_mqtt/src.hpp b/include/async_mqtt/src.hpp deleted file mode 100644 index f55a9ba6b..000000000 --- a/include/async_mqtt/src.hpp +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright Takatoshi Kondo 2024 -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#if !defined(ASYNC_MQTT_SRC_HPP) -#define ASYNC_MQTT_SRC_HPP - -#ifndef ASYNC_MQTT_SEPARATE_COMPILATION -#error You need to define ASYNC_MQTT_SEPARATE_COMPILATION in all translation units that use the compiled version of async_mqtt, \ - as well as the one where this file is included. -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#endif // ASYNC_MQTT_SRC_HPP diff --git a/include/async_mqtt/stream_customize.hpp b/include/async_mqtt/stream_customize.hpp new file mode 100644 index 000000000..1498a1787 --- /dev/null +++ b/include/async_mqtt/stream_customize.hpp @@ -0,0 +1,107 @@ +// Copyright Takatoshi Kondo 2022 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#if !defined(ASYNC_MQTT_IMPL_STREAM_CUSTOMIZE_HPP) +#define ASYNC_MQTT_IMPL_STREAM_CUSTOMIZE_HPP + +#include +#include + +#include +#include + +#include + +namespace async_mqtt { + +namespace as = boost::asio; + +/** + * @defgroup underlying_customize underlying layer customization + * @ingroup underlying_layer + */ + +/** + * @ingroup underlying_customize + * @brief customization class template for underlying layer + * In order to adapt your layer to async_mqtt, specialize the class template. + * @tparam Layer Specialized parameter for your own layer + */ +template +struct layer_customize; + +// initialze + +template +struct has_initialize : std::false_type {}; + +template +struct has_initialize< + Layer, + std::void_t< + decltype(layer_customize::initialize(std::declval())) + > +> : std::true_type {}; + +// async_read_some + +template +struct has_async_read_some : std::false_type {}; + +template +struct has_async_read_some< + Layer, + std::void_t< + decltype( + layer_customize::async_read_some( + std::declval(), + std::declval(), + std::declval>() + ) + ) + > +> : std::true_type {}; + +// async_write + +template +struct has_async_write : std::false_type {}; + +template +struct has_async_write< + Layer, + std::void_t< + decltype( + layer_customize::async_write( + std::declval(), + std::declval const&>(), + std::declval>() + ) + ) + > +> : std::true_type {}; + +// async_close + +template +struct has_async_close : std::false_type {}; + +template +struct has_async_close< + Layer, + std::void_t< + decltype( + layer_customize::async_close( + std::declval(), + std::declval>() + ) + ) + > +> : std::true_type {}; + +} // namespace async_mqtt + +#endif // ASYNC_MQTT_IMPL_STREAM_CUSTOMIZE_HPP diff --git a/include/async_mqtt/util/impl/stream_read_packet.hpp b/include/async_mqtt/util/impl/stream_read_packet.hpp deleted file mode 100644 index 750386767..000000000 --- a/include/async_mqtt/util/impl/stream_read_packet.hpp +++ /dev/null @@ -1,398 +0,0 @@ -// Copyright Takatoshi Kondo 2022 -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#if !defined(ASYNC_MQTT_UTIL_IMPL_STREAM_READ_PACKET_HPP) -#define ASYNC_MQTT_UTIL_IMPL_STREAM_READ_PACKET_HPP - -#include -#include -#include - -namespace async_mqtt { - -namespace detail { - -template -struct stream_impl::stream_read_packet_op { - using stream_type = this_type; - using stream_type_sp = std::shared_ptr; - using next_layer_type = stream_type::next_layer_type; - - std::shared_ptr strm; - std::size_t received = 0; - std::uint32_t mul = 1; - std::uint32_t rl = 0; - std::size_t rl_expected = 2; - std::shared_ptr spca = nullptr; - enum { dispatch, post, work, remaining_length, complete } state = dispatch; - - template - void operator()( - Self& self - ) { - auto& a_strm{*strm}; - switch (state) { - case dispatch: { - state = post; - as::dispatch( - a_strm.get_executor(), - force_move(self) - ); - } break; - case post: { - state = work; - a_strm.read_queue_.post( - force_move(self) - ); - a_strm.read_queue_.try_execute(); - } break; - case work: { - a_strm.read_queue_.start_work(); - if (a_strm.bulk_read_buffer_size_ == 0) { - // start non bulk read - state = remaining_length; - // read fixed_header + first remaining_length - a_strm.header_remaining_length_buf_.resize(5); - auto address = &a_strm.header_remaining_length_buf_[received]; - if constexpr ( - has_async_read::value) { - layer_customize::async_read( - a_strm.nl_, - as::buffer(address, 2), - force_move(self) - ); - } - else { - async_read( - a_strm.nl_, - as::buffer(address, 2), - as::transfer_all(), - force_move(self) - ); - } - } - else { - // start bulk read - auto strm_copy = strm; - async_read_some( - strm_copy, - force_move(self) - ); - } - } break; - default: - BOOST_ASSERT(false); - break; - } - } - - // for non bulk read - template - void operator()( - Self& self, - error_code ec, - std::size_t bytes_transferred - ) { - (void)bytes_transferred; // Ignore unused argument in release build - auto& a_strm{*strm}; - - if (ec) { - next(); - self.complete(ec, buffer{}); - return; - } - - switch (state) { - case remaining_length: - BOOST_ASSERT(bytes_transferred == rl_expected); - rl_expected = 1; - received += bytes_transferred; - if (a_strm.header_remaining_length_buf_[received - 1] & 0b10000000) { - // remaining_length continues - if (received == 5) { - next(); - ASYNC_MQTT_LOG("mqtt_impl", warning) - << ASYNC_MQTT_ADD_VALUE(address, this) - << "out of size remaining length"; - self.complete( - make_error_code(disconnect_reason_code::packet_too_large), - buffer{} - ); - return; - } - rl += (a_strm.header_remaining_length_buf_[received - 1] & 0b01111111) * mul; - mul *= 128; - auto address = &a_strm.header_remaining_length_buf_[received]; - if constexpr ( - has_async_read::value) { - layer_customize::async_read( - a_strm.nl_, - as::buffer(address, 1), - force_move(self) - ); - } - else { - async_read( - a_strm.nl_, - as::buffer(address, 1), - as::transfer_all(), - force_move(self) - ); - } - } - else { - // remaining_length end - rl += (a_strm.header_remaining_length_buf_[received - 1] & 0b01111111) * mul; - spca = make_shared_ptr_char_array( - received + rl - ); - std::copy( - a_strm.header_remaining_length_buf_.data(), - a_strm.header_remaining_length_buf_.data() + received, spca.get() - ); - - if (rl == 0) { - next(); - auto ptr = spca.get(); - self.complete(ec, buffer{ptr, ptr + received + rl, force_move(spca)}); - return; - } - else { - state = complete; - auto address = &spca[std::ptrdiff_t(received)]; - if constexpr ( - has_async_read::value) { - layer_customize::async_read( - a_strm.nl_, - as::buffer(address, rl), - force_move(self) - ); - } - else { - async_read( - a_strm.nl_, - as::buffer(address, rl), - as::transfer_all(), - force_move(self) - ); - } - } - } - break; - case complete: { - next(); - auto ptr = spca.get(); - self.complete(ec, buffer{ptr, ptr + received + rl, force_move(spca)}); - } break; - default: - BOOST_ASSERT(false); - break; - } - } - - // finish bulk read - template - void operator()( - Self& self, - error_code const& ec, - buffer packet - ) { - next(); - self.complete(ec, force_move(packet)); - } - - void next() { - auto& a_strm{*strm}; - a_strm.read_queue_.stop_work(); - as::post( - a_strm.get_executor(), - [strm = force_move(strm)] { - strm->read_queue_.poll_one(); - } - ); - } -}; - -template -inline -void -stream_impl::init_read() { - read_state_ = read_state::fixed_header; - header_remaining_length_buf_.clear(); - remaining_length_ = 0; - multiplier_ = 1; -} - -template -struct stream_impl::stream_read_some_op { - using stream_type = this_type; - using stream_type_sp = std::shared_ptr; - using next_layer_type = stream_type::next_layer_type; - - std::shared_ptr strm; - - template - void operator()( - Self& self - ) { - auto& a_strm{*strm}; - if (a_strm.read_packets_.empty()) { - if constexpr ( - has_async_read_some::value) { - layer_customize::async_read_some( - a_strm.nl_, - a_strm.read_buf_.prepare(a_strm.bulk_read_buffer_size_), - force_move(self) - ); - } - else { - a_strm.nl_.async_read_some( - a_strm.read_buf_.prepare(a_strm.bulk_read_buffer_size_), - force_move(self) - ); - } - } - else { - auto [ec, packet] = force_move(a_strm.read_packets_.front()); - a_strm.read_packets_.pop_front(); - self.complete(ec, force_move(packet)); - } - } - - template - void operator()( - Self& self, - error_code const& ec, - std::size_t bytes_transferred - ) { - auto& a_strm{*strm}; - if (ec) { - a_strm.init_read(); - a_strm.read_packets_.emplace_back(ec); - } - else { - a_strm.read_buf_.commit(bytes_transferred); - a_strm.parse_packet(); - as::dispatch( - a_strm.get_executor(), - force_move(self) - ); - } - } -}; - -template -template -auto -stream_impl::async_read_some( - this_type_sp impl, - CompletionToken&& token -) { - BOOST_ASSERT(impl); - auto exe = impl->get_executor(); - return - as::async_compose< - CompletionToken, - void(error_code, buffer) - >( - stream_read_some_op{ - force_move(impl) - }, - token, - exe - ); -} - - -template -inline -void -stream_impl::parse_packet() { - while (read_buf_.size() != 0) { - switch (read_state_) { - case read_state::fixed_header: { - if (read_buf_.size() > 0) { - std::istream is{&read_buf_}; - char fixed_header; - is.read(&fixed_header, 1); - header_remaining_length_buf_.push_back(fixed_header); - read_state_ = read_state::remaining_length; - } - } break; - case read_state::remaining_length: { - while (read_buf_.size() > 0) { - std::istream is{&read_buf_}; - char encoded_byte; - is.read(&encoded_byte, 1); - header_remaining_length_buf_.push_back(encoded_byte); - remaining_length_ += (std::uint8_t(encoded_byte) & 0b0111'1111) * multiplier_; - multiplier_ *= 128; - if ((encoded_byte & 0b1000'0000) == 0) { - read_state_ = read_state::payload; - break; - } - if (multiplier_ == 128 * 128 * 128 * 128) { - read_packets_.emplace_back(make_error_code(disconnect_reason_code::packet_too_large)); - init_read(); - return; - } - } - if (read_state_ != read_state::payload) { - return; - } - } break; - case read_state::payload: { - if (read_buf_.size() >= remaining_length_) { - std::size_t total_size = header_remaining_length_buf_.size() + remaining_length_; - auto spca = make_shared_ptr_char_array(total_size); - std::copy_n( - header_remaining_length_buf_.data(), - header_remaining_length_buf_.size(), - spca.get() - ); - std::istream is{&read_buf_}; - auto ptr = spca.get(); - is.read(ptr + header_remaining_length_buf_.size(), static_cast(remaining_length_)); - read_packets_.emplace_back( - buffer{ptr, total_size, force_move(spca)} - ); - - init_read(); - } - else { - return; - } - } break; - } - } -} - -} // namespace detail - -template -template -auto -stream::async_read_packet( - CompletionToken&& token -) { - BOOST_ASSERT(impl_); - return - as::async_compose< - CompletionToken, - void(error_code, buffer) - >( - typename impl_type::stream_read_packet_op{ - impl_ - }, - token, - get_executor() - ); -} - - -} // namespace async_mqtt - -#endif // ASYNC_MQTT_UTIL_IMPL_STREAM_READ_PACKET_HPP diff --git a/include/async_mqtt/util/topic_alias_recv.hpp b/include/async_mqtt/util/topic_alias_recv.hpp index 98e85bdbf..c26b2cb9d 100644 --- a/include/async_mqtt/util/topic_alias_recv.hpp +++ b/include/async_mqtt/util/topic_alias_recv.hpp @@ -19,7 +19,7 @@ #include #include -#include +#include namespace async_mqtt { diff --git a/include/async_mqtt/util/topic_alias_send.hpp b/include/async_mqtt/util/topic_alias_send.hpp index 097b27d53..542b802bf 100644 --- a/include/async_mqtt/util/topic_alias_send.hpp +++ b/include/async_mqtt/util/topic_alias_send.hpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include namespace async_mqtt { diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index f1bf061e8..ea5572d8b 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1,31 +1,43 @@ # Separate compilation library -file(GLOB_RECURSE ALL_IPP ${CMAKE_CURRENT_SOURCE_DIR} "../include/*.ipp") -FOREACH (IPP ${ALL_IPP}) - GET_FILENAME_COMPONENT (IPP_NAME ${IPP} NAME) - FILE (COPY ${IPP} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}") - FILE (RENAME "${CMAKE_CURRENT_BINARY_DIR}/${IPP_NAME}" "${CMAKE_CURRENT_BINARY_DIR}/${IPP_NAME}.cpp") - LIST (APPEND LIB_SRC "${CMAKE_CURRENT_BINARY_DIR}/${IPP_NAME}.cpp") -ENDFOREACH () +file(GLOB_RECURSE ASIO_BIND_IPP ${CMAKE_CURRENT_SOURCE_DIR} "../include/async_mqtt/impl/*.ipp") +set_source_files_properties(${ASIO_BIND_IPP} PROPERTIES LANGUAGE CXX) +add_library(async_mqtt_asio_bind ${ASIO_BIND_IPP}) +target_compile_definitions(async_mqtt_asio_bind PRIVATE ASYNC_MQTT_SEPARATE_COMPILATION) +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + target_compile_options(async_mqtt_asio_bind PRIVATE -x c++) +endif() -add_library(async_mqtt_separate ${LIB_SRC}) +file(GLOB_RECURSE PROTOCOL_IPP ${CMAKE_CURRENT_SOURCE_DIR} "../include/async_mqtt/protocol/*.ipp") +set_source_files_properties(${PROTOCOL_IPP} PROPERTIES LANGUAGE CXX) +add_library(async_mqtt_protocol ${PROTOCOL_IPP}) +target_compile_definitions(async_mqtt_protocol PRIVATE ASYNC_MQTT_SEPARATE_COMPILATION) +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + target_compile_options(async_mqtt_protocol PRIVATE -x c++) +endif() if(ASYNC_MQTT_USE_LOG) target_compile_definitions( - async_mqtt_separate + async_mqtt_asio_bind + PRIVATE + $,,BOOST_LOG_DYN_LINK> + ) + target_compile_definitions( + async_mqtt_protocol PRIVATE $,,BOOST_LOG_DYN_LINK> ) endif() -target_compile_definitions(async_mqtt_separate PRIVATE ASYNC_MQTT_SEPARATE_COMPILATION) macro(fix_msvc_build) message(STATUS "MSVC build fix applied") - target_compile_options(async_mqtt_separate PRIVATE "/Zc:preprocessor" "/bigobj") + target_compile_options(async_mqtt_asio_bind PRIVATE "/Zc:preprocessor" "/bigobj") + target_compile_options(async_mqtt_protocol PRIVATE "/Zc:preprocessor" "/bigobj") endmacro() if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") fix_msvc_build() endif() -target_link_libraries(async_mqtt_separate async_mqtt_iface) +target_link_libraries(async_mqtt_asio_bind async_mqtt_iface) +target_link_libraries(async_mqtt_protocol async_mqtt_iface) diff --git a/test/system/coro_base.hpp b/test/system/coro_base.hpp index f51e6c6ff..800f498d7 100644 --- a/test/system/coro_base.hpp +++ b/test/system/coro_base.hpp @@ -29,13 +29,13 @@ struct coro_base : as::coroutine { virtual ~coro_base() = default; void operator()(am::error_code const& ec = am::error_code{}) { - proc(ec, am::basic_packet_variant{}, 0); + proc(ec, std::nullopt, 0); } - void operator()(am::error_code const& ec, am::basic_packet_variant pv) { - proc(ec, am::force_move(pv), 0); + void operator()(am::error_code const& ec, std::optional> pv_opt) { + proc(ec, am::force_move(pv_opt), 0); } void operator()(am::error_code const& ec, typename am::basic_packet_id_type::type pid) { - proc(ec, am::basic_packet_variant{}, am::force_move(pid)); + proc(ec, std::nullopt, pid); } bool finish() const { return *finish_; @@ -49,7 +49,7 @@ struct coro_base : as::coroutine { private: virtual void proc( am::error_code ec, - am::basic_packet_variant pv, + std::optional> pv_opt, typename am::basic_packet_id_type::type pid ) = 0; std::vector> eps_; diff --git a/test/system/st_auth.cpp b/test/system/st_auth.cpp index f00939513..ffeedc724 100644 --- a/test/system/st_auth.cpp +++ b/test/system/st_auth.cpp @@ -32,7 +32,7 @@ BOOST_AUTO_TEST_CASE(fail_plain) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -42,8 +42,7 @@ BOOST_AUTO_TEST_CASE(fail_plain) { *this ) ); - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -62,7 +61,7 @@ BOOST_AUTO_TEST_CASE(fail_plain) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -101,7 +100,7 @@ BOOST_AUTO_TEST_CASE(success_digest) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -111,8 +110,7 @@ BOOST_AUTO_TEST_CASE(success_digest) { *this ) ); - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -131,7 +129,7 @@ BOOST_AUTO_TEST_CASE(success_digest) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -170,7 +168,7 @@ BOOST_AUTO_TEST_CASE(fail_digest) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -180,8 +178,7 @@ BOOST_AUTO_TEST_CASE(fail_digest) { *this ) ); - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -200,7 +197,7 @@ BOOST_AUTO_TEST_CASE(fail_digest) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -239,7 +236,7 @@ BOOST_AUTO_TEST_CASE(send_auth) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -249,8 +246,7 @@ BOOST_AUTO_TEST_CASE(send_auth) { *this ) ); - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -269,7 +265,7 @@ BOOST_AUTO_TEST_CASE(send_auth) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(!p.session_present()); diff --git a/test/system/st_cancel.cpp b/test/system/st_cancel.cpp index b567f452f..be8037f5f 100644 --- a/test/system/st_cancel.cpp +++ b/test/system/st_cancel.cpp @@ -28,8 +28,7 @@ BOOST_AUTO_TEST_CASE(ep) { as::cancellation_signal sig1; std::size_t canceled = 0; - am::async_underlying_handshake( - amep.next_layer(), + amep.async_underlying_handshake( "127.0.0.1", "1883", [&](am::error_code const& ec) { @@ -46,9 +45,9 @@ BOOST_AUTO_TEST_CASE(ep) { [&](am::error_code const& ec) { BOOST_TEST(!ec); amep.async_recv( - [&](am::error_code const& ec, am::packet_variant pv) { + [&](am::error_code const& ec, std::optional pv_opt) { BOOST_TEST(!ec); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -63,16 +62,16 @@ BOOST_AUTO_TEST_CASE(ep) { amep.async_recv( as::bind_cancellation_slot( sig1.slot(), - [&](am::error_code const& ec, am::packet_variant pv) { + [&](am::error_code const& ec, std::optional pv_opt) { BOOST_TEST(ec == as::error::operation_aborted); - BOOST_TEST(!pv); + BOOST_TEST(!pv_opt); ++canceled; amep.async_recv( as::bind_cancellation_slot( sig1.slot(), - [&](am::error_code const& ec, am::packet_variant pv) { + [&](am::error_code const& ec, std::optional pv_opt) { BOOST_TEST(ec == as::error::operation_aborted); - BOOST_TEST(!pv); + BOOST_TEST(!pv_opt); ++canceled; amep.async_close(as::detached); } @@ -122,8 +121,7 @@ BOOST_AUTO_TEST_CASE(cl) { as::cancellation_signal sig1; std::size_t canceled = 0; - am::async_underlying_handshake( - amcl.next_layer(), + amcl.async_underlying_handshake( "127.0.0.1", "1883", [&](am::error_code const& ec) { @@ -144,16 +142,16 @@ BOOST_AUTO_TEST_CASE(cl) { amcl.async_recv( as::bind_cancellation_slot( sig1.slot(), - [&](am::error_code const& ec, am::packet_variant pv) { + [&](am::error_code const& ec, std::optional pv_opt) { BOOST_TEST(ec == as::error::operation_aborted); - BOOST_TEST(!pv); + BOOST_TEST(!pv_opt); ++canceled; amcl.async_recv( as::bind_cancellation_slot( sig1.slot(), - [&](am::error_code const& ec, am::packet_variant pv) { + [&](am::error_code const& ec, std::optional pv_opt) { BOOST_TEST(ec == as::error::operation_aborted); - BOOST_TEST(!pv); + BOOST_TEST(!pv_opt); ++canceled; amcl.async_close(as::detached); } diff --git a/test/system/st_conflict_cid.cpp b/test/system/st_conflict_cid.cpp index 30cc13bd0..1652efaca 100644 --- a/test/system/st_conflict_cid.cpp +++ b/test/system/st_conflict_cid.cpp @@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE(v311_cs1to1) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -50,8 +50,7 @@ BOOST_AUTO_TEST_CASE(v311_cs1to1) { *this ) ); - yield am::async_underlying_handshake( - ep(c1).next_layer(), + yield ep(c1).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -70,7 +69,7 @@ BOOST_AUTO_TEST_CASE(v311_cs1to1) { ); BOOST_TEST(!ec); yield ep(c1).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -87,8 +86,7 @@ BOOST_AUTO_TEST_CASE(v311_cs1to1) { *this ) ); - yield am::async_underlying_handshake( - ep(c2).next_layer(), + yield ep(c2).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -107,7 +105,7 @@ BOOST_AUTO_TEST_CASE(v311_cs1to1) { ); BOOST_TEST(!ec); yield ep(c2).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -154,7 +152,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0to1) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -164,8 +162,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0to1) { *this ) ); - yield am::async_underlying_handshake( - ep(c1).next_layer(), + yield ep(c1).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -184,7 +181,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0to1) { ); BOOST_TEST(!ec); yield ep(c1).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -201,8 +198,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0to1) { *this ) ); - yield am::async_underlying_handshake( - ep(c2).next_layer(), + yield ep(c2).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -221,7 +217,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0to1) { ); BOOST_TEST(!ec); yield ep(c2).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -268,7 +264,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0to0) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -278,8 +274,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0to0) { *this ) ); - yield am::async_underlying_handshake( - ep(c1).next_layer(), + yield ep(c1).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -298,7 +293,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0to0) { ); BOOST_TEST(!ec); yield ep(c1).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -315,8 +310,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0to0) { *this ) ); - yield am::async_underlying_handshake( - ep(c2).next_layer(), + yield ep(c2).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -335,7 +329,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0to0) { ); BOOST_TEST(!ec); yield ep(c2).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(p.session_present()); @@ -382,7 +376,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0offto1) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -392,8 +386,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0offto1) { *this ) ); - yield am::async_underlying_handshake( - ep(c1).next_layer(), + yield ep(c1).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -412,7 +405,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0offto1) { ); BOOST_TEST(!ec); yield ep(c1).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -430,8 +423,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0offto1) { *this ) ); - yield am::async_underlying_handshake( - ep(c2).next_layer(), + yield ep(c2).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -450,7 +442,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0offto1) { ); BOOST_TEST(!ec); yield ep(c2).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); diff --git a/test/system/st_cpp20coro_client.cpp b/test/system/st_cpp20coro_client.cpp index 172381b75..aac590b6f 100644 --- a/test/system/st_cpp20coro_client.cpp +++ b/test/system/st_cpp20coro_client.cpp @@ -34,8 +34,7 @@ BOOST_AUTO_TEST_CASE(v311) { ); // Handshake undlerying layer (Name resolution and TCP handshaking) - auto [ec_und] = co_await am::async_underlying_handshake( - amcl.next_layer(), + auto [ec_und] = co_await amcl.async_underlying_handshake( "127.0.0.1", "1883", as::as_tuple(as::use_awaitable) @@ -204,8 +203,7 @@ BOOST_AUTO_TEST_CASE(v5) { ); // Handshake undlerying layer (Name resolution and TCP handshaking) - auto [ec_und] = co_await am::async_underlying_handshake( - amcl.next_layer(), + auto [ec_und] = co_await amcl.async_underlying_handshake( "127.0.0.1", "1883", as::as_tuple(as::use_awaitable) diff --git a/test/system/st_cpp20coro_client_direct.cpp b/test/system/st_cpp20coro_client_direct.cpp index 3535df88f..9f09ae9f8 100644 --- a/test/system/st_cpp20coro_client_direct.cpp +++ b/test/system/st_cpp20coro_client_direct.cpp @@ -34,14 +34,14 @@ BOOST_AUTO_TEST_CASE(v311) { ); // Handshake undlerying layer (Name resolution and TCP handshaking) - auto [ec_und] = co_await am::async_underlying_handshake( - amcl.next_layer(), + auto [ec_und] = co_await amcl.async_underlying_handshake( "127.0.0.1", "1883", as::as_tuple(as::use_awaitable) ); BOOST_TEST(!ec_und); - + // Not mandatory, to increase coverage + amcl.set_close_delay_after_disconnect_sent(std::chrono::milliseconds{10}); // MQTT connect and receive loop start auto [ec_con, connack_opt] = co_await amcl.async_start( true, // clean_session @@ -190,8 +190,7 @@ BOOST_AUTO_TEST_CASE(v5) { ); // Handshake undlerying layer (Name resolution and TCP handshaking) - auto [ec_und] = co_await am::async_underlying_handshake( - amcl.next_layer(), + auto [ec_und] = co_await amcl.async_underlying_handshake( "127.0.0.1", "1883", as::as_tuple(as::use_awaitable) diff --git a/test/system/st_cpp20coro_client_direct_default.cpp b/test/system/st_cpp20coro_client_direct_default.cpp index 6ab8c03e6..9ae5df504 100644 --- a/test/system/st_cpp20coro_client_direct_default.cpp +++ b/test/system/st_cpp20coro_client_direct_default.cpp @@ -36,8 +36,7 @@ BOOST_AUTO_TEST_CASE(v311) { ); // Handshake undlerying layer (Name resolution and TCP handshaking) - auto [ec_und] = co_await am::async_underlying_handshake( - amcl.next_layer(), + auto [ec_und] = co_await amcl.async_underlying_handshake( "127.0.0.1", "1883" ); @@ -185,8 +184,7 @@ BOOST_AUTO_TEST_CASE(v5) { ); // Handshake undlerying layer (Name resolution and TCP handshaking) - auto [ec_und] = co_await am::async_underlying_handshake( - amcl.next_layer(), + auto [ec_und] = co_await amcl.async_underlying_handshake( "127.0.0.1", "1883" ); diff --git a/test/system/st_cpp20coro_client_direct_default_error.cpp b/test/system/st_cpp20coro_client_direct_default_error.cpp index ef381c997..446fbfbdc 100644 --- a/test/system/st_cpp20coro_client_direct_default_error.cpp +++ b/test/system/st_cpp20coro_client_direct_default_error.cpp @@ -36,8 +36,7 @@ BOOST_AUTO_TEST_CASE(v311) { ); // Handshake undlerying layer (Name resolution and TCP handshaking) - auto [ec_und] = co_await am::async_underlying_handshake( - amcl.next_layer(), + auto [ec_und] = co_await amcl.async_underlying_handshake( "127.0.0.1", "1883" ); @@ -110,8 +109,7 @@ BOOST_AUTO_TEST_CASE(v5) { ); // Handshake undlerying layer (Name resolution and TCP handshaking) - auto [ec_und] = co_await am::async_underlying_handshake( - amcl.next_layer(), + auto [ec_und] = co_await amcl.async_underlying_handshake( "127.0.0.1", "1883" ); diff --git a/test/system/st_cpp20coro_client_direct_error.cpp b/test/system/st_cpp20coro_client_direct_error.cpp index 0e088c789..f7679fc94 100644 --- a/test/system/st_cpp20coro_client_direct_error.cpp +++ b/test/system/st_cpp20coro_client_direct_error.cpp @@ -35,8 +35,7 @@ BOOST_AUTO_TEST_CASE(v311) { ); // Handshake undlerying layer (Name resolution and TCP handshaking) - auto [ec_und] = co_await am::async_underlying_handshake( - amcl.next_layer(), + auto [ec_und] = co_await amcl.async_underlying_handshake( "127.0.0.1", "1883", as::as_tuple(as::use_awaitable) @@ -113,8 +112,7 @@ BOOST_AUTO_TEST_CASE(v5) { ); // Handshake undlerying layer (Name resolution and TCP handshaking) - auto [ec_und] = co_await am::async_underlying_handshake( - amcl.next_layer(), + auto [ec_und] = co_await amcl.async_underlying_handshake( "127.0.0.1", "1883", as::as_tuple(as::use_awaitable) diff --git a/test/system/st_gencid.cpp b/test/system/st_gencid.cpp index c573edf29..5c1f7e091 100644 --- a/test/system/st_gencid.cpp +++ b/test/system/st_gencid.cpp @@ -32,7 +32,7 @@ BOOST_AUTO_TEST_CASE(v311_cs1) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -42,8 +42,7 @@ BOOST_AUTO_TEST_CASE(v311_cs1) { *this ) ); - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -62,7 +61,7 @@ BOOST_AUTO_TEST_CASE(v311_cs1) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -100,7 +99,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -110,8 +109,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0) { *this ) ); - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -130,7 +128,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -169,7 +167,7 @@ BOOST_AUTO_TEST_CASE(v5_cs1) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -179,8 +177,7 @@ BOOST_AUTO_TEST_CASE(v5_cs1) { *this ) ); - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -200,7 +197,7 @@ BOOST_AUTO_TEST_CASE(v5_cs1) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -253,7 +250,7 @@ BOOST_AUTO_TEST_CASE(v5_cs0) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -263,8 +260,7 @@ BOOST_AUTO_TEST_CASE(v5_cs0) { *this ) ); - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -284,7 +280,7 @@ BOOST_AUTO_TEST_CASE(v5_cs0) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -307,8 +303,7 @@ BOOST_AUTO_TEST_CASE(v5_cs0) { ); yield ep().async_close(*this); - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -327,7 +322,7 @@ BOOST_AUTO_TEST_CASE(v5_cs0) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(p.session_present()); diff --git a/test/system/st_inflight.cpp b/test/system/st_inflight.cpp index ef0ec6f3c..7020030e3 100644 --- a/test/system/st_inflight.cpp +++ b/test/system/st_inflight.cpp @@ -29,7 +29,7 @@ BOOST_AUTO_TEST_CASE(v311_to_broker) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -41,8 +41,7 @@ BOOST_AUTO_TEST_CASE(v311_to_broker) { ); // connect 1 - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -61,7 +60,7 @@ BOOST_AUTO_TEST_CASE(v311_to_broker) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -71,10 +70,13 @@ BOOST_AUTO_TEST_CASE(v311_to_broker) { } } ); + + BOOST_TEST(ep().register_packet_id(1)); + BOOST_TEST(ep().register_packet_id(2)); // publish QoS1 yield ep().async_send( am::v3_1_1::publish_packet{ - *ep().acquire_unique_packet_id(), + 1, "topic1", "payload1", am::qos::at_least_once | am::pub::retain::yes | am::pub::dup::no @@ -86,7 +88,7 @@ BOOST_AUTO_TEST_CASE(v311_to_broker) { // publish QoS2 yield ep().async_send( am::v3_1_1::publish_packet{ - *ep().acquire_unique_packet_id(), + 2, "topic1", "payload1", am::qos::exactly_once | am::pub::retain::no | am::pub::dup::no @@ -98,8 +100,7 @@ BOOST_AUTO_TEST_CASE(v311_to_broker) { yield ep().async_close(*this); // connect 2 - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -118,7 +119,7 @@ BOOST_AUTO_TEST_CASE(v311_to_broker) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(p.session_present()); @@ -128,20 +129,19 @@ BOOST_AUTO_TEST_CASE(v311_to_broker) { } } ); - // recv puback + // recv puback or pubrec yield ep().async_recv(*this); - BOOST_TEST(pv == am::v3_1_1::puback_packet{1}); + BOOST_TEST(exp.erase(*pv_opt) == 1); // recv pubrec yield ep().async_recv(*this); - BOOST_TEST(pv == am::v3_1_1::pubrec_packet{2}); + BOOST_TEST(exp.erase(*pv_opt) == 1); // send pubrel yield ep().async_send(am::v3_1_1::pubrel_packet{2}, *this); yield ep().async_close(*this); // connect 3 - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -160,7 +160,7 @@ BOOST_AUTO_TEST_CASE(v311_to_broker) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(p.session_present()); @@ -172,13 +172,18 @@ BOOST_AUTO_TEST_CASE(v311_to_broker) { ); // recv pubcomp yield ep().async_recv(*this); - BOOST_TEST(pv == am::v3_1_1::pubcomp_packet{2}); + BOOST_TEST(*pv_opt == am::v3_1_1::pubcomp_packet{2}); yield ep().async_close(*this); set_finish(); guard.reset(); } } + + std::set exp { + am::v3_1_1::puback_packet{1}, + am::v3_1_1::pubrec_packet{2} + }; }; tc t{amep}; @@ -202,7 +207,7 @@ BOOST_AUTO_TEST_CASE(v5_to_broker) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -214,8 +219,7 @@ BOOST_AUTO_TEST_CASE(v5_to_broker) { ); // connect 1 - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -235,7 +239,7 @@ BOOST_AUTO_TEST_CASE(v5_to_broker) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -245,10 +249,14 @@ BOOST_AUTO_TEST_CASE(v5_to_broker) { } } ); + + BOOST_TEST(ep().register_packet_id(1)); + BOOST_TEST(ep().register_packet_id(2)); + // publish QoS1 yield ep().async_send( am::v5::publish_packet{ - *ep().acquire_unique_packet_id(), + 1, "topic1", "payload1", am::qos::at_least_once | am::pub::retain::yes | am::pub::dup::no @@ -260,7 +268,7 @@ BOOST_AUTO_TEST_CASE(v5_to_broker) { // publish QoS2 yield ep().async_send( am::v5::publish_packet{ - *ep().acquire_unique_packet_id(), + 2, "topic1", "payload1", am::qos::exactly_once | am::pub::retain::no | am::pub::dup::no @@ -272,8 +280,7 @@ BOOST_AUTO_TEST_CASE(v5_to_broker) { yield ep().async_close(*this); // connect 2 - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -293,7 +300,7 @@ BOOST_AUTO_TEST_CASE(v5_to_broker) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(p.session_present()); @@ -305,13 +312,10 @@ BOOST_AUTO_TEST_CASE(v5_to_broker) { ); // recv puback yield ep().async_recv(*this); - BOOST_TEST(pv == (am::v5::puback_packet{1, am::puback_reason_code::no_matching_subscribers})); + BOOST_TEST(exp.erase(*pv_opt) == 1); // recv pubrec yield ep().async_recv(*this); - BOOST_CHECK( - pv == (am::v5::pubrec_packet{2, am::pubrec_reason_code::no_matching_subscribers}) || - pv == (am::v5::pubrec_packet{2}) - ); + BOOST_TEST(exp.erase(*pv_opt) == 1); // send pubrel yield ep().async_send(am::v5::pubrel_packet{2}, *this); @@ -319,8 +323,7 @@ BOOST_AUTO_TEST_CASE(v5_to_broker) { yield ep().async_close(*this); // connect 3 - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -339,7 +342,7 @@ BOOST_AUTO_TEST_CASE(v5_to_broker) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(p.session_present()); @@ -351,13 +354,19 @@ BOOST_AUTO_TEST_CASE(v5_to_broker) { ); // recv pubcomp yield ep().async_recv(*this); - BOOST_TEST(pv == (am::v5::pubcomp_packet{2})); + BOOST_TEST(*pv_opt == (am::v5::pubcomp_packet{2})); yield ep().async_close(*this); set_finish(); guard.reset(); } } + + std::set exp { + am::v5::puback_packet{1, am::puback_reason_code::no_matching_subscribers}, + am::v5::pubrec_packet{2, am::pubrec_reason_code::no_matching_subscribers}, + am::v5::pubrec_packet{2} // already handled in the broker + }; }; tc t{amep}; @@ -389,7 +398,7 @@ BOOST_AUTO_TEST_CASE(v311_from_broker) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -403,8 +412,7 @@ BOOST_AUTO_TEST_CASE(v311_from_broker) { ) ); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -423,7 +431,7 @@ BOOST_AUTO_TEST_CASE(v311_from_broker) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -445,7 +453,7 @@ BOOST_AUTO_TEST_CASE(v311_from_broker) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); @@ -457,8 +465,7 @@ BOOST_AUTO_TEST_CASE(v311_from_broker) { ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -477,7 +484,7 @@ BOOST_AUTO_TEST_CASE(v311_from_broker) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // publish QoS1 yield ep(pub).async_send( @@ -513,8 +520,7 @@ BOOST_AUTO_TEST_CASE(v311_from_broker) { yield ep(sub).async_close(*this); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -533,7 +539,7 @@ BOOST_AUTO_TEST_CASE(v311_from_broker) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(p.session_present()); @@ -546,7 +552,7 @@ BOOST_AUTO_TEST_CASE(v311_from_broker) { yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v3_1_1::publish_packet{ 1, @@ -558,7 +564,7 @@ BOOST_AUTO_TEST_CASE(v311_from_broker) { yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v3_1_1::publish_packet{ 2, @@ -612,7 +618,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -626,8 +632,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { ) ); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -647,7 +652,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -669,7 +674,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( @@ -679,8 +684,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { ) ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -699,7 +703,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // publish QoS1 yield ep(pub).async_send( @@ -735,8 +739,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { yield ep(sub).async_close(*this); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -762,7 +765,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { ) ); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(p.session_present()); @@ -775,7 +778,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ 1, @@ -787,7 +790,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ 2, @@ -841,7 +844,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker_mei) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -855,8 +858,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker_mei) { ) ); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -876,7 +878,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker_mei) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -898,7 +900,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker_mei) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( @@ -909,8 +911,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker_mei) { ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -929,7 +930,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker_mei) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // publish QoS1 yield ep(pub).async_send( @@ -975,8 +976,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker_mei) { yield ep(sub).async_close(*this); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -995,7 +995,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker_mei) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(p.session_present()); @@ -1010,7 +1010,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker_mei) { // message_expiry_interval shouldn't be updated // because PUBLISH has already been triggered BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ 1, @@ -1025,7 +1025,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker_mei) { // message_expiry_interval shouldn't be updated // because PUBLISH has already been triggered BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ 2, diff --git a/test/system/st_invalid.cpp b/test/system/st_invalid.cpp index e3040cd45..b589e8f81 100644 --- a/test/system/st_invalid.cpp +++ b/test/system/st_invalid.cpp @@ -34,7 +34,7 @@ BOOST_AUTO_TEST_CASE(remaining_length) { private: void proc( am::error_code ec, - am::packet_variant /*pv*/, + std::optional /*pv_opt*/, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -44,8 +44,7 @@ BOOST_AUTO_TEST_CASE(remaining_length) { *this ) ); - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this diff --git a/test/system/st_keep_alive.cpp b/test/system/st_keep_alive.cpp index 1390ed79e..34e249cb2 100644 --- a/test/system/st_keep_alive.cpp +++ b/test/system/st_keep_alive.cpp @@ -32,7 +32,7 @@ BOOST_AUTO_TEST_CASE(v311_timeout) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -42,8 +42,7 @@ BOOST_AUTO_TEST_CASE(v311_timeout) { *this ) ); - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -62,7 +61,7 @@ BOOST_AUTO_TEST_CASE(v311_timeout) { ); BOOST_TEST(!ec); yield ep().async_recv({am::control_packet_type::connack}, *this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); ep().set_pingreq_send_interval(std::chrono::seconds{10}); yield ep().async_recv(am::filter::except, {am::control_packet_type::pingresp}, *this); BOOST_TEST(ec); @@ -93,7 +92,7 @@ BOOST_AUTO_TEST_CASE(v5_timeout) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -103,8 +102,7 @@ BOOST_AUTO_TEST_CASE(v5_timeout) { *this ) ); - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -124,10 +122,10 @@ BOOST_AUTO_TEST_CASE(v5_timeout) { ); BOOST_TEST(!ec); yield ep().async_recv({am::control_packet_type::connack}, *this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); ep().set_pingreq_send_interval(std::chrono::seconds{10}); yield ep().async_recv(am::filter::except, {am::control_packet_type::pingresp}, *this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield ep().async_recv(am::filter::except, {am::control_packet_type::pingresp}, *this); BOOST_TEST(ec); set_finish(); diff --git a/test/system/st_mqtt_connect.cpp b/test/system/st_mqtt_connect.cpp index 77f4f7aaa..4ebf2b1dd 100644 --- a/test/system/st_mqtt_connect.cpp +++ b/test/system/st_mqtt_connect.cpp @@ -26,8 +26,7 @@ BOOST_AUTO_TEST_CASE(cb) { ioc.get_executor() }; - am::async_underlying_handshake( - amep.next_layer(), + amep.async_underlying_handshake( "127.0.0.1", "1883", [&](am::error_code const& ec) { @@ -44,9 +43,9 @@ BOOST_AUTO_TEST_CASE(cb) { [&](am::error_code const& ec) { BOOST_TEST(!ec); amep.async_recv( - [&](am::error_code const& ec, am::packet_variant pv) { + [&](am::error_code const& ec, std::optional pv_opt) { BOOST_TEST(!ec); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -92,8 +91,7 @@ BOOST_AUTO_TEST_CASE(fut) { ); { - auto fut = am::async_underlying_handshake( - amep.next_layer(), + auto fut = amep.async_underlying_handshake( "127.0.0.1", "1883", as::use_future @@ -129,8 +127,8 @@ BOOST_AUTO_TEST_CASE(fut) { auto fut = amep.async_recv(as::use_future); try { - auto pv = fut.get(); - pv.visit( + auto pv_opt = fut.get(); + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -165,12 +163,11 @@ BOOST_AUTO_TEST_CASE(coro) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -189,7 +186,7 @@ BOOST_AUTO_TEST_CASE(coro) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); diff --git a/test/system/st_mqtts_connect.cpp b/test/system/st_mqtts_connect.cpp index ce42129e0..7ee078e28 100644 --- a/test/system/st_mqtts_connect.cpp +++ b/test/system/st_mqtts_connect.cpp @@ -34,8 +34,7 @@ BOOST_AUTO_TEST_CASE(cb) { ctx }; - am::async_underlying_handshake( - amep.next_layer(), + amep.async_underlying_handshake( "127.0.0.1", "8883", [&](am::error_code const& ec) { @@ -52,9 +51,9 @@ BOOST_AUTO_TEST_CASE(cb) { [&](am::error_code const& ec) { BOOST_TEST(!ec); amep.async_recv( - [&](am::error_code const& ec, am::packet_variant pv) { + [&](am::error_code const& ec, std::optional pv_opt) { BOOST_TEST(!ec); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -106,8 +105,7 @@ BOOST_AUTO_TEST_CASE(fut) { ); { - auto fut = am::async_underlying_handshake( - amep.next_layer(), + auto fut = amep.async_underlying_handshake( "127.0.0.1", "8883", as::use_future @@ -143,8 +141,8 @@ BOOST_AUTO_TEST_CASE(fut) { auto fut = amep.async_recv(as::use_future); try { - auto pv = fut.get(); - pv.visit( + auto pv_opt = fut.get(); + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -184,12 +182,11 @@ BOOST_AUTO_TEST_CASE(coro) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "8883", *this @@ -208,7 +205,7 @@ BOOST_AUTO_TEST_CASE(coro) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -251,12 +248,11 @@ BOOST_AUTO_TEST_CASE(coro_client_cert) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "8883", *this @@ -275,7 +271,7 @@ BOOST_AUTO_TEST_CASE(coro_client_cert) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(p.code() == am::connect_return_code::accepted); diff --git a/test/system/st_offline.cpp b/test/system/st_offline.cpp index 1ec7ce507..28924b334 100644 --- a/test/system/st_offline.cpp +++ b/test/system/st_offline.cpp @@ -33,7 +33,7 @@ BOOST_AUTO_TEST_CASE(v311_cs1_sp0) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -44,6 +44,7 @@ BOOST_AUTO_TEST_CASE(v311_cs1_sp0) { ) ); + ep().set_offline_publish(true); // publish QoS0 yield ep().async_send( @@ -80,8 +81,7 @@ BOOST_AUTO_TEST_CASE(v311_cs1_sp0) { ); BOOST_TEST(!ec); - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -101,7 +101,7 @@ BOOST_AUTO_TEST_CASE(v311_cs1_sp0) { BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -128,12 +128,12 @@ BOOST_AUTO_TEST_CASE(v311_cs1_sp0) { if (count++ == 0) { // 1st BOOST_TEST(ec == am::errc::success); // timeout - BOOST_TEST(!pv); // not recv + BOOST_TEST(!pv_opt); // not recv ep().async_close(*this); } else { // 2nd - BOOST_TEST(!pv); // recv error due to close + BOOST_TEST(!pv_opt); // recv error due to close } } set_finish(); @@ -164,7 +164,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp0) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -175,6 +175,8 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp0) { ) ); + ep().set_offline_publish(true); + // publish QoS0 yield ep().async_send( am::v3_1_1::publish_packet{ @@ -210,9 +212,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp0) { ); BOOST_TEST(!ec); - yield am::async_underlying_handshake( - - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -232,7 +232,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp0) { BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -260,12 +260,12 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp0) { if (count++ == 0) { // 1st BOOST_TEST(ec == am::errc::success); // timeout - BOOST_TEST(!pv); // not recv + BOOST_TEST(!pv_opt); // not recv ep().async_close(*this); } else { // 2nd - BOOST_TEST(!pv); // recv error due to close + BOOST_TEST(!pv_opt); // recv error due to close } } set_finish(); @@ -295,7 +295,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp1) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -306,9 +306,9 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp1) { ) ); - yield am::async_underlying_handshake( + ep().set_offline_publish(true); - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -328,7 +328,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp1) { BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -375,9 +375,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp1) { ); BOOST_TEST(!ec); - yield am::async_underlying_handshake( - - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -397,7 +395,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp1) { BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(p.session_present()); @@ -410,10 +408,10 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp1) { // recv puback yield ep().async_recv(*this); - BOOST_TEST(pv == am::v3_1_1::puback_packet{1}); + BOOST_TEST(*pv_opt == am::v3_1_1::puback_packet{1}); // recv pubrec yield ep().async_recv(*this); - BOOST_TEST(pv == am::v3_1_1::pubrec_packet{2}); + BOOST_TEST(*pv_opt == am::v3_1_1::pubrec_packet{2}); yield ep().async_close(*this); set_finish(); guard.reset(); @@ -450,7 +448,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp1_from_broker) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -461,9 +459,12 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp1_from_broker) { ) ); + ep(pub).set_offline_publish(true); + // To avoid windows environment close just after sent problem. + ep(pub).set_close_delay_after_disconnect_sent(std::chrono::milliseconds{100}); + // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -482,7 +483,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp1_from_broker) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -504,11 +505,11 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp1_from_broker) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield ep(sub).async_send(am::v3_1_1::disconnect_packet{}, *this); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(!pv); // wait and check close by broker + BOOST_TEST(!pv_opt); // wait and check close by broker yield as::dispatch( as::bind_executor( @@ -518,13 +519,14 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp1_from_broker) { ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this ); BOOST_TEST(ec == am::error_code{}); + // To avoid windows environment close just after sent problem. + ep(pub).set_close_delay_after_disconnect_sent(std::chrono::milliseconds{100}); yield ep(pub).async_send( am::v3_1_1::connect_packet{ true, // clean_session @@ -538,7 +540,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp1_from_broker) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // publish QoS0 yield ep(pub).async_send( @@ -577,7 +579,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp1_from_broker) { yield ep(pub).async_send(am::v3_1_1::disconnect_packet{}, *this); BOOST_TEST(!ec); yield ep(pub).async_recv(am::filter::match, {}, *this); - BOOST_TEST(!pv); // wait and check close by broker + BOOST_TEST(!pv_opt); // wait and check close by broker yield as::dispatch( as::bind_executor( @@ -587,8 +589,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp1_from_broker) { ); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -607,7 +608,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp1_from_broker) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(p.session_present()); @@ -620,7 +621,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp1_from_broker) { yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v3_1_1::publish_packet{ "topic1", @@ -630,7 +631,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp1_from_broker) { ); yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v3_1_1::publish_packet{ 1, @@ -641,7 +642,7 @@ BOOST_AUTO_TEST_CASE(v311_cs0_sp1_from_broker) { ); yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v3_1_1::publish_packet{ 2, @@ -686,7 +687,7 @@ BOOST_AUTO_TEST_CASE(v5_cs0_sp1_from_broker_mei) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -697,9 +698,12 @@ BOOST_AUTO_TEST_CASE(v5_cs0_sp1_from_broker_mei) { ) ); + ep(pub).set_offline_publish(true); + // To avoid windows environment close just after sent problem. + ep(pub).set_close_delay_after_disconnect_sent(std::chrono::milliseconds{100}); + // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -719,7 +723,7 @@ BOOST_AUTO_TEST_CASE(v5_cs0_sp1_from_broker_mei) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -741,11 +745,11 @@ BOOST_AUTO_TEST_CASE(v5_cs0_sp1_from_broker_mei) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield ep(sub).async_send(am::v5::disconnect_packet{}, *this); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(!pv); // wait and check close by broker + BOOST_TEST(!pv_opt); // wait and check close by broker yield as::dispatch( as::bind_executor( @@ -755,8 +759,7 @@ BOOST_AUTO_TEST_CASE(v5_cs0_sp1_from_broker_mei) { ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -775,7 +778,7 @@ BOOST_AUTO_TEST_CASE(v5_cs0_sp1_from_broker_mei) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // publish QoS0 yield ep(pub).async_send( @@ -816,7 +819,7 @@ BOOST_AUTO_TEST_CASE(v5_cs0_sp1_from_broker_mei) { yield ep(pub).async_send(am::v5::disconnect_packet{}, *this); BOOST_TEST(!ec); yield ep(pub).async_recv(am::filter::match, {}, *this); - BOOST_TEST(!pv); // wait and check close by broker + BOOST_TEST(!pv_opt); // wait and check close by broker yield as::dispatch( as::bind_executor( @@ -829,8 +832,7 @@ BOOST_AUTO_TEST_CASE(v5_cs0_sp1_from_broker_mei) { std::this_thread::sleep_for(std::chrono::seconds(2)); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -849,7 +851,7 @@ BOOST_AUTO_TEST_CASE(v5_cs0_sp1_from_broker_mei) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(p.session_present()); @@ -862,7 +864,7 @@ BOOST_AUTO_TEST_CASE(v5_cs0_sp1_from_broker_mei) { yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ "topic1", @@ -872,7 +874,7 @@ BOOST_AUTO_TEST_CASE(v5_cs0_sp1_from_broker_mei) { ); yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ 1, diff --git a/test/system/st_order.cpp b/test/system/st_order.cpp index e9577f677..ac70220f1 100644 --- a/test/system/st_order.cpp +++ b/test/system/st_order.cpp @@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE(v311_qos0) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -55,8 +55,7 @@ BOOST_AUTO_TEST_CASE(v311_qos0) { ); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -75,7 +74,7 @@ BOOST_AUTO_TEST_CASE(v311_qos0) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -97,7 +96,7 @@ BOOST_AUTO_TEST_CASE(v311_qos0) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( @@ -108,8 +107,7 @@ BOOST_AUTO_TEST_CASE(v311_qos0) { ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -128,7 +126,7 @@ BOOST_AUTO_TEST_CASE(v311_qos0) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // publish QoS0 count = 0; @@ -157,7 +155,7 @@ BOOST_AUTO_TEST_CASE(v311_qos0) { while (true) { yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v3_1_1::publish_packet{ "topic1", @@ -214,7 +212,7 @@ BOOST_AUTO_TEST_CASE(v311_qos1) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -229,8 +227,7 @@ BOOST_AUTO_TEST_CASE(v311_qos1) { ); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -249,7 +246,7 @@ BOOST_AUTO_TEST_CASE(v311_qos1) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -271,7 +268,7 @@ BOOST_AUTO_TEST_CASE(v311_qos1) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( @@ -282,8 +279,7 @@ BOOST_AUTO_TEST_CASE(v311_qos1) { ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -302,7 +298,7 @@ BOOST_AUTO_TEST_CASE(v311_qos1) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // publish QoS1 count = 0; @@ -332,10 +328,10 @@ BOOST_AUTO_TEST_CASE(v311_qos1) { count = 0; while (true) { yield ep(sub).async_recv(*this); - BOOST_ASSERT(pv.get_if()); - BOOST_TEST(pv.get_if()->opts().get_qos() == am::qos::at_least_once); + BOOST_ASSERT(pv_opt->get_if()); + BOOST_TEST(pv_opt->get_if()->opts().get_qos() == am::qos::at_least_once); BOOST_TEST( - pv.get_if()->payload() + pv_opt->get_if()->payload() == "payload" + std::to_string(++count) ); @@ -387,7 +383,7 @@ BOOST_AUTO_TEST_CASE(v311_qos2) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -402,8 +398,7 @@ BOOST_AUTO_TEST_CASE(v311_qos2) { ); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -422,7 +417,7 @@ BOOST_AUTO_TEST_CASE(v311_qos2) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -444,7 +439,7 @@ BOOST_AUTO_TEST_CASE(v311_qos2) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( @@ -455,8 +450,7 @@ BOOST_AUTO_TEST_CASE(v311_qos2) { ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -475,7 +469,7 @@ BOOST_AUTO_TEST_CASE(v311_qos2) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // publish QoS2 count = 0; @@ -505,10 +499,10 @@ BOOST_AUTO_TEST_CASE(v311_qos2) { count = 0; while (true) { yield ep(sub).async_recv(am::filter::match, {am::control_packet_type::publish}, *this); - BOOST_ASSERT(pv.get_if()); - BOOST_TEST(pv.get_if()->opts().get_qos() == am::qos::exactly_once); + BOOST_ASSERT(pv_opt->get_if()); + BOOST_TEST(pv_opt->get_if()->opts().get_qos() == am::qos::exactly_once); BOOST_TEST( - pv.get_if()->payload() + pv_opt->get_if()->payload() == "payload" + std::to_string(++count) ); @@ -560,7 +554,7 @@ BOOST_AUTO_TEST_CASE(v5_qos0) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -575,8 +569,7 @@ BOOST_AUTO_TEST_CASE(v5_qos0) { ); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -595,7 +588,7 @@ BOOST_AUTO_TEST_CASE(v5_qos0) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -617,7 +610,7 @@ BOOST_AUTO_TEST_CASE(v5_qos0) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( @@ -628,8 +621,7 @@ BOOST_AUTO_TEST_CASE(v5_qos0) { ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -648,7 +640,7 @@ BOOST_AUTO_TEST_CASE(v5_qos0) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // publish QoS0 count = 0; @@ -677,7 +669,7 @@ BOOST_AUTO_TEST_CASE(v5_qos0) { while (true) { yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v3_1_1::publish_packet{ "topic1", @@ -733,7 +725,7 @@ BOOST_AUTO_TEST_CASE(v5_qos1) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -748,8 +740,7 @@ BOOST_AUTO_TEST_CASE(v5_qos1) { ); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -768,7 +759,7 @@ BOOST_AUTO_TEST_CASE(v5_qos1) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -790,7 +781,7 @@ BOOST_AUTO_TEST_CASE(v5_qos1) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( @@ -801,8 +792,7 @@ BOOST_AUTO_TEST_CASE(v5_qos1) { ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -821,7 +811,7 @@ BOOST_AUTO_TEST_CASE(v5_qos1) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // publish QoS1 count = 0; @@ -851,10 +841,10 @@ BOOST_AUTO_TEST_CASE(v5_qos1) { count = 0; while (true) { yield ep(sub).async_recv(*this); - BOOST_ASSERT(pv.get_if()); - BOOST_TEST(pv.get_if()->opts().get_qos() == am::qos::at_least_once); + BOOST_ASSERT(pv_opt->get_if()); + BOOST_TEST(pv_opt->get_if()->opts().get_qos() == am::qos::at_least_once); BOOST_TEST( - pv.get_if()->payload() + pv_opt->get_if()->payload() == "payload" + std::to_string(++count) ); @@ -906,7 +896,7 @@ BOOST_AUTO_TEST_CASE(v5_qos2) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -921,8 +911,7 @@ BOOST_AUTO_TEST_CASE(v5_qos2) { ); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -941,7 +930,7 @@ BOOST_AUTO_TEST_CASE(v5_qos2) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -963,7 +952,7 @@ BOOST_AUTO_TEST_CASE(v5_qos2) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( @@ -974,8 +963,7 @@ BOOST_AUTO_TEST_CASE(v5_qos2) { ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -994,7 +982,7 @@ BOOST_AUTO_TEST_CASE(v5_qos2) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // publish QoS2 count = 0; @@ -1024,10 +1012,10 @@ BOOST_AUTO_TEST_CASE(v5_qos2) { count = 0; while (true) { yield ep(sub).async_recv(am::filter::match, {am::control_packet_type::publish}, *this); - BOOST_ASSERT(pv.get_if()); - BOOST_TEST(pv.get_if()->opts().get_qos() == am::qos::exactly_once); + BOOST_ASSERT(pv_opt->get_if()); + BOOST_TEST(pv_opt->get_if()->opts().get_qos() == am::qos::exactly_once); BOOST_TEST( - pv.get_if()->payload() + pv_opt->get_if()->payload() == "payload" + std::to_string(++count) ); diff --git a/test/system/st_pub.cpp b/test/system/st_pub.cpp index 10ef245c4..a4b0dd124 100644 --- a/test/system/st_pub.cpp +++ b/test/system/st_pub.cpp @@ -32,7 +32,7 @@ BOOST_AUTO_TEST_CASE(v311_pub_to_broker) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -45,9 +45,7 @@ BOOST_AUTO_TEST_CASE(v311_pub_to_broker) { ) ); - yield am::async_underlying_handshake( - - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -66,7 +64,7 @@ BOOST_AUTO_TEST_CASE(v311_pub_to_broker) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // publish QoS0 yield ep().async_send( @@ -93,7 +91,7 @@ BOOST_AUTO_TEST_CASE(v311_pub_to_broker) { BOOST_TEST(!ec); // recv puback yield ep().async_recv(*this); - BOOST_TEST(pv == am::v3_1_1::puback_packet{pid}); + BOOST_TEST(*pv_opt == am::v3_1_1::puback_packet{pid}); // publish QoS2 pid = *ep().acquire_unique_packet_id(); @@ -109,10 +107,10 @@ BOOST_AUTO_TEST_CASE(v311_pub_to_broker) { BOOST_TEST(!ec); // recv pubrec yield ep().async_recv(*this); - BOOST_TEST(pv == am::v3_1_1::pubrec_packet{pid}); + BOOST_TEST(*pv_opt == am::v3_1_1::pubrec_packet{pid}); // recv pubcomp yield ep().async_recv(*this); - BOOST_TEST(pv == am::v3_1_1::pubcomp_packet{pid}); + BOOST_TEST(*pv_opt == am::v3_1_1::pubcomp_packet{pid}); yield ep().async_close(*this); set_finish(); guard.reset(); @@ -142,7 +140,7 @@ BOOST_AUTO_TEST_CASE(v5_pub_to_broker) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -155,9 +153,7 @@ BOOST_AUTO_TEST_CASE(v5_pub_to_broker) { ) ); - yield am::async_underlying_handshake( - - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -176,7 +172,7 @@ BOOST_AUTO_TEST_CASE(v5_pub_to_broker) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // publish QoS0 yield ep().async_send( @@ -204,7 +200,7 @@ BOOST_AUTO_TEST_CASE(v5_pub_to_broker) { BOOST_TEST(!ec); // recv puback yield ep().async_recv(*this); - BOOST_TEST(pv == (am::v5::puback_packet{pid, am::puback_reason_code::no_matching_subscribers})); + BOOST_TEST(*pv_opt == (am::v5::puback_packet{pid, am::puback_reason_code::no_matching_subscribers})); // publish QoS2 pid = *ep().acquire_unique_packet_id(); @@ -221,12 +217,12 @@ BOOST_AUTO_TEST_CASE(v5_pub_to_broker) { // recv pubrec yield ep().async_recv(*this); BOOST_CHECK( - pv == (am::v5::pubrec_packet{pid, am::pubrec_reason_code::no_matching_subscribers}) || - pv == (am::v5::pubrec_packet{pid}) + *pv_opt == (am::v5::pubrec_packet{pid, am::pubrec_reason_code::no_matching_subscribers}) || + *pv_opt == (am::v5::pubrec_packet{pid}) ); // recv pubcomp yield ep().async_recv(*this); - BOOST_TEST(pv == am::v5::pubcomp_packet{pid}); + BOOST_TEST(*pv_opt == am::v5::pubcomp_packet{pid}); yield ep().async_close(*this); set_finish(); guard.reset(); @@ -264,7 +260,7 @@ BOOST_AUTO_TEST_CASE(v311_from_broker) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -279,8 +275,7 @@ BOOST_AUTO_TEST_CASE(v311_from_broker) { ); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -299,7 +294,7 @@ BOOST_AUTO_TEST_CASE(v311_from_broker) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -321,7 +316,7 @@ BOOST_AUTO_TEST_CASE(v311_from_broker) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( @@ -332,8 +327,7 @@ BOOST_AUTO_TEST_CASE(v311_from_broker) { ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -352,7 +346,7 @@ BOOST_AUTO_TEST_CASE(v311_from_broker) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // publish QoS0 yield ep(pub).async_send( @@ -405,7 +399,7 @@ BOOST_AUTO_TEST_CASE(v311_from_broker) { yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v3_1_1::publish_packet{ "topic1", @@ -415,7 +409,7 @@ BOOST_AUTO_TEST_CASE(v311_from_broker) { ); yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v3_1_1::publish_packet{ 1, @@ -426,7 +420,7 @@ BOOST_AUTO_TEST_CASE(v311_from_broker) { ); yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v3_1_1::publish_packet{ 2, @@ -437,11 +431,11 @@ BOOST_AUTO_TEST_CASE(v311_from_broker) { ); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield ep(sub).async_send(am::v3_1_1::disconnect_packet{}, *this); BOOST_TEST(!ec); yield ep(sub).async_recv(am::filter::match, {}, *this); - BOOST_TEST(!pv); // wait and check close by broker + BOOST_TEST(!pv_opt); // wait and check close by broker yield as::dispatch( as::bind_executor( @@ -485,7 +479,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -500,8 +494,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { ); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -520,7 +513,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -542,7 +535,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( @@ -553,8 +546,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -573,7 +565,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // publish QoS0 yield ep(pub).async_send( @@ -626,7 +618,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ "topic1", @@ -636,7 +628,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { ); yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ 1, @@ -647,7 +639,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { ); yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ 2, @@ -658,11 +650,11 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { ); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield ep(sub).async_send(am::v5::disconnect_packet{}, *this); BOOST_TEST(!ec); yield ep(sub).async_recv(am::filter::match, {}, *this); - BOOST_TEST(!pv); // wait and check close by broker + BOOST_TEST(!pv_opt); // wait and check close by broker yield as::dispatch( as::bind_executor( diff --git a/test/system/st_reqres.cpp b/test/system/st_reqres.cpp index 37514fe08..f156f75a2 100644 --- a/test/system/st_reqres.cpp +++ b/test/system/st_reqres.cpp @@ -32,7 +32,7 @@ BOOST_AUTO_TEST_CASE(generate_reuse_renew) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -43,9 +43,7 @@ BOOST_AUTO_TEST_CASE(generate_reuse_renew) { ) ); - yield am::async_underlying_handshake( - - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -68,7 +66,7 @@ BOOST_AUTO_TEST_CASE(generate_reuse_renew) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet& p) { BOOST_TEST(!p.session_present()); @@ -93,8 +91,7 @@ BOOST_AUTO_TEST_CASE(generate_reuse_renew) { yield ep().async_close(*this); // reconnect inherit - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -117,7 +114,7 @@ BOOST_AUTO_TEST_CASE(generate_reuse_renew) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet& p) { BOOST_TEST(p.session_present()); @@ -143,8 +140,7 @@ BOOST_AUTO_TEST_CASE(generate_reuse_renew) { yield ep().async_close(*this); // reconnect no inherit (clean_start) - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -166,7 +162,7 @@ BOOST_AUTO_TEST_CASE(generate_reuse_renew) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet& p) { BOOST_TEST(!p.session_present()); diff --git a/test/system/st_retain.cpp b/test/system/st_retain.cpp index de5623b9e..0f35a44e4 100644 --- a/test/system/st_retain.cpp +++ b/test/system/st_retain.cpp @@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE(v5_mei_none) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -54,8 +54,7 @@ BOOST_AUTO_TEST_CASE(v5_mei_none) { ) ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -74,7 +73,7 @@ BOOST_AUTO_TEST_CASE(v5_mei_none) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // publish QoS0 yield ep(pub).async_send( @@ -120,8 +119,7 @@ BOOST_AUTO_TEST_CASE(v5_mei_none) { ); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -140,7 +138,7 @@ BOOST_AUTO_TEST_CASE(v5_mei_none) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -162,11 +160,11 @@ BOOST_AUTO_TEST_CASE(v5_mei_none) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ 1, @@ -220,7 +218,7 @@ BOOST_AUTO_TEST_CASE(v5_mei_no_exp) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -234,8 +232,7 @@ BOOST_AUTO_TEST_CASE(v5_mei_no_exp) { ) ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -254,7 +251,7 @@ BOOST_AUTO_TEST_CASE(v5_mei_no_exp) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // publish QoS0 yield ep(pub).async_send( @@ -301,8 +298,7 @@ BOOST_AUTO_TEST_CASE(v5_mei_no_exp) { ); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -321,7 +317,7 @@ BOOST_AUTO_TEST_CASE(v5_mei_no_exp) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -343,11 +339,11 @@ BOOST_AUTO_TEST_CASE(v5_mei_no_exp) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ 1, @@ -403,7 +399,7 @@ BOOST_AUTO_TEST_CASE(v5_mei_exp) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -417,8 +413,7 @@ BOOST_AUTO_TEST_CASE(v5_mei_exp) { ) ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -437,7 +432,7 @@ BOOST_AUTO_TEST_CASE(v5_mei_exp) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // publish QoS0 yield ep(pub).async_send( @@ -487,8 +482,7 @@ BOOST_AUTO_TEST_CASE(v5_mei_exp) { std::this_thread::sleep_for(std::chrono::seconds(2)); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -507,7 +501,7 @@ BOOST_AUTO_TEST_CASE(v5_mei_exp) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -529,7 +523,7 @@ BOOST_AUTO_TEST_CASE(v5_mei_exp) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // not recv publish (retain) yield { @@ -547,12 +541,12 @@ BOOST_AUTO_TEST_CASE(v5_mei_exp) { if (count++ == 0) { // 1st BOOST_TEST(ec == am::errc::success); // timeout - BOOST_TEST(!pv); // not recv + BOOST_TEST(!pv_opt); // not recv ep(sub).async_close(*this); } else { // 2nd - BOOST_TEST(!pv); // recv error due to close + BOOST_TEST(!pv_opt); // recv error due to close } } @@ -599,7 +593,7 @@ BOOST_AUTO_TEST_CASE(v5_clear) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -613,8 +607,7 @@ BOOST_AUTO_TEST_CASE(v5_clear) { ) ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -633,7 +626,7 @@ BOOST_AUTO_TEST_CASE(v5_clear) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // publish QoS0 yield ep(pub).async_send( @@ -667,8 +660,7 @@ BOOST_AUTO_TEST_CASE(v5_clear) { ); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -687,7 +679,7 @@ BOOST_AUTO_TEST_CASE(v5_clear) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -709,7 +701,7 @@ BOOST_AUTO_TEST_CASE(v5_clear) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // not recv publish (retain) yield { @@ -727,12 +719,12 @@ BOOST_AUTO_TEST_CASE(v5_clear) { if (count++ == 0) { // 1st BOOST_TEST(ec == am::errc::success); // timeout - BOOST_TEST(!pv); // not recv + BOOST_TEST(!pv_opt); // not recv ep(sub).async_close(*this); } else { // 2nd - BOOST_TEST(!pv); // recv error due to close + BOOST_TEST(!pv_opt); // recv error due to close } } diff --git a/test/system/st_shared_sub.cpp b/test/system/st_shared_sub.cpp index e624ac449..9bf39ac04 100644 --- a/test/system/st_shared_sub.cpp +++ b/test/system/st_shared_sub.cpp @@ -50,7 +50,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -66,8 +66,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { *this ) ); - yield am::async_underlying_handshake( - ep(sub1).next_layer(), + yield ep(sub1).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -86,7 +85,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { ); BOOST_TEST(!ec); yield ep(sub1).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( as::bind_executor( ep(sub1).get_executor(), @@ -104,11 +103,10 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { ); BOOST_TEST(!ec); yield ep(sub1).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // connect sub2 - yield am::async_underlying_handshake( - ep(sub2).next_layer(), + yield ep(sub2).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -134,7 +132,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { ); BOOST_TEST(!ec); yield ep(sub2).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( as::bind_executor( ep(sub2).get_executor(), @@ -152,7 +150,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { ); BOOST_TEST(!ec); yield ep(sub2).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // connect sub3 yield as::dispatch( @@ -161,8 +159,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { *this ) ); - yield am::async_underlying_handshake( - ep(sub3).next_layer(), + yield ep(sub3).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -181,7 +178,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { ); BOOST_TEST(!ec); yield ep(sub3).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( as::bind_executor( @@ -200,7 +197,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { ); BOOST_TEST(!ec); yield ep(sub3).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // connect pub yield as::dispatch( @@ -209,8 +206,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { *this ) ); - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -229,7 +225,7 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // publish 1 yield ep(pub).async_send( @@ -336,9 +332,9 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { *this ) ); - yield ep(sub1).async_recv(*this); + yield ep(sub1).async_recv(am::filter::match, {am::control_packet_type::publish}, *this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ "topic1", @@ -353,9 +349,9 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { *this ) ); - yield ep(sub2).async_recv(*this); + yield ep(sub2).async_recv(am::filter::match, {am::control_packet_type::publish}, *this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ 1, @@ -371,9 +367,9 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { *this ) ); - yield ep(sub3).async_recv(*this); + yield ep(sub3).async_recv(am::filter::match, {am::control_packet_type::publish}, *this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ 1, @@ -389,9 +385,9 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { *this ) ); - yield ep(sub1).async_recv(*this); + yield ep(sub1).async_recv(am::filter::match, {am::control_packet_type::publish}, *this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ "topic1", @@ -406,9 +402,9 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { *this ) ); - yield ep(sub2).async_recv(*this); + yield ep(sub2).async_recv(am::filter::match, {am::control_packet_type::publish}, *this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ 2, @@ -424,9 +420,9 @@ BOOST_AUTO_TEST_CASE(v5_from_broker) { *this ) ); - yield ep(sub3).async_recv(*this); + yield ep(sub3).async_recv(am::filter::match, {am::control_packet_type::publish}, *this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ 2, @@ -513,7 +509,7 @@ BOOST_AUTO_TEST_CASE(v5_unsub_from_broker) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type pid ) override { reenter(this) { @@ -530,8 +526,7 @@ BOOST_AUTO_TEST_CASE(v5_unsub_from_broker) { ); // connect sub1 - yield am::async_underlying_handshake( - ep(sub1).next_layer(), + yield ep(sub1).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -550,7 +545,7 @@ BOOST_AUTO_TEST_CASE(v5_unsub_from_broker) { ); BOOST_TEST(!ec); yield ep(sub1).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield ep(sub1).async_send( am::v5::subscribe_packet{ *ep(sub1).acquire_unique_packet_id(), @@ -563,7 +558,7 @@ BOOST_AUTO_TEST_CASE(v5_unsub_from_broker) { ); BOOST_TEST(!ec); yield ep(sub1).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( as::bind_executor( @@ -573,8 +568,7 @@ BOOST_AUTO_TEST_CASE(v5_unsub_from_broker) { ); // connect sub2 - yield am::async_underlying_handshake( - ep(sub2).next_layer(), + yield ep(sub2).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -593,7 +587,7 @@ BOOST_AUTO_TEST_CASE(v5_unsub_from_broker) { ); BOOST_TEST(!ec); yield ep(sub2).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield ep(sub2).async_send( am::v5::subscribe_packet{ *ep(sub2).acquire_unique_packet_id(), @@ -606,7 +600,7 @@ BOOST_AUTO_TEST_CASE(v5_unsub_from_broker) { ); BOOST_TEST(!ec); yield ep(sub2).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( as::bind_executor( @@ -616,8 +610,7 @@ BOOST_AUTO_TEST_CASE(v5_unsub_from_broker) { ); // connect sub3 - yield am::async_underlying_handshake( - ep(sub3).next_layer(), + yield ep(sub3).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -636,7 +629,7 @@ BOOST_AUTO_TEST_CASE(v5_unsub_from_broker) { ); BOOST_TEST(!ec); yield ep(sub3).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield ep(sub3).async_send( am::v5::subscribe_packet{ *ep(sub3).acquire_unique_packet_id(), @@ -649,7 +642,7 @@ BOOST_AUTO_TEST_CASE(v5_unsub_from_broker) { ); BOOST_TEST(!ec); yield ep(sub3).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( as::bind_executor( @@ -659,8 +652,7 @@ BOOST_AUTO_TEST_CASE(v5_unsub_from_broker) { ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -679,7 +671,7 @@ BOOST_AUTO_TEST_CASE(v5_unsub_from_broker) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // publish 1 yield ep(pub).async_send( @@ -726,9 +718,9 @@ BOOST_AUTO_TEST_CASE(v5_unsub_from_broker) { ) ); - yield ep(sub1).async_recv(*this); + yield ep(sub1).async_recv(am::filter::match, {am::control_packet_type::publish}, *this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ "topic1", @@ -745,9 +737,9 @@ BOOST_AUTO_TEST_CASE(v5_unsub_from_broker) { ) ); - yield ep(sub2).async_recv(*this); + yield ep(sub2).async_recv(am::filter::match, {am::control_packet_type::publish}, *this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ 1, @@ -764,9 +756,9 @@ BOOST_AUTO_TEST_CASE(v5_unsub_from_broker) { *this ) ); - yield ep(sub3).async_recv(*this); + yield ep(sub3).async_recv(am::filter::match, {am::control_packet_type::publish}, *this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ 1, @@ -798,7 +790,7 @@ BOOST_AUTO_TEST_CASE(v5_unsub_from_broker) { ); BOOST_TEST(!ec); yield ep(sub1).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( as::bind_executor( @@ -851,9 +843,9 @@ BOOST_AUTO_TEST_CASE(v5_unsub_from_broker) { ) ); - yield ep(sub2).async_recv(*this); + yield ep(sub2).async_recv(am::filter::match, {am::control_packet_type::publish}, *this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ "topic1", @@ -870,10 +862,9 @@ BOOST_AUTO_TEST_CASE(v5_unsub_from_broker) { ) ); - yield ep(sub3).async_recv(*this); // recv pubrel - yield ep(sub3).async_recv(*this); + yield ep(sub3).async_recv(am::filter::match, {am::control_packet_type::publish}, *this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ 2, @@ -890,9 +881,9 @@ BOOST_AUTO_TEST_CASE(v5_unsub_from_broker) { *this ) ); - yield ep(sub2).async_recv(*this); + yield ep(sub2).async_recv(am::filter::match, {am::control_packet_type::publish}, *this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ 1, diff --git a/test/system/st_sub.cpp b/test/system/st_sub.cpp index 70f1afb46..7ce81d251 100644 --- a/test/system/st_sub.cpp +++ b/test/system/st_sub.cpp @@ -32,7 +32,7 @@ BOOST_AUTO_TEST_CASE(v311_sub) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -42,8 +42,7 @@ BOOST_AUTO_TEST_CASE(v311_sub) { *this ) ); - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -62,7 +61,7 @@ BOOST_AUTO_TEST_CASE(v311_sub) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // subscribe pid = *ep().acquire_unique_packet_id(); @@ -80,7 +79,7 @@ BOOST_AUTO_TEST_CASE(v311_sub) { BOOST_TEST(!ec); yield ep().async_recv(*this); BOOST_TEST( - pv == (am::v3_1_1::suback_packet{ + *pv_opt == (am::v3_1_1::suback_packet{ pid, { am::suback_return_code::success_maximum_qos_0, @@ -106,7 +105,7 @@ BOOST_AUTO_TEST_CASE(v311_sub) { BOOST_TEST(!ec); yield ep().async_recv(*this); BOOST_TEST( - pv == (am::v3_1_1::suback_packet{ + *pv_opt == (am::v3_1_1::suback_packet{ pid, { am::suback_return_code::success_maximum_qos_1, @@ -132,7 +131,7 @@ BOOST_AUTO_TEST_CASE(v311_sub) { BOOST_TEST(!ec); yield ep().async_recv(*this); BOOST_TEST( - pv == am::v3_1_1::unsuback_packet{ + *pv_opt == am::v3_1_1::unsuback_packet{ pid } ); @@ -165,7 +164,7 @@ BOOST_AUTO_TEST_CASE(v5_sub) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -175,8 +174,7 @@ BOOST_AUTO_TEST_CASE(v5_sub) { *this ) ); - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "1883", *this @@ -196,7 +194,7 @@ BOOST_AUTO_TEST_CASE(v5_sub) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); // subscribe pid = *ep().acquire_unique_packet_id(); @@ -231,7 +229,7 @@ BOOST_AUTO_TEST_CASE(v5_sub) { BOOST_TEST(!ec); yield ep().async_recv(*this); BOOST_TEST( - pv == (am::v5::suback_packet{ + *pv_opt == (am::v5::suback_packet{ pid, { am::suback_reason_code::granted_qos_0, @@ -259,7 +257,7 @@ BOOST_AUTO_TEST_CASE(v5_sub) { BOOST_TEST(!ec); yield ep().async_recv(*this); BOOST_TEST( - pv == (am::v5::suback_packet{ + *pv_opt == (am::v5::suback_packet{ pid, { am::suback_reason_code::granted_qos_1, @@ -287,7 +285,7 @@ BOOST_AUTO_TEST_CASE(v5_sub) { BOOST_TEST(!ec); yield ep().async_recv(*this); BOOST_TEST( - pv == (am::v5::unsuback_packet{ + *pv_opt == (am::v5::unsuback_packet{ pid, { am::unsuback_reason_code::success, diff --git a/test/system/st_will.cpp b/test/system/st_will.cpp index 720473b93..37860fe5f 100644 --- a/test/system/st_will.cpp +++ b/test/system/st_will.cpp @@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE(v311_will) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -52,8 +52,7 @@ BOOST_AUTO_TEST_CASE(v311_will) { ); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -72,7 +71,7 @@ BOOST_AUTO_TEST_CASE(v311_will) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -94,7 +93,7 @@ BOOST_AUTO_TEST_CASE(v311_will) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( as::bind_executor( @@ -104,8 +103,7 @@ BOOST_AUTO_TEST_CASE(v311_will) { ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -128,7 +126,7 @@ BOOST_AUTO_TEST_CASE(v311_will) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield ep(pub).async_close(*this); yield as::dispatch( @@ -140,7 +138,7 @@ BOOST_AUTO_TEST_CASE(v311_will) { yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v3_1_1::publish_packet{ "topic1", @@ -185,7 +183,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_send) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -197,8 +195,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_send) { ); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -217,7 +214,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_send) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -239,7 +236,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_send) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( as::bind_executor( @@ -249,8 +246,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_send) { ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -277,7 +273,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_send) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield ep(pub).async_close(*this); yield as::dispatch( @@ -288,7 +284,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_send) { ); yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ "topic1", @@ -333,7 +329,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_send_sei) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -345,8 +341,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_send_sei) { ); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -365,7 +360,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_send_sei) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -387,7 +382,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_send_sei) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( as::bind_executor( @@ -397,8 +392,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_send_sei) { ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -425,7 +419,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_send_sei) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield ep(pub).async_close(*this); yield as::dispatch( @@ -436,7 +430,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_send_sei) { ); yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ "topic1", @@ -481,7 +475,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_send_sei_disconnect) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -493,8 +487,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_send_sei_disconnect) { ); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -513,7 +506,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_send_sei_disconnect) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -535,7 +528,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_send_sei_disconnect) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( as::bind_executor( @@ -545,8 +538,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_send_sei_disconnect) { ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -573,7 +565,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_send_sei_disconnect) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield ep(pub).async_send( am::v5::disconnect_packet{ am::disconnect_reason_code::disconnect_with_will_message @@ -592,7 +584,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_send_sei_disconnect) { yield ep(sub).async_recv(*this); BOOST_TEST( - pv + *pv_opt == (am::v5::publish_packet{ "topic1", @@ -638,7 +630,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_not_send_sei_disconnect) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -650,8 +642,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_not_send_sei_disconnect) { ); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -670,7 +661,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_not_send_sei_disconnect) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -692,7 +683,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_not_send_sei_disconnect) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( as::bind_executor( @@ -702,8 +693,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_not_send_sei_disconnect) { ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -727,7 +717,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_not_send_sei_disconnect) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield ep(pub).async_send( am::v5::disconnect_packet{ am::disconnect_reason_code::normal_disconnection @@ -763,12 +753,12 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_not_send_sei_disconnect) { if (count++ == 0) { // 1st BOOST_TEST(ec == am::errc::success); // timeout - BOOST_TEST(!pv); // not recv + BOOST_TEST(!pv_opt); // not recv ep(sub).async_close(*this); } else { // 2nd - BOOST_TEST(!pv); // recv error due to close + BOOST_TEST(!pv_opt); // recv error due to close } } set_finish(); @@ -807,7 +797,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_not_send_mei) { }; void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { @@ -819,8 +809,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_not_send_mei) { ); // connect sub - yield am::async_underlying_handshake( - ep(sub).next_layer(), + yield ep(sub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -839,7 +828,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_not_send_mei) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -861,7 +850,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_not_send_mei) { ); BOOST_TEST(!ec); yield ep(sub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield as::dispatch( as::bind_executor( @@ -871,8 +860,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_not_send_mei) { ); // connect pub - yield am::async_underlying_handshake( - ep(pub).next_layer(), + yield ep(pub).async_underlying_handshake( "127.0.0.1", "1883", *this @@ -902,7 +890,7 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_not_send_mei) { ); BOOST_TEST(!ec); yield ep(pub).async_recv(*this); - BOOST_TEST(pv.get_if()); + BOOST_TEST(pv_opt->get_if()); yield ep(pub).async_close(*this); yield as::dispatch( @@ -931,12 +919,12 @@ BOOST_AUTO_TEST_CASE(v5_will_wd_not_send_mei) { if (count++ == 0) { // 1st BOOST_TEST(ec == am::errc::success); // timeout - BOOST_TEST(!pv); // not recv + BOOST_TEST(!pv_opt); // not recv ep(sub).async_close(*this); } else { // 2nd - BOOST_TEST(!pv); // recv error due to close + BOOST_TEST(!pv_opt); // recv error due to close } } set_finish(); diff --git a/test/system/st_ws_connect.cpp b/test/system/st_ws_connect.cpp index 6f102b002..806feb378 100644 --- a/test/system/st_ws_connect.cpp +++ b/test/system/st_ws_connect.cpp @@ -29,8 +29,7 @@ BOOST_AUTO_TEST_CASE(cb) { am::protocol::ws{ioc.get_executor()} }; - am::async_underlying_handshake( - amep.next_layer(), + amep.async_underlying_handshake( "127.0.0.1", "10080", [&](am::error_code const& ec) { @@ -47,9 +46,9 @@ BOOST_AUTO_TEST_CASE(cb) { [&](am::error_code const& ec) { BOOST_TEST(!ec); amep.async_recv( - [&](am::error_code const& ec, am::packet_variant pv) { + [&](am::error_code const& ec, std::optional pv_opt) { BOOST_TEST(!ec); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -93,8 +92,7 @@ BOOST_AUTO_TEST_CASE(fut) { ); { - auto fut = am::async_underlying_handshake( - amep.next_layer(), + auto fut = amep.async_underlying_handshake( "127.0.0.1", "10080", "/", @@ -131,8 +129,8 @@ BOOST_AUTO_TEST_CASE(fut) { auto fut = amep.async_recv(as::use_future); try { - auto pv = fut.get(); - pv.visit( + auto pv_opt = fut.get(); + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -167,12 +165,11 @@ BOOST_AUTO_TEST_CASE(coro) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "10080", "/", @@ -192,7 +189,7 @@ BOOST_AUTO_TEST_CASE(coro) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); diff --git a/test/system/st_wss_connect.cpp b/test/system/st_wss_connect.cpp index 5aa9f7a8c..53152eb67 100644 --- a/test/system/st_wss_connect.cpp +++ b/test/system/st_wss_connect.cpp @@ -34,8 +34,7 @@ BOOST_AUTO_TEST_CASE(cb) { ctx }; - am::async_underlying_handshake( - amep.next_layer(), + amep.async_underlying_handshake( "127.0.0.1", "10443", [&](am::error_code const& ec) { @@ -52,9 +51,9 @@ BOOST_AUTO_TEST_CASE(cb) { [&](am::error_code const& ec) { BOOST_TEST(!ec); amep.async_recv( - [&](am::error_code const& ec, am::packet_variant pv) { + [&](am::error_code const& ec, std::optional pv_opt) { BOOST_TEST(!ec); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -106,8 +105,7 @@ BOOST_AUTO_TEST_CASE(fut) { ); { - auto fut = am::async_underlying_handshake( - amep.next_layer(), + auto fut = amep.async_underlying_handshake( "127.0.0.1", "10443", "/", @@ -144,8 +142,8 @@ BOOST_AUTO_TEST_CASE(fut) { auto fut = amep.async_recv(as::use_future); try { - auto pv = fut.get(); - pv.visit( + auto pv_opt = fut.get(); + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); @@ -185,12 +183,11 @@ BOOST_AUTO_TEST_CASE(coro) { private: void proc( am::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type /*pid*/ ) override { reenter(this) { - yield am::async_underlying_handshake( - ep().next_layer(), + yield ep().async_underlying_handshake( "127.0.0.1", "10443", "/", @@ -210,7 +207,7 @@ BOOST_AUTO_TEST_CASE(coro) { ); BOOST_TEST(!ec); yield ep().async_recv(*this); - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::connack_packet const& p) { BOOST_TEST(!p.session_present()); diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 0c72b30f0..4332381bf 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -20,6 +20,7 @@ list(APPEND check_PROGRAMS ut_broker_security.cpp ut_buffer.cpp ut_code.cpp + ut_connection.cpp ut_ep_alloc.cpp ut_ep_con_discon.cpp ut_ep_keep_alive.cpp @@ -64,7 +65,6 @@ list(APPEND check_PROGRAMS ut_packet_variant.cpp ut_property.cpp ut_prop_variant.cpp - ut_prop_variant_no_assert.cpp ut_retained_topic_map.cpp ut_retained_topic_map_broker.cpp ut_strm.cpp diff --git a/test/unit/cpp20coro_stub_socket.hpp b/test/unit/cpp20coro_stub_socket.hpp index 899639e56..def65f083 100644 --- a/test/unit/cpp20coro_stub_socket.hpp +++ b/test/unit/cpp20coro_stub_socket.hpp @@ -12,11 +12,11 @@ #include #include -#include -#include -#include +#include +#include +#include +#include #include -#include #include "test_allocate_buffer.hpp" @@ -32,8 +32,8 @@ struct cpp20coro_basic_stub_socket { struct error_packet { error_packet( - packet_variant_type pv - ): packet{ to_string(pv.const_buffer_sequence()) } + std::optional pv + ): packet{ to_string(pv->const_buffer_sequence()) } {} error_packet( @@ -71,7 +71,7 @@ struct cpp20coro_basic_stub_socket { CompletionToken, void() > ( - emulate_recv_impl{ + emulate_recv_op{ *this, error_packet{std::forward(t)} }, @@ -94,9 +94,9 @@ struct cpp20coro_basic_stub_socket { auto wait_response(CompletionToken&& token) { return as::async_compose< CompletionToken, - void(error_code, packet_variant_type) + void(error_code, std::optional) > ( - wait_response_impl{ + wait_response_op{ *this }, token, @@ -104,7 +104,7 @@ struct cpp20coro_basic_stub_socket { ); } - struct emulate_recv_impl { + struct emulate_recv_op { this_type& socket; error_packet epk; @@ -127,7 +127,7 @@ struct cpp20coro_basic_stub_socket { } }; - struct wait_response_impl { + struct wait_response_op { this_type& socket; template @@ -145,7 +145,7 @@ struct cpp20coro_basic_stub_socket { error_packet epk ) { if (epk.ec) { - self.complete(epk.ec, packet_variant_type{}); + self.complete(epk.ec, std::nullopt); } else { buffer buf{epk.packet}; @@ -181,7 +181,7 @@ struct cpp20coro_basic_stub_socket { CompletionToken, void(error_code const& ec, std::size_t) > ( - async_write_some_impl{ + async_write_some_op{ *this, buffers }, @@ -191,7 +191,7 @@ struct cpp20coro_basic_stub_socket { } template - struct async_write_some_impl { + struct async_write_some_op { this_type& socket; ConstBufferSequence buffers; @@ -237,7 +237,7 @@ struct cpp20coro_basic_stub_socket { CompletionToken, void(error_code const& ec, std::size_t) > ( - async_read_some_impl{ + async_read_some_op{ *this, mb }, @@ -247,7 +247,7 @@ struct cpp20coro_basic_stub_socket { } template - struct async_read_some_impl { + struct async_read_some_op { this_type& socket; MutableBufferSequence mb; enum { read, complete } state = read; @@ -325,15 +325,65 @@ struct cpp20coro_basic_stub_socket { using cpp20coro_stub_socket = cpp20coro_basic_stub_socket<2>; -template <> -struct layer_customize { +template +struct layer_customize> { + template < + typename CompletionToken + > + static auto + async_handshake( + cpp20coro_basic_stub_socket& stream, + CompletionToken&& token + ) { + return + as::async_compose< + CompletionToken, + void(error_code) + >( + async_handshake_op{ + stream + }, + token, + stream + ); + } + + struct async_handshake_op { + cpp20coro_basic_stub_socket& stream; + enum {dispatch, complete} state = dispatch; + + async_handshake_op( + cpp20coro_basic_stub_socket& stream + ): stream{stream} + {} + + template + void operator()( + Self& self + ) { + switch (state) { + case dispatch: { + state = complete; + auto& a_stream{stream}; + as::dispatch( + a_stream.get_executor(), + force_move(self) + ); + } break; + case complete: + self.complete(error_code{}); + break; + } + } + }; + template < typename MutableBufferSequence, typename CompletionToken > static auto async_read( - cpp20coro_stub_socket& stream, + cpp20coro_basic_stub_socket& stream, MutableBufferSequence const& mbs, CompletionToken&& token ) { @@ -341,7 +391,7 @@ struct layer_customize { CompletionToken, void(error_code const& ec, std::size_t) > ( - async_read_impl{ + async_read_op{ stream, mbs }, @@ -351,14 +401,14 @@ struct layer_customize { } template - struct async_read_impl { - async_read_impl( - cpp20coro_stub_socket& stream, + struct async_read_op { + async_read_op( + cpp20coro_basic_stub_socket& stream, MutableBufferSequence const& mbs ): stream{stream}, mbs{mbs} {} - cpp20coro_stub_socket& stream; + cpp20coro_basic_stub_socket& stream; MutableBufferSequence mbs; template @@ -387,7 +437,7 @@ struct layer_customize { > static auto async_write( - cpp20coro_stub_socket& stream, + cpp20coro_basic_stub_socket& stream, ConstBufferSequence const& cbs, CompletionToken&& token ) { @@ -395,7 +445,7 @@ struct layer_customize { CompletionToken, void(error_code const& ec, std::size_t) > ( - async_write_impl{ + async_write_op{ stream, cbs }, @@ -405,14 +455,14 @@ struct layer_customize { } template - struct async_write_impl { - async_write_impl( - cpp20coro_stub_socket& stream, + struct async_write_op { + async_write_op( + cpp20coro_basic_stub_socket& stream, ConstBufferSequence const& cbs ): stream{stream}, cbs{cbs} {} - cpp20coro_stub_socket& stream; + cpp20coro_basic_stub_socket& stream; ConstBufferSequence cbs; template @@ -440,50 +490,40 @@ struct layer_customize { > static auto async_close( - cpp20coro_stub_socket& stream, + cpp20coro_basic_stub_socket& stream, CompletionToken&& token ) { return as::async_compose< CompletionToken, void(error_code const& ec) > ( - async_close_impl{stream}, + async_close_op{stream}, token, stream ); } - struct async_close_impl { - async_close_impl( - cpp20coro_stub_socket& stream + struct async_close_op { + async_close_op( + cpp20coro_basic_stub_socket& stream ):stream{stream} {} - cpp20coro_stub_socket& stream; - enum {wait1, wait2, complete} state = wait1; + cpp20coro_basic_stub_socket& stream; + enum {dispatch, complete} state = dispatch; template void operator()( Self& self ) { switch (state) { - case wait1: - ASYNC_MQTT_LOG("mqtt_impl", info) - << "stub close wait1"; - state = wait2; - as::post( - stream.get_executor(), - force_move(self) - ); - break; - case wait2: - ASYNC_MQTT_LOG("mqtt_impl", info) - << "stub close wait2"; + case dispatch: { state = complete; - as::post( - stream.get_executor(), + auto& a_stream{stream}; + as::dispatch( + a_stream.get_executor(), force_move(self) ); - break; + } break; case complete: { error_code ec; if (stream.is_open()) { @@ -502,94 +542,6 @@ struct layer_customize { }; }; -template <> -struct layer_customize> { - template < - typename MutableBufferSequence, - typename CompletionToken - > - static auto - async_read( - cpp20coro_basic_stub_socket<4>& stream, - MutableBufferSequence const& mbs, - CompletionToken&& token - ) { - return as::async_compose< - CompletionToken, - void(error_code const& ec, std::size_t) - > ( - async_read_impl{ - stream, - mbs - }, - token, - stream - ); - } - - template - struct async_read_impl { - async_read_impl( - cpp20coro_basic_stub_socket<4>& stream, - MutableBufferSequence const& mbs - ): stream{stream}, mbs{mbs} - {} - - cpp20coro_basic_stub_socket<4>& stream; - MutableBufferSequence mbs; - - template - void operator()( - Self& self - ) { - return stream.async_read_some( - mbs, - force_move(self) - ); - } - - template - void operator()( - Self& self, - error_code const& ec, - std::size_t size - ) { - self.complete(ec, size); - } - }; - - - template < - typename CompletionToken - > - static auto - async_close( - cpp20coro_basic_stub_socket<4>& stream, - CompletionToken&& token - ) { - return as::async_compose< - CompletionToken, - void(error_code const& ec) - > ( - [&stream](auto& self) { - error_code ec; - if (stream.is_open()) { - ASYNC_MQTT_LOG("mqtt_impl", info) - << "stub close"; - stream.close(ec); - } - else { - ASYNC_MQTT_LOG("mqtt_impl", info) - << "stub already closed"; - } - self.complete(ec); - }, - token, - stream - ); - } -}; - } // namespace async_mqtt #endif // ASYNC_MQTT_CPP20CORO_STUB_SOCKET_HPP diff --git a/test/unit/stub_socket.hpp b/test/unit/stub_socket.hpp index 37d17fa62..5c9a14590 100644 --- a/test/unit/stub_socket.hpp +++ b/test/unit/stub_socket.hpp @@ -10,11 +10,11 @@ #include #include -#include -#include -#include +#include +#include +#include +#include #include -#include #include #include "test_allocate_buffer.hpp" @@ -118,7 +118,7 @@ struct basic_stub_socket { CompletionToken, void(error_code const& ec, std::size_t) > ( - async_write_some_impl{ + async_write_some_op{ *this, buffers }, @@ -128,7 +128,7 @@ struct basic_stub_socket { } template - struct async_write_some_impl { + struct async_write_some_op { this_type& socket; ConstBufferSequence buffers; @@ -147,7 +147,7 @@ struct basic_stub_socket { auto buf = allocate_buffer(packet_begin, packet_end); error_code ec; auto pv = buffer_to_basic_packet_variant(buf, socket.version_, ec); - if (socket.write_packet_checker_) socket.write_packet_checker_(pv); + if (socket.write_packet_checker_) socket.write_packet_checker_(*pv); it = packet_end; packet_begin = packet_end; } @@ -165,7 +165,7 @@ struct basic_stub_socket { CompletionToken, void(error_code const& ec, std::size_t) > ( - async_read_some_impl{ + async_read_some_op{ *this, mb }, @@ -175,7 +175,7 @@ struct basic_stub_socket { } template - struct async_read_some_impl { + struct async_read_some_op { this_type& socket; MutableBufferSequence mb; enum { read, complete } state = read; @@ -218,31 +218,30 @@ struct basic_stub_socket { socket.packet_it_opt_.emplace(begin); } auto packet_it = *socket.packet_it_opt_; - BOOST_ASSERT( - static_cast(std::distance(packet_it, end)) >= mb.size() - ); + auto rest_size = static_cast(std::distance(packet_it, end)); + auto copy_size = std::min(rest_size, mb.size()); std::copy_n( packet_it, - mb.size(), + copy_size, static_cast(mb.data()) ); - std::advance(packet_it, static_cast(mb.size())); + std::advance(packet_it, static_cast(copy_size)); if (packet_it == end) { // all conttents have read socket.packet_it_opt_.reset(); ++socket.recv_packets_it_; } else { - *socket.packet_it_opt_ = packet_it; + socket.packet_it_opt_.emplace(packet_it); } - self.complete(errc::make_error_code(errc::success), mb.size()); + self.complete(errc::make_error_code(errc::success), copy_size); } }; private: template - friend struct async_read_some_impl; + friend struct async_read_some_op; protocol_version version_; as::any_io_executor exe_; packet_queue_t recv_packets_; @@ -275,102 +274,65 @@ void async_read( socket.async_read_some(mb, std::forward(token)); } -template <> -struct layer_customize { +template +struct layer_customize> { template < - typename MutableBufferSequence, typename CompletionToken > static auto - async_read( - stub_socket& stream, - MutableBufferSequence const& mbs, + async_handshake( + basic_stub_socket& stream, CompletionToken&& token ) { - return as::async_compose< - CompletionToken, - void(error_code const& ec, std::size_t) - > ( - async_read_impl{ - stream, - mbs + return + as::async_compose< + CompletionToken, + void(error_code) + >( + async_handshake_op{ + stream }, token, stream ); } - template - struct async_read_impl { - async_read_impl( - stub_socket& stream, - MutableBufferSequence const& mbs - ): stream{stream}, mbs{mbs} - {} + struct async_handshake_op { + basic_stub_socket& stream; + enum {dispatch, complete} state = dispatch; - stub_socket& stream; - MutableBufferSequence mbs; + async_handshake_op( + basic_stub_socket& stream + ): stream{stream} + {} template void operator()( Self& self ) { - return stream.async_read_some( - mbs, - force_move(self) - ); - } - - template - void operator()( - Self& self, - error_code const& ec, - std::size_t size - ) { - self.complete(ec, size); + switch (state) { + case dispatch: { + state = complete; + auto& a_stream{stream}; + as::dispatch( + a_stream.get_executor(), + force_move(self) + ); + } break; + case complete: + self.complete(error_code{}); + break; + } } }; - template < - typename CompletionToken - > - static auto - async_close( - stub_socket& stream, - CompletionToken&& token - ) { - return as::async_compose< - CompletionToken, - void(error_code const& ec) - > ( - [&stream](auto& self) { - error_code ec; - if (stream.is_open()) { - ASYNC_MQTT_LOG("mqtt_impl", info) - << "stub close"; - stream.close(ec); - } - else { - ASYNC_MQTT_LOG("mqtt_impl", info) - << "stub already closed"; - } - self.complete(ec); - }, - token, - stream - ); - } -}; - -template <> -struct layer_customize> { template < typename MutableBufferSequence, typename CompletionToken > static auto async_read( - basic_stub_socket<4>& stream, + basic_stub_socket& stream, MutableBufferSequence const& mbs, CompletionToken&& token ) { @@ -378,7 +340,7 @@ struct layer_customize> { CompletionToken, void(error_code const& ec, std::size_t) > ( - async_read_impl{ + async_read_op{ stream, mbs }, @@ -388,21 +350,21 @@ struct layer_customize> { } template - struct async_read_impl { - async_read_impl( - basic_stub_socket<4>& stream, + struct async_read_op { + basic_stub_socket& stream; + MutableBufferSequence mbs; + + async_read_op( + basic_stub_socket& stream, MutableBufferSequence const& mbs ): stream{stream}, mbs{mbs} {} - basic_stub_socket<4>& stream; - MutableBufferSequence mbs; - template void operator()( Self& self ) { - return stream.async_read_some( + stream.async_read_some( mbs, force_move(self) ); @@ -423,7 +385,7 @@ struct layer_customize> { > static auto async_close( - basic_stub_socket<4>& stream, + basic_stub_socket& stream, CompletionToken&& token ) { return as::async_compose< diff --git a/test/unit/ut_buffer.cpp b/test/unit/ut_buffer.cpp index 5e43af996..a50b09c3b 100644 --- a/test/unit/ut_buffer.cpp +++ b/test/unit/ut_buffer.cpp @@ -9,9 +9,9 @@ #include #include -#include +#include -#include +#include BOOST_AUTO_TEST_SUITE(ut_buffer) diff --git a/test/unit/ut_code.cpp b/test/unit/ut_code.cpp index 474170c4c..bda7026b6 100644 --- a/test/unit/ut_code.cpp +++ b/test/unit/ut_code.cpp @@ -10,11 +10,11 @@ #include #include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_code) diff --git a/test/unit/ut_connection.cpp b/test/unit/ut_connection.cpp new file mode 100644 index 000000000..8a5fac576 --- /dev/null +++ b/test/unit/ut_connection.cpp @@ -0,0 +1,111 @@ +// Copyright Takatoshi Kondo 2024 +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include "../common/test_main.hpp" +#include "../common/global_fixture.hpp" + +#include + +BOOST_AUTO_TEST_SUITE(ut_connection) + +namespace am = async_mqtt; + + +BOOST_AUTO_TEST_CASE(v5_connect_connack) { + am::rv_connection c{am::protocol_version::v5}; + + auto w = am::will{ + "topic1", + "payload1", + am::pub::retain::yes | am::qos::at_least_once, + am::properties{ + am::property::will_delay_interval(0x0fffffff), + am::property::content_type("json") + } + }; + + auto props = am::properties{ + am::property::session_expiry_interval(0x0fffffff), + am::property::user_property("mykey", "myval") + }; + + auto p = am::v5::connect_packet{ + true, // clean_start + 0x1234, // keep_alive + "cid1", + w, + "user1", + "pass1", + props + }; + + auto events = c.send(p); + BOOST_TEST(events.size() == 2); + std::visit( + am::overload{ + [&](am::event::send const& ev) { + BOOST_TEST(!ev.get_release_packet_id_if_send_error()); + BOOST_TEST(ev.get() == p); + }, + [](auto const&...) { + BOOST_TEST(false); + } + }, + events[0] + ); + std::visit( + am::overload{ + [&](am::event::timer const& ev) { + BOOST_TEST(ev.get_op() == am::timer_op::reset); + BOOST_TEST(ev.get_kind() == am::timer_kind::pingreq_send); + BOOST_CHECK(ev.get_ms() == std::chrono::seconds{0x1234}); + }, + [](auto const&...) { + BOOST_TEST(false); + } + }, + events[1] + ); + + char recv_connack[] { + 0x20, // fixed_header + 0x08, // remaining_length + 0x01, // session_present + char(0x87), // connect_reason_code + 0x05, // property_length + 0x11, 0x0f, char(0xff), char(0xff), char(0xff), // session_expiry_interval + }; + + std::istringstream is{std::string{recv_connack, sizeof(recv_connack)}}; + events = c.recv(is); + BOOST_TEST(events.size() == 1); + { + auto expected = + [&] { + auto props = am::properties{ + am::property::session_expiry_interval(0x0fffffff) + }; + return am::v5::connack_packet{ + true, // session_present + am::connect_reason_code::not_authorized, + props + }; + } (); + std::visit( + am::overload{ + [&](am::event::packet_received const& ev) { + BOOST_TEST(ev.get() == expected); + }, + [](auto const&...) { + BOOST_TEST(false); + } + }, + events[0] + ); + } +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/test/unit/ut_cpp20coro_broker.cpp b/test/unit/ut_cpp20coro_broker.cpp index 4c5612def..bbedc9246 100644 --- a/test/unit/ut_cpp20coro_broker.cpp +++ b/test/unit/ut_cpp20coro_broker.cpp @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include @@ -47,6 +47,7 @@ BOOST_AUTO_TEST_CASE(tc1) { am::protocol_version::v3_1_1, // for emulated client so should already be known exe ); + ep1->underlying_accepted(); brk.handle_accept(epv_t{ep1}); // underlying connect @@ -58,6 +59,7 @@ BOOST_AUTO_TEST_CASE(tc1) { am::protocol_version::v5, exe ); + ep2->underlying_accepted(); brk.handle_accept(epv_t{ep2}); { @@ -78,7 +80,7 @@ BOOST_AUTO_TEST_CASE(tc1) { am::connect_return_code::accepted }; auto b2c_packet = co_await ep1->next_layer().wait_response(as::deferred); - BOOST_TEST(b2c_packet == exp_packet); + BOOST_TEST(*b2c_packet == exp_packet); } { // subscribe ep1 @@ -103,7 +105,7 @@ BOOST_AUTO_TEST_CASE(tc1) { } }; auto b2c_packet = co_await ep1->next_layer().wait_response(as::deferred); - BOOST_TEST(b2c_packet == exp_packet); + BOOST_TEST(*b2c_packet == exp_packet); } { // connect ep2 @@ -127,7 +129,7 @@ BOOST_AUTO_TEST_CASE(tc1) { } }; auto b2c_packet = co_await ep2->next_layer().wait_response(as::deferred); - BOOST_TEST(b2c_packet == exp_packet); + BOOST_TEST(*b2c_packet == exp_packet); } { // subscribe ep2 @@ -150,7 +152,7 @@ BOOST_AUTO_TEST_CASE(tc1) { } }; auto b2c_packet = co_await ep2->next_layer().wait_response(as::deferred); - BOOST_TEST(b2c_packet == exp_packet); + BOOST_TEST(*b2c_packet == exp_packet); } { // publish ep2 @@ -176,7 +178,7 @@ BOOST_AUTO_TEST_CASE(tc1) { am::qos::at_most_once | am::pub::retain::no | am::pub::dup::no }; auto b2c_packet = co_await ep1->next_layer().wait_response(as::deferred); - BOOST_TEST(b2c_packet == exp_packet); + BOOST_TEST(*b2c_packet == exp_packet); } { std::set exp_packets { @@ -194,9 +196,9 @@ BOOST_AUTO_TEST_CASE(tc1) { }; // recv ep2 auto b2c_packet1 = co_await ep2->next_layer().wait_response(as::deferred); - BOOST_ASSERT(exp_packets.erase(b2c_packet1) == 1); + BOOST_ASSERT(exp_packets.erase(*b2c_packet1) == 1); auto b2c_packet2 = co_await ep2->next_layer().wait_response(as::deferred); - BOOST_ASSERT(exp_packets.erase(b2c_packet2) == 1); + BOOST_ASSERT(exp_packets.erase(*b2c_packet2) == 1); } { // close ep1 diff --git a/test/unit/ut_cpp20coro_cl.cpp b/test/unit/ut_cpp20coro_cl.cpp index 8e3e50085..875e8ccee 100644 --- a/test/unit/ut_cpp20coro_cl.cpp +++ b/test/unit/ut_cpp20coro_cl.cpp @@ -288,7 +288,9 @@ BOOST_AUTO_TEST_CASE(v311_subscribe_single_mismatch) { BOOST_TEST(false); } catch (am::system_error const& se) { - BOOST_TEST(se.code() == am::disconnect_reason_code::protocol_error); + // Invalid unsuback is received, then the connection is automatically + // closed, and all halfway operations are cancelled. + BOOST_TEST(se.code() == as::error::operation_aborted); } co_await cl.next_layer().emulate_close(as::use_awaitable); co_await cl.async_close(as::use_awaitable); @@ -616,7 +618,9 @@ BOOST_AUTO_TEST_CASE(v311_unsubscribe_mismatch) { BOOST_TEST(false); } catch (am::system_error const& se) { - BOOST_TEST(se.code() == am::disconnect_reason_code::protocol_error); + // Invalid suback is received, then the connection is automatically + // closed, and all halfway operations are cancelled. + BOOST_TEST(se.code() == as::error::operation_aborted); } co_await cl.next_layer().emulate_close(as::use_awaitable); co_await cl.async_close(as::use_awaitable); @@ -2037,12 +2041,12 @@ BOOST_AUTO_TEST_CASE(v5_recv_auth_disconnect_fast) { co_await cl.next_layer().emulate_recv(auth, as::use_awaitable); co_await cl.next_layer().emulate_recv(disconnect, as::use_awaitable); { - auto pv = co_await cl.async_recv(as::use_awaitable); - BOOST_TEST(pv == auth); + auto pv_opt = co_await cl.async_recv(as::use_awaitable); + BOOST_TEST(*pv_opt == auth); } { - auto pv = co_await cl.async_recv(as::use_awaitable); - BOOST_TEST(pv == disconnect); + auto pv_opt = co_await cl.async_recv(as::use_awaitable); + BOOST_TEST(*pv_opt == disconnect); } // tear down @@ -2091,11 +2095,11 @@ BOOST_AUTO_TEST_CASE(v5_recv_disconnect_last) { // test case auto disconnect = am::v5::disconnect_packet{}; - auto pv = co_await ( + auto pv_opt = co_await ( cl.next_layer().emulate_recv(disconnect, as::use_awaitable) && cl.async_recv(as::use_awaitable) ); - BOOST_TEST(pv == disconnect); + BOOST_TEST(*pv_opt == disconnect); // tear down co_await cl.next_layer().emulate_close(as::use_awaitable); diff --git a/test/unit/ut_cpp20coro_ep.cpp b/test/unit/ut_cpp20coro_ep.cpp index 1c720b817..b4376c460 100644 --- a/test/unit/ut_cpp20coro_ep.cpp +++ b/test/unit/ut_cpp20coro_ep.cpp @@ -39,6 +39,8 @@ BOOST_AUTO_TEST_CASE(pingresp_v311) { version, am::force_move(exe) }; + // connection established as server + ep.underlying_accepted(); ep.set_auto_ping_response(true); // prepare connect { @@ -63,7 +65,7 @@ BOOST_AUTO_TEST_CASE(pingresp_v311) { co_await ep.next_layer().emulate_recv(am::v3_1_1::pingreq_packet{}, as::as_tuple(as::deferred)); co_await ep.async_recv(as::as_tuple(as::deferred)); auto [ec, pingresp] = co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); - BOOST_TEST(pingresp == am::v3_1_1::pingresp_packet{}); + BOOST_TEST(*pingresp == am::v3_1_1::pingresp_packet{}); co_await ep.async_close(as::deferred); co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); } @@ -87,6 +89,8 @@ BOOST_AUTO_TEST_CASE(pingresp_v5) { version, am::force_move(exe) }; + // connection established as server + ep.underlying_accepted(); ep.set_auto_ping_response(true); // prepare connect { @@ -111,7 +115,7 @@ BOOST_AUTO_TEST_CASE(pingresp_v5) { co_await ep.next_layer().emulate_recv(am::v5::pingreq_packet{}, as::as_tuple(as::deferred)); co_await ep.async_recv(as::as_tuple(as::deferred)); auto [ec, pingresp] = co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); - BOOST_TEST(pingresp == am::v5::pingresp_packet{}); + BOOST_TEST(*pingresp == am::v5::pingresp_packet{}); co_await ep.async_close(as::deferred); co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); } @@ -135,6 +139,10 @@ BOOST_AUTO_TEST_CASE(pingresp_no_tout_v311) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } ep.set_pingresp_recv_timeout(std::chrono::milliseconds{10}); // prepare connect { @@ -190,6 +198,10 @@ BOOST_AUTO_TEST_CASE(pingresp_no_tout_v5) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } ep.set_pingresp_recv_timeout(std::chrono::milliseconds{10}); // prepare connect { @@ -245,6 +257,10 @@ BOOST_AUTO_TEST_CASE(pingresp_tout_v311) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } ep.set_pingreq_send_interval(std::chrono::milliseconds::zero()); // for coverage ep.set_pingresp_recv_timeout(std::chrono::milliseconds::zero()); // for coverage ep.set_pingresp_recv_timeout(std::chrono::milliseconds{10}); @@ -300,6 +316,10 @@ BOOST_AUTO_TEST_CASE(pingresp_tout_v5) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } ep.set_pingresp_recv_timeout(std::chrono::milliseconds{10}); // prepare connect { @@ -334,7 +354,7 @@ BOOST_AUTO_TEST_CASE(pingresp_tout_v5) { { auto [ec, disconnect] = co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); BOOST_TEST(!ec); - BOOST_TEST(disconnect == exp); + BOOST_TEST(*disconnect == exp); } { auto [ec, close] = co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); @@ -363,6 +383,10 @@ BOOST_AUTO_TEST_CASE(bulk_write) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } ep.set_bulk_write(true); // prepare connect { @@ -419,6 +443,8 @@ BOOST_AUTO_TEST_CASE(remaining_length_error) { version, am::force_move(exe) }; + // connection established as server + ep.underlying_accepted(); // test scenario { co_await ep.next_layer().emulate_recv( @@ -435,7 +461,7 @@ BOOST_AUTO_TEST_CASE(remaining_length_error) { ioc.run(); } -BOOST_AUTO_TEST_CASE(remaining_length_error_bulk) { +BOOST_AUTO_TEST_CASE(remaining_length_error_set_buffer_size) { auto version = am::protocol_version::v3_1_1; as::io_context ioc; as::co_spawn( @@ -448,7 +474,9 @@ BOOST_AUTO_TEST_CASE(remaining_length_error_bulk) { version, am::force_move(exe) }; - ep.set_bulk_read_buffer_size(4096); + // connection established as server + ep.underlying_accepted(); + ep.set_read_buffer_size(4096); // test scenario { co_await ep.next_layer().emulate_recv( @@ -480,6 +508,10 @@ BOOST_AUTO_TEST_CASE(sub_send_error_v5) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } // prepare connect { auto connect = am::v5::connect_packet{ @@ -541,6 +573,10 @@ BOOST_AUTO_TEST_CASE(unsub_send_error_v5) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } // prepare connect { auto connect = am::v5::connect_packet{ @@ -602,6 +638,10 @@ BOOST_AUTO_TEST_CASE(pub_send_error_v5) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } // prepare connect { auto connect = am::v5::connect_packet{ @@ -665,6 +705,10 @@ BOOST_AUTO_TEST_CASE(pub_recv_non_exist_ta_v5) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } // prepare connect { auto connect = am::v5::connect_packet{ @@ -713,7 +757,7 @@ BOOST_AUTO_TEST_CASE(pub_recv_non_exist_ta_v5) { { auto [ec, disconnect] = co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); BOOST_TEST(ec == am::error_code{}); - BOOST_TEST(disconnect == exp); + BOOST_TEST(*disconnect == exp); } { auto [ec, _] = co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); @@ -741,6 +785,10 @@ BOOST_AUTO_TEST_CASE(pub_recv_no_ta_v5) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } // prepare connect { auto connect = am::v5::connect_packet{ @@ -786,7 +834,7 @@ BOOST_AUTO_TEST_CASE(pub_recv_no_ta_v5) { { auto [ec, disconnect] = co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); BOOST_TEST(ec == am::error_code{}); - BOOST_TEST(disconnect == exp); + BOOST_TEST(*disconnect == exp); } { auto [ec, _] = co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); @@ -814,6 +862,10 @@ BOOST_AUTO_TEST_CASE(pub_recv_max_zero_ta_v5) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } // prepare connect { auto connect = am::v5::connect_packet{ @@ -861,7 +913,7 @@ BOOST_AUTO_TEST_CASE(pub_recv_max_zero_ta_v5) { { auto [ec, disconnect] = co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); BOOST_TEST(ec == am::error_code{}); - BOOST_TEST(disconnect == exp); + BOOST_TEST(*disconnect == exp); } { auto [ec, _] = co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); @@ -889,6 +941,10 @@ BOOST_AUTO_TEST_CASE(pub_send_max_zero_ta_v5) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } // prepare connect { auto connect = am::v5::connect_packet{ @@ -952,6 +1008,10 @@ BOOST_AUTO_TEST_CASE(pub_send_size_over_store_ta_v5) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } // prepare connect { auto connect = am::v5::connect_packet{ @@ -1035,6 +1095,10 @@ BOOST_AUTO_TEST_CASE(puback_recv_no_pid_v311) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } // prepare connect { auto connect = am::v3_1_1::connect_packet{ @@ -1088,6 +1152,10 @@ BOOST_AUTO_TEST_CASE(puback_recv_no_pid_v5) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } // prepare connect { auto connect = am::v5::connect_packet{ @@ -1123,7 +1191,7 @@ BOOST_AUTO_TEST_CASE(puback_recv_no_pid_v5) { { auto [ec, disconnect] = co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); BOOST_TEST(ec == am::error_code{}); - BOOST_TEST(disconnect == exp); + BOOST_TEST(*disconnect == exp); } { auto [ec, _] = co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); @@ -1151,6 +1219,10 @@ BOOST_AUTO_TEST_CASE(pubrec_recv_no_pid_v311) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } // prepare connect { auto connect = am::v3_1_1::connect_packet{ @@ -1204,6 +1276,10 @@ BOOST_AUTO_TEST_CASE(pubrec_recv_no_pid_v5) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } // prepare connect { auto connect = am::v5::connect_packet{ @@ -1239,7 +1315,7 @@ BOOST_AUTO_TEST_CASE(pubrec_recv_no_pid_v5) { { auto [ec, disconnect] = co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); BOOST_TEST(ec == am::error_code{}); - BOOST_TEST(disconnect == exp); + BOOST_TEST(*disconnect == exp); } { auto [ec, _] = co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); @@ -1267,6 +1343,10 @@ BOOST_AUTO_TEST_CASE(pubcomp_recv_no_pid_v311) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } // prepare connect { auto connect = am::v3_1_1::connect_packet{ @@ -1320,6 +1400,10 @@ BOOST_AUTO_TEST_CASE(pubcomp_recv_no_pid_v5) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } // prepare connect { auto connect = am::v5::connect_packet{ @@ -1355,7 +1439,7 @@ BOOST_AUTO_TEST_CASE(pubcomp_recv_no_pid_v5) { { auto [ec, disconnect] = co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); BOOST_TEST(ec == am::error_code{}); - BOOST_TEST(disconnect == exp); + BOOST_TEST(*disconnect == exp); } { auto [ec, _] = co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); @@ -1385,6 +1469,10 @@ BOOST_AUTO_TEST_CASE(close_close) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } // prepare connect { auto connect = am::v5::connect_packet{ @@ -1434,6 +1522,10 @@ BOOST_AUTO_TEST_CASE(connect_bad_version_v5) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } // prepare connect { auto connect = am::v3_1_1::connect_packet{ @@ -1467,6 +1559,10 @@ BOOST_AUTO_TEST_CASE(connect_bad_timing_v5) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } // prepare connect { auto connect = am::v5::connect_packet{ @@ -1507,6 +1603,8 @@ BOOST_AUTO_TEST_CASE(connack_bad_version_v5) { version, am::force_move(exe) }; + // connection established as server + ep.underlying_accepted(); { auto connect = am::v5::connect_packet{ true, // clean_start @@ -1545,6 +1643,8 @@ BOOST_AUTO_TEST_CASE(connack_bad_timing_v5) { version, am::force_move(exe) }; + // connection established as server + ep.underlying_accepted(); // prepare connack { auto connack = am::v5::connack_packet{true, am::connect_reason_code::success}; @@ -1574,6 +1674,8 @@ BOOST_AUTO_TEST_CASE(auth_bad_version) { version, am::force_move(exe) }; + // connection established as server + ep.underlying_accepted(); { auto connect = am::v3_1_1::connect_packet{ true, // clean_session @@ -1614,6 +1716,10 @@ BOOST_AUTO_TEST_CASE(general_bad_version) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } // prepare connect { auto connect = am::v3_1_1::connect_packet{ @@ -1670,6 +1776,10 @@ BOOST_AUTO_TEST_CASE(pubrec_as_error_v5) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } // prepare connect { auto connect = am::v5::connect_packet{ @@ -1718,110 +1828,7 @@ BOOST_AUTO_TEST_CASE(pubrec_as_error_v5) { ioc.run(); } -// continuous recv - -BOOST_AUTO_TEST_CASE(publish_cont_recv_v5) { - auto version = am::protocol_version::v5; - as::io_context ioc; - as::co_spawn( - ioc.get_executor(), - [&]() -> as::awaitable { - auto exe = co_await as::this_coro::executor; - auto ep = am::endpoint{ - version, - // for stub_socket args - version, - am::force_move(exe) - }; - // prepare connect - { - auto connect = am::v5::connect_packet{ - true, // clean_start - 0, // keep_alive - "cid1" - }; - auto [ec] = co_await ep.async_send(connect, as::as_tuple(as::deferred)); - BOOST_TEST(!ec); - co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); - - auto connack = am::v5::connack_packet{ - false, // session_present - am::connect_reason_code::success - }; - co_await ep.next_layer().emulate_recv(connack, as::as_tuple(as::deferred)); - co_await ep.async_recv(as::as_tuple(as::deferred)); - } - // test scenario - { - auto publish1 = - am::v5::publish_packet{ - "topic1", - "payload1", - am::qos::at_most_once - }; - auto publish2 = - am::v5::publish_packet{ - "topic2", - "payload2", - am::qos::at_most_once - }; - auto publish3 = - am::v5::publish_packet{ - "topic3", - "payload3", - am::qos::at_most_once - }; - auto publish4 = - am::v5::publish_packet{ - "topic4", - "payload4", - am::qos::at_most_once - }; - auto publish5 = - am::v5::publish_packet{ - "topic5", - "payload5", - am::qos::at_most_once - }; - co_await ep.next_layer().emulate_recv(publish1, as::as_tuple(as::deferred)); - co_await ep.next_layer().emulate_recv(publish2, as::as_tuple(as::deferred)); - co_await ep.next_layer().emulate_recv(publish3, as::as_tuple(as::deferred)); - co_await ep.next_layer().emulate_recv(publish4, as::as_tuple(as::deferred)); - co_await ep.next_layer().emulate_recv(publish5, as::as_tuple(as::deferred)); - auto [ec1, pv1, t2, t3, t4, t5] = co_await ( - ep.async_recv(as::as_tuple(as::use_awaitable)) && - ep.async_recv(as::as_tuple(as::use_awaitable)) && - ep.async_recv(as::as_tuple(as::use_awaitable)) && - ep.async_recv(as::as_tuple(as::use_awaitable)) && - ep.async_recv(as::as_tuple(as::use_awaitable)) - ); - BOOST_TEST(ec1 == am::error_code{}); - BOOST_TEST(pv1 == publish1); - auto [ec2, pv2] = t2; - BOOST_TEST(ec2 == am::error_code{}); - BOOST_TEST(pv2 == publish2); - auto [ec3, pv3] = t3; - BOOST_TEST(ec3 == am::error_code{}); - BOOST_TEST(pv3 == publish3); - auto [ec4, pv4] = t4; - BOOST_TEST(ec4 == am::error_code{}); - BOOST_TEST(pv4 == publish4); - auto [ec5, pv5] = t5; - BOOST_TEST(ec5 == am::error_code{}); - BOOST_TEST(pv5 == publish5); - - co_await ep.async_close(as::deferred); - co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); - } - - co_return; - }, - as::detached - ); - ioc.run(); -} - -BOOST_AUTO_TEST_CASE(publish_cont_bulk_recv_v5) { +BOOST_AUTO_TEST_CASE(set_buffer_size_recv_chunked) { auto version = am::protocol_version::v5; as::io_context ioc; as::co_spawn( @@ -1834,109 +1841,11 @@ BOOST_AUTO_TEST_CASE(publish_cont_bulk_recv_v5) { version, am::force_move(exe) }; - ep.set_bulk_read_buffer_size(4096); - // prepare connect { - auto connect = am::v5::connect_packet{ - true, // clean_start - 0, // keep_alive - "cid1" - }; - auto [ec] = co_await ep.async_send(connect, as::as_tuple(as::deferred)); + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); BOOST_TEST(!ec); - co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); - - auto connack = am::v5::connack_packet{ - false, // session_present - am::connect_reason_code::success - }; - co_await ep.next_layer().emulate_recv(connack, as::as_tuple(as::deferred)); - co_await ep.async_recv(as::as_tuple(as::deferred)); } - // test scenario - { - auto publish1 = - am::v5::publish_packet{ - "topic1", - "payload1", - am::qos::at_most_once - }; - auto publish2 = - am::v5::publish_packet{ - "topic2", - "payload2", - am::qos::at_most_once - }; - auto publish3 = - am::v5::publish_packet{ - "topic3", - "payload3", - am::qos::at_most_once - }; - auto publish4 = - am::v5::publish_packet{ - "topic4", - "payload4", - am::qos::at_most_once - }; - auto publish5 = - am::v5::publish_packet{ - "topic5", - "payload5", - am::qos::at_most_once - }; - co_await ep.next_layer().emulate_recv(publish1, as::as_tuple(as::deferred)); - co_await ep.next_layer().emulate_recv(publish2, as::as_tuple(as::deferred)); - co_await ep.next_layer().emulate_recv(publish3, as::as_tuple(as::deferred)); - co_await ep.next_layer().emulate_recv(publish4, as::as_tuple(as::deferred)); - co_await ep.next_layer().emulate_recv(publish5, as::as_tuple(as::deferred)); - auto [ec1, pv1, t2, t3, t4, t5] = co_await ( - ep.async_recv(as::as_tuple(as::use_awaitable)) && - ep.async_recv(as::as_tuple(as::use_awaitable)) && - ep.async_recv(as::as_tuple(as::use_awaitable)) && - ep.async_recv(as::as_tuple(as::use_awaitable)) && - ep.async_recv(as::as_tuple(as::use_awaitable)) - ); - BOOST_TEST(ec1 == am::error_code{}); - BOOST_TEST(pv1 == publish1); - auto [ec2, pv2] = t2; - BOOST_TEST(ec2 == am::error_code{}); - BOOST_TEST(pv2 == publish2); - auto [ec3, pv3] = t3; - BOOST_TEST(ec3 == am::error_code{}); - BOOST_TEST(pv3 == publish3); - auto [ec4, pv4] = t4; - BOOST_TEST(ec4 == am::error_code{}); - BOOST_TEST(pv4 == publish4); - auto [ec5, pv5] = t5; - BOOST_TEST(ec5 == am::error_code{}); - BOOST_TEST(pv5 == publish5); - - co_await ep.async_close(as::deferred); - co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); - } - - co_return; - }, - as::detached - ); - ioc.run(); -} - -BOOST_AUTO_TEST_CASE(bulk_recv_chunked) { - auto version = am::protocol_version::v5; - as::io_context ioc; - as::co_spawn( - ioc.get_executor(), - [&]() -> as::awaitable { - auto exe = co_await as::this_coro::executor; - auto ep = am::endpoint{ - version, - // for stub_socket args - version, - am::force_move(exe) - }; - ep.set_bulk_read_buffer_size(4096); + ep.set_read_buffer_size(4096); // prepare connect { auto connect = am::v5::connect_packet{ @@ -1958,7 +1867,7 @@ BOOST_AUTO_TEST_CASE(bulk_recv_chunked) { // test scenario { co_await ep.next_layer().emulate_recv( - "\xe0\x80"sv, // invalid remaining length + "\xe0\x80\x80\x80\x80"sv, // invalid remaining length as::as_tuple(as::deferred) ); co_await ep.next_layer().emulate_recv( @@ -1966,7 +1875,7 @@ BOOST_AUTO_TEST_CASE(bulk_recv_chunked) { as::as_tuple(as::deferred) ); auto [ec, _] = co_await ep.async_recv(as::as_tuple(as::deferred)); - BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); + BOOST_TEST(ec == am::disconnect_reason_code::packet_too_large); co_await ep.async_close(as::deferred); co_await ep.next_layer().wait_response(as::as_tuple(as::deferred)); @@ -1979,7 +1888,7 @@ BOOST_AUTO_TEST_CASE(bulk_recv_chunked) { ioc.run(); } -BOOST_AUTO_TEST_CASE(bulk_recv_chunked_halfway_payload) { +BOOST_AUTO_TEST_CASE(bulk_set_buffer_size_recv_chunked_halfway_payload) { auto version = am::protocol_version::v5; as::io_context ioc; as::co_spawn( @@ -1992,7 +1901,11 @@ BOOST_AUTO_TEST_CASE(bulk_recv_chunked_halfway_payload) { version, am::force_move(exe) }; - ep.set_bulk_read_buffer_size(4096); + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } + ep.set_read_buffer_size(4096); // prepare connect { auto connect = am::v5::connect_packet{ @@ -2050,6 +1963,10 @@ BOOST_AUTO_TEST_CASE(bulk_write_close) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } ep.set_bulk_write(true); // prepare connect { @@ -2107,6 +2024,10 @@ BOOST_AUTO_TEST_CASE(write_close) { version, am::force_move(exe) }; + { + auto [ec] = co_await ep.async_underlying_handshake(as::as_tuple(as::deferred)); + BOOST_TEST(!ec); + } // test scenario { auto connect = am::v3_1_1::connect_packet{ diff --git a/test/unit/ut_ep_alloc.cpp b/test/unit/ut_ep_alloc.cpp index 44a372aa2..349e218be 100644 --- a/test/unit/ut_ep_alloc.cpp +++ b/test/unit/ut_ep_alloc.cpp @@ -40,13 +40,17 @@ struct my_alloc_read : std::allocator { T* allocate(std::size_t n, void const* hint = nullptr) { (void)hint; - if (n == check_digit_read) { + if (n == check_digit_read || + n == check_digit_read + sizeof(std::ptrdiff_t) // any_completion_handler + ) { allocate_called_read = true; } return base_type::allocate(n); } void deallocate(T* p, std::size_t n) { - if (n == check_digit_read) { + if (n == check_digit_read || + n == check_digit_read + sizeof(std::ptrdiff_t) // any_completion_handler + ) { deallocate_called_read = true; } return base_type::deallocate(p, n); @@ -87,18 +91,23 @@ BOOST_AUTO_TEST_CASE(custom_read) { my_alloc_read ma; BOOST_CHECK(!allocate_called_read); BOOST_CHECK(!deallocate_called_read); - ep.async_send( - connect, + ep.async_underlying_handshake( [&](auto ec) { BOOST_CHECK(!ec); - ep.async_recv( - as::bind_allocator( - ma, - [&](auto ec, auto pv) { - BOOST_TEST(!ec); - BOOST_TEST(pv == connack); - } - ) + ep.async_send( + connect, + [&](auto ec) { + BOOST_CHECK(!ec); + ep.async_recv( + as::bind_allocator( + ma, + [&](auto ec, auto pv) { + BOOST_TEST(!ec); + BOOST_TEST(*pv == connack); + } + ) + ); + } ); } ); @@ -170,20 +179,25 @@ BOOST_AUTO_TEST_CASE(custom_write) { my_alloc_write ma; BOOST_CHECK(!allocate_called_write); BOOST_CHECK(!deallocate_called_write); - ep.async_send( - connect, - as::bind_allocator( - ma, - [&](auto ec) { - BOOST_CHECK(!ec); - ep.async_recv( - [&](auto ec, auto pv) { - BOOST_TEST(!ec); - BOOST_TEST(pv == connack); + ep.async_underlying_handshake( + [&](auto ec) { + BOOST_CHECK(!ec); + ep.async_send( + connect, + as::bind_allocator( + ma, + [&](auto ec) { + BOOST_CHECK(!ec); + ep.async_recv( + [&](auto ec, auto pv) { + BOOST_TEST(!ec); + BOOST_TEST(*pv == connack); + } + ); } - ); - } - ) + ) + ); + } ); ioc.run(); BOOST_CHECK(allocate_called_write); diff --git a/test/unit/ut_ep_con_discon.cpp b/test/unit/ut_ep_con_discon.cpp index 2c0bd245b..9b9ba32a4 100644 --- a/test/unit/ut_ep_con_discon.cpp +++ b/test/unit/ut_ep_con_discon.cpp @@ -110,6 +110,12 @@ BOOST_AUTO_TEST_CASE(valid_client_v3_1_1) { } ); + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -125,7 +131,7 @@ BOOST_AUTO_TEST_CASE(valid_client_v3_1_1) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack == pv); + BOOST_TEST(connack == *pv); } // register packet_id for testing @@ -231,6 +237,12 @@ BOOST_AUTO_TEST_CASE(valid_client_v3_1_1) { BOOST_TEST(!pv); } + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -246,7 +258,7 @@ BOOST_AUTO_TEST_CASE(valid_client_v3_1_1) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack == pv); + BOOST_TEST(connack == *pv); } // send disconnect @@ -288,6 +300,8 @@ BOOST_AUTO_TEST_CASE(invalid_client_v3_1_1) { ioc.get_executor() }; + ep.set_offline_publish(true); + auto connect = am::v3_1_1::connect_packet{ true, // clean_session 0x1234, // keep_alive @@ -538,6 +552,12 @@ BOOST_AUTO_TEST_CASE(invalid_client_v3_1_1) { BOOST_TEST(ec == am::mqtt_error::packet_not_allowed_to_send); } + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -640,7 +660,7 @@ BOOST_AUTO_TEST_CASE(invalid_client_v3_1_1) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack == pv); + BOOST_TEST(connack == *pv); } // offline publish success @@ -811,11 +831,13 @@ BOOST_AUTO_TEST_CASE(valid_server_v3_1_1) { } ); + // connection established as server + ep1.underlying_accepted(); // recv connect { auto [ec, pv] = ep1.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connect == pv); + BOOST_TEST(connect == *pv); } // send connack @@ -930,11 +952,13 @@ BOOST_AUTO_TEST_CASE(valid_server_v3_1_1) { } ); + // connection established as server + ep2.underlying_accepted(); // recv connect { auto [ec, pv] = ep2.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connect == pv); + BOOST_TEST(connect == *pv); } // send connack @@ -991,6 +1015,8 @@ BOOST_AUTO_TEST_CASE(invalid_server_v3_1_1) { ioc.get_executor() }; + ep.set_offline_publish(true); + auto connect = am::v3_1_1::connect_packet{ true, // clean_session 0x1234, // keep_alive @@ -1241,11 +1267,13 @@ BOOST_AUTO_TEST_CASE(invalid_server_v3_1_1) { BOOST_TEST(ec == am::mqtt_error::packet_not_allowed_to_send); } + // connection established as server + ep.underlying_accepted(); // recv connect { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connect == pv); + BOOST_TEST(connect == *pv); } // offline publish success @@ -1534,6 +1562,12 @@ BOOST_AUTO_TEST_CASE(valid_client_v5) { } ); + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -1560,7 +1594,7 @@ BOOST_AUTO_TEST_CASE(valid_client_v5) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack == pv); + BOOST_TEST(connack == *pv); } // send valid packets @@ -1676,6 +1710,12 @@ BOOST_AUTO_TEST_CASE(valid_client_v5) { BOOST_TEST(!pv); } + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -1691,7 +1731,7 @@ BOOST_AUTO_TEST_CASE(valid_client_v5) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack == pv); + BOOST_TEST(connack == *pv); } // send disconnect @@ -1733,6 +1773,8 @@ BOOST_AUTO_TEST_CASE(invalid_client_v5) { ioc.get_executor() }; + ep.set_offline_publish(true); + auto connect = am::v5::connect_packet{ true, // clean_start 0x1234, // keep_alive @@ -2021,6 +2063,12 @@ BOOST_AUTO_TEST_CASE(invalid_client_v5) { BOOST_TEST(ec == am::mqtt_error::packet_not_allowed_to_send); } + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -2123,7 +2171,7 @@ BOOST_AUTO_TEST_CASE(invalid_client_v5) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack == pv); + BOOST_TEST(connack == *pv); } // offline publish success @@ -2322,11 +2370,13 @@ BOOST_AUTO_TEST_CASE(valid_server_v5) { } ); + // connection established as server + ep1.underlying_accepted(); // recv connect { auto [ec, pv] = ep1.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connect == pv); + BOOST_TEST(connect == *pv); } // send auth @@ -2462,11 +2512,13 @@ BOOST_AUTO_TEST_CASE(valid_server_v5) { } ); + // connection established as server + ep2.underlying_accepted(); // recv connect { auto [ec, pv] = ep2.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connect == pv); + BOOST_TEST(connect == *pv); } // send connack @@ -2523,6 +2575,8 @@ BOOST_AUTO_TEST_CASE(invalid_server_v5) { ioc.get_executor() }; + ep.set_offline_publish(true); + auto connect = am::v5::connect_packet{ true, // clean_start 0x1234, // keep_alive @@ -2621,8 +2675,6 @@ BOOST_AUTO_TEST_CASE(invalid_server_v5) { am::properties{} }; - auto close = am::packet_variant{}; - ep.next_layer().set_recv_packets( { // receive packets @@ -2813,11 +2865,13 @@ BOOST_AUTO_TEST_CASE(invalid_server_v5) { BOOST_TEST(ec == am::mqtt_error::packet_not_allowed_to_send); } + // connection established as server + ep.underlying_accepted(); // recv connect { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connect == pv); + BOOST_TEST(connect == *pv); } // offline publish success diff --git a/test/unit/ut_ep_keep_alive.cpp b/test/unit/ut_ep_keep_alive.cpp index fb065cd00..4b1988c21 100644 --- a/test/unit/ut_ep_keep_alive.cpp +++ b/test/unit/ut_ep_keep_alive.cpp @@ -67,6 +67,12 @@ BOOST_AUTO_TEST_CASE(server_keep_alive) { } ); + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -82,7 +88,7 @@ BOOST_AUTO_TEST_CASE(server_keep_alive) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack == pv); + BOOST_TEST(connack == *pv); } std::promise pro; diff --git a/test/unit/ut_ep_packet_error.cpp b/test/unit/ut_ep_packet_error.cpp index 44c6e9ab5..c1156b72e 100644 --- a/test/unit/ut_ep_packet_error.cpp +++ b/test/unit/ut_ep_packet_error.cpp @@ -56,6 +56,12 @@ BOOST_AUTO_TEST_CASE(v311_before_connected) { } ); + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -118,6 +124,12 @@ BOOST_AUTO_TEST_CASE(v5_before_connected) { } ); + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -187,6 +199,12 @@ BOOST_AUTO_TEST_CASE(v5_after_connected) { } ); + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -202,7 +220,7 @@ BOOST_AUTO_TEST_CASE(v5_after_connected) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack == pv); + BOOST_TEST(connack == *pv); } // set checker before malformed packet recv @@ -250,7 +268,8 @@ BOOST_AUTO_TEST_CASE(v5_server_connect) { version, ioc.get_executor() }; - + // connection established as server + ep.underlying_accepted(); ep.next_layer().set_recv_packets( { // receive packets diff --git a/test/unit/ut_ep_recv_filter.cpp b/test/unit/ut_ep_recv_filter.cpp index 01ba7d8f7..372dec2e2 100644 --- a/test/unit/ut_ep_recv_filter.cpp +++ b/test/unit/ut_ep_recv_filter.cpp @@ -63,6 +63,12 @@ BOOST_AUTO_TEST_CASE(recv_filter) { } ); + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -78,7 +84,7 @@ BOOST_AUTO_TEST_CASE(recv_filter) { { auto [ec, pv] = ep.async_recv(am::filter::match, {am::control_packet_type::connack}, as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack == pv); + BOOST_TEST(connack == *pv); } ep.async_close(as::as_tuple(as::use_future)).get(); diff --git a/test/unit/ut_ep_recv_max.cpp b/test/unit/ut_ep_recv_max.cpp index 722f32b93..2061adca9 100644 --- a/test/unit/ut_ep_recv_max.cpp +++ b/test/unit/ut_ep_recv_max.cpp @@ -62,6 +62,12 @@ BOOST_AUTO_TEST_CASE(client_send) { } ); + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -77,7 +83,7 @@ BOOST_AUTO_TEST_CASE(client_send) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack == pv); + BOOST_TEST(connack == *pv); } auto [ec1, pid1] = ep.async_acquire_unique_packet_id(as::as_tuple(as::use_future)).get(); @@ -212,7 +218,7 @@ BOOST_AUTO_TEST_CASE(client_send) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(puback2 == pv); + BOOST_TEST(puback2 == *pv); } f.get(); @@ -221,7 +227,7 @@ BOOST_AUTO_TEST_CASE(client_send) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(pubrec3 == pv); + BOOST_TEST(pubrec3 == *pv); } // send pubrel3 @@ -239,7 +245,7 @@ BOOST_AUTO_TEST_CASE(client_send) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(pubcomp3 == pv); + BOOST_TEST(pubcomp3 == *pv); } ep.async_close(as::as_tuple(as::use_future)).get(); guard.reset(); @@ -288,11 +294,13 @@ BOOST_AUTO_TEST_CASE(server_send) { } ); + // connection established as server + ep.underlying_accepted(); // recv connect { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connect == pv); + BOOST_TEST(connect == *pv); } // send connack @@ -438,7 +446,7 @@ BOOST_AUTO_TEST_CASE(server_send) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(puback2 == pv); + BOOST_TEST(puback2 == *pv); } f.get(); @@ -447,7 +455,7 @@ BOOST_AUTO_TEST_CASE(server_send) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(pubrec3 == pv); + BOOST_TEST(pubrec3 == *pv); } // send pubrel3 @@ -465,7 +473,7 @@ BOOST_AUTO_TEST_CASE(server_send) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(pubcomp3 == pv); + BOOST_TEST(pubcomp3 == *pv); } ep.async_close(as::as_tuple(as::use_future)).get(); guard.reset(); @@ -519,6 +527,12 @@ BOOST_AUTO_TEST_CASE(client_recv) { } ); + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -534,7 +548,7 @@ BOOST_AUTO_TEST_CASE(client_recv) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack == pv); + BOOST_TEST(connack == *pv); } auto publish_1_q1 = am::v5::publish_packet( @@ -616,19 +630,19 @@ BOOST_AUTO_TEST_CASE(client_recv) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_1_q1 == pv); + BOOST_TEST(publish_1_q1 == *pv); } // recv publish2 { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_2_q1 == pv); + BOOST_TEST(publish_2_q1 == *pv); } // recv publish3 { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_3_q0 == pv); + BOOST_TEST(publish_3_q0 == *pv); } bool close_called = false; @@ -664,6 +678,12 @@ BOOST_AUTO_TEST_CASE(client_recv) { } ); + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -679,7 +699,7 @@ BOOST_AUTO_TEST_CASE(client_recv) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack == pv); + BOOST_TEST(connack == *pv); } ep.next_layer().set_recv_packets( @@ -700,13 +720,13 @@ BOOST_AUTO_TEST_CASE(client_recv) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_1_q1 == pv); + BOOST_TEST(publish_1_q1 == *pv); } // recv publish4 { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_4_q2 == pv); + BOOST_TEST(publish_4_q2 == *pv); } // send puback2 ep.next_layer().set_write_packet_checker( @@ -732,7 +752,7 @@ BOOST_AUTO_TEST_CASE(client_recv) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(pubrel3 == pv); + BOOST_TEST(pubrel3 == *pv); } // send pubcomp3 ep.next_layer().set_write_packet_checker( @@ -748,19 +768,19 @@ BOOST_AUTO_TEST_CASE(client_recv) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_2_q1 == pv); + BOOST_TEST(publish_2_q1 == *pv); } // recv publish3 { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_3_q0 == pv); + BOOST_TEST(publish_3_q0 == *pv); } // recv publish5 { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_5_q1 == pv); + BOOST_TEST(publish_5_q1 == *pv); } close_called = false; @@ -839,11 +859,13 @@ BOOST_AUTO_TEST_CASE(server_recv) { } ); + // connection established as server + ep1.underlying_accepted(); // recv connect { auto [ec, pv] = ep1.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connect == pv); + BOOST_TEST(connect == *pv); } // send connack @@ -936,19 +958,19 @@ BOOST_AUTO_TEST_CASE(server_recv) { { auto [ec, pv] = ep1.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_1_q1 == pv); + BOOST_TEST(publish_1_q1 == *pv); } // recv publish2 { auto [ec, pv] = ep1.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_2_q1 == pv); + BOOST_TEST(publish_2_q1 == *pv); } // recv publish3 { auto [ec, pv] = ep1.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_3_q0 == pv); + BOOST_TEST(publish_3_q0 == *pv); } bool close_called = false; @@ -984,11 +1006,13 @@ BOOST_AUTO_TEST_CASE(server_recv) { } ); + // connection established as server + ep2.underlying_accepted(); // recv connect { auto [ec, pv] = ep2.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connect == pv); + BOOST_TEST(connect == *pv); } // send connack @@ -1020,13 +1044,13 @@ BOOST_AUTO_TEST_CASE(server_recv) { { auto [ec, pv] = ep2.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_1_q1 == pv); + BOOST_TEST(publish_1_q1 == *pv); } // recv publish4 { auto [ec, pv] = ep2.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_4_q2 == pv); + BOOST_TEST(publish_4_q2 == *pv); } // send puback2 ep2.next_layer().set_write_packet_checker( @@ -1052,7 +1076,7 @@ BOOST_AUTO_TEST_CASE(server_recv) { { auto [ec, pv] = ep2.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(pubrel3 == pv); + BOOST_TEST(pubrel3 == *pv); } // send pubcomp3 ep2.next_layer().set_write_packet_checker( @@ -1068,19 +1092,19 @@ BOOST_AUTO_TEST_CASE(server_recv) { { auto [ec, pv] = ep2.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_2_q1 == pv); + BOOST_TEST(publish_2_q1 == *pv); } // recv publish3 { auto [ec, pv] = ep2.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_3_q0 == pv); + BOOST_TEST(publish_3_q0 == *pv); } // recv publish5 { auto [ec, pv] = ep2.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_5_q1 == pv); + BOOST_TEST(publish_5_q1 == *pv); } close_called = false; diff --git a/test/unit/ut_ep_size_max.cpp b/test/unit/ut_ep_size_max.cpp index ab6c5d2ed..4d372cfbc 100644 --- a/test/unit/ut_ep_size_max.cpp +++ b/test/unit/ut_ep_size_max.cpp @@ -68,6 +68,12 @@ BOOST_AUTO_TEST_CASE(client_send) { } ); + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -83,7 +89,7 @@ BOOST_AUTO_TEST_CASE(client_send) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack == pv); + BOOST_TEST(connack == *pv); } // size: 21bytes @@ -184,6 +190,12 @@ BOOST_AUTO_TEST_CASE(client_send_no_store) { } ); + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -199,7 +211,7 @@ BOOST_AUTO_TEST_CASE(client_send_no_store) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack == pv); + BOOST_TEST(connack == *pv); } // size: 21bytes @@ -308,6 +320,12 @@ BOOST_AUTO_TEST_CASE(client_recv) { } ); + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -323,7 +341,7 @@ BOOST_AUTO_TEST_CASE(client_recv) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack == pv); + BOOST_TEST(connack == *pv); } // size: 21bytes @@ -360,7 +378,7 @@ BOOST_AUTO_TEST_CASE(client_recv) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_1_q1 == pv); + BOOST_TEST(publish_1_q1 == *pv); } // recv publish2 @@ -437,11 +455,13 @@ BOOST_AUTO_TEST_CASE(server_recv) { } ); + // connection established as server + ep.underlying_accepted(); // recv connect { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connect == pv); + BOOST_TEST(connect == *pv); } // send connack @@ -489,7 +509,7 @@ BOOST_AUTO_TEST_CASE(server_recv) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_1_q1 == pv); + BOOST_TEST(publish_1_q1 == *pv); } // recv publish2 @@ -563,11 +583,13 @@ BOOST_AUTO_TEST_CASE(server_send) { } ); + // connection established as server + ep.underlying_accepted(); // recv connect { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connect == pv); + BOOST_TEST(connect == *pv); } // send connack diff --git a/test/unit/ut_ep_store.cpp b/test/unit/ut_ep_store.cpp index 2cc86f34b..30310d2ba 100644 --- a/test/unit/ut_ep_store.cpp +++ b/test/unit/ut_ep_store.cpp @@ -65,6 +65,12 @@ BOOST_AUTO_TEST_CASE(v311_client) { } ); + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -80,7 +86,7 @@ BOOST_AUTO_TEST_CASE(v311_client) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack_sp_false == pv); + BOOST_TEST(connack_sp_false == *pv); } auto publish0 = am::v3_1_1::publish_packet( @@ -180,6 +186,12 @@ BOOST_AUTO_TEST_CASE(v311_client) { BOOST_TEST(ec == am::errc::connection_reset); } + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -214,7 +226,7 @@ BOOST_AUTO_TEST_CASE(v311_client) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack_sp_true == pv); + BOOST_TEST(connack_sp_true == *pv); } f.get(); BOOST_TEST(index == 2); @@ -223,7 +235,7 @@ BOOST_AUTO_TEST_CASE(v311_client) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(pubrec2 == pv); + BOOST_TEST(pubrec2 == *pv); } // send pubrel2 @@ -254,6 +266,12 @@ BOOST_AUTO_TEST_CASE(v311_client) { BOOST_TEST(ec == am::errc::connection_reset); } + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -291,7 +309,7 @@ BOOST_AUTO_TEST_CASE(v311_client) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack_sp_true == pv); + BOOST_TEST(connack_sp_true == *pv); } f.get(); BOOST_TEST(index == 3); @@ -302,6 +320,11 @@ BOOST_AUTO_TEST_CASE(v311_client) { BOOST_TEST(ec == am::errc::connection_reset); } + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -323,7 +346,7 @@ BOOST_AUTO_TEST_CASE(v311_client) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack_sp_false == pv); + BOOST_TEST(connack_sp_false == *pv); } ep.async_close(as::as_tuple(as::use_future)).get(); guard.reset(); @@ -400,11 +423,13 @@ BOOST_AUTO_TEST_CASE(v311_server) { } ); + // connection established as server + ep1.underlying_accepted(); // recv connect_no_clean { auto [ec, pv] = ep1.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connect_no_clean == pv); + BOOST_TEST(connect_no_clean == *pv); } // send connack_sp_false @@ -530,11 +555,13 @@ BOOST_AUTO_TEST_CASE(v311_server) { BOOST_TEST(ec == am::errc::connection_reset); } + // connection established as server + ep2.underlying_accepted(); // recv connect_no_clean { auto [ec, pv] = ep2.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connect_no_clean == pv); + BOOST_TEST(connect_no_clean == *pv); } // get_stored and restore next endpoint @@ -583,7 +610,7 @@ BOOST_AUTO_TEST_CASE(v311_server) { { auto [ec, pv] = ep2.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(pubrec2 == pv); + BOOST_TEST(pubrec2 == *pv); } // send pubrel2 @@ -614,11 +641,13 @@ BOOST_AUTO_TEST_CASE(v311_server) { BOOST_TEST(ec == am::errc::connection_reset); } + // connection established as server + ep3.underlying_accepted(); // recv connect_no_clean { auto [ec, pv] = ep3.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connect_no_clean == pv); + BOOST_TEST(connect_no_clean == *pv); } // get_stored and restore next endpoint @@ -672,11 +701,13 @@ BOOST_AUTO_TEST_CASE(v311_server) { BOOST_TEST(ec == am::errc::connection_reset); } + // connection established as server + ep4.underlying_accepted(); // recv connect_clean { auto [ec, pv] = ep4.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connect_clean == pv); + BOOST_TEST(connect_clean == *pv); } // no restore because clean_session is true @@ -762,6 +793,12 @@ BOOST_AUTO_TEST_CASE(v5_client) { } ); + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -777,7 +814,7 @@ BOOST_AUTO_TEST_CASE(v5_client) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack_sp_false == pv); + BOOST_TEST(connack_sp_false == *pv); } auto publish0 = am::v5::publish_packet( @@ -880,6 +917,12 @@ BOOST_AUTO_TEST_CASE(v5_client) { BOOST_TEST(ec == am::errc::connection_reset); } + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -914,7 +957,7 @@ BOOST_AUTO_TEST_CASE(v5_client) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack_sp_true == pv); + BOOST_TEST(connack_sp_true == *pv); } f.get(); BOOST_TEST(index == 2); @@ -923,7 +966,7 @@ BOOST_AUTO_TEST_CASE(v5_client) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(pubrec2 == pv); + BOOST_TEST(pubrec2 == *pv); } // send pubrel2 @@ -954,6 +997,12 @@ BOOST_AUTO_TEST_CASE(v5_client) { BOOST_TEST(ec == am::errc::connection_reset); } + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -991,7 +1040,7 @@ BOOST_AUTO_TEST_CASE(v5_client) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack_sp_true == pv); + BOOST_TEST(connack_sp_true == *pv); } f.get(); BOOST_TEST(index == 3); @@ -1002,6 +1051,12 @@ BOOST_AUTO_TEST_CASE(v5_client) { BOOST_TEST(ec == am::errc::connection_reset); } + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -1023,7 +1078,7 @@ BOOST_AUTO_TEST_CASE(v5_client) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack_sp_false == pv); + BOOST_TEST(connack_sp_false == *pv); } ep.async_close(as::as_tuple(as::use_future)).get(); guard.reset(); @@ -1106,11 +1161,13 @@ BOOST_AUTO_TEST_CASE(v5_server) { } ); + // connection established as server + ep1.underlying_accepted(); // recv connect_no_clean { auto [ec, pv] = ep1.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connect_no_clean == pv); + BOOST_TEST(connect_no_clean == *pv); } // send connack_sp_false @@ -1239,11 +1296,13 @@ BOOST_AUTO_TEST_CASE(v5_server) { BOOST_TEST(ec == am::errc::connection_reset); } + // connection established as server + ep2.underlying_accepted(); // recv connect_no_clean { auto [ec, pv] = ep2.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connect_no_clean == pv); + BOOST_TEST(connect_no_clean == *pv); } // get_stored and restore next endpoint @@ -1293,7 +1352,7 @@ BOOST_AUTO_TEST_CASE(v5_server) { { auto [ec, pv] = ep2.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(pubrec2 == pv); + BOOST_TEST(pubrec2 == *pv); } // send pubrel2 @@ -1324,10 +1383,12 @@ BOOST_AUTO_TEST_CASE(v5_server) { BOOST_TEST(ec == am::errc::connection_reset); } + // connection established as server + ep3.underlying_accepted(); // recv connect_no_clean { auto [ec, pv] = ep3.async_recv(as::as_tuple(as::use_future)).get(); - BOOST_TEST(connect_no_clean == pv); + BOOST_TEST(connect_no_clean == *pv); } // get_stored and restore next endpoint @@ -1381,11 +1442,13 @@ BOOST_AUTO_TEST_CASE(v5_server) { BOOST_TEST(ec == am::errc::connection_reset); } + // connection established as server + ep4.underlying_accepted(); // recv connect_clean { auto [ec, pv] = ep4.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connect_clean == pv); + BOOST_TEST(connect_clean == *pv); } // no restore because clean_session is true @@ -1473,6 +1536,12 @@ BOOST_AUTO_TEST_CASE(v5_topic_alias) { } ); + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -1488,7 +1557,7 @@ BOOST_AUTO_TEST_CASE(v5_topic_alias) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack_sp_false == pv); + BOOST_TEST(connack_sp_false == *pv); } auto publish0 = am::v5::publish_packet( @@ -1611,6 +1680,12 @@ BOOST_AUTO_TEST_CASE(v5_topic_alias) { BOOST_TEST(ec == am::errc::connection_reset); } + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -1645,7 +1720,7 @@ BOOST_AUTO_TEST_CASE(v5_topic_alias) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack_sp_true == pv); + BOOST_TEST(connack_sp_true == *pv); } f.get(); BOOST_TEST(index == 2); @@ -1654,7 +1729,7 @@ BOOST_AUTO_TEST_CASE(v5_topic_alias) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(pubrec2 == pv); + BOOST_TEST(pubrec2 == *pv); } // send pubrel2 @@ -1685,6 +1760,12 @@ BOOST_AUTO_TEST_CASE(v5_topic_alias) { BOOST_TEST(ec == am::errc::connection_reset); } + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -1722,7 +1803,7 @@ BOOST_AUTO_TEST_CASE(v5_topic_alias) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack_sp_true == pv); + BOOST_TEST(connack_sp_true == *pv); } f.get(); BOOST_TEST(index == 3); @@ -1733,6 +1814,12 @@ BOOST_AUTO_TEST_CASE(v5_topic_alias) { BOOST_TEST(ec == am::errc::connection_reset); } + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -1754,7 +1841,7 @@ BOOST_AUTO_TEST_CASE(v5_topic_alias) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack_sp_false == pv); + BOOST_TEST(connack_sp_false == *pv); } ep.async_close(as::as_tuple(as::use_future)).get(); guard.reset(); diff --git a/test/unit/ut_ep_topic_alias.cpp b/test/unit/ut_ep_topic_alias.cpp index 7200e4ce5..75e96b2d4 100644 --- a/test/unit/ut_ep_topic_alias.cpp +++ b/test/unit/ut_ep_topic_alias.cpp @@ -80,6 +80,12 @@ BOOST_AUTO_TEST_CASE(send_client) { } ); + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -95,7 +101,7 @@ BOOST_AUTO_TEST_CASE(send_client) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack == pv); + BOOST_TEST(connack == *pv); } auto [ec1, pid1] = ep.async_acquire_unique_packet_id(as::as_tuple(as::use_future)).get(); @@ -388,11 +394,13 @@ BOOST_AUTO_TEST_CASE(send_server) { } ); + // connection established as server + ep.underlying_accepted(); // recv connect { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connect == pv); + BOOST_TEST(connect == *pv); } // send connack @@ -623,6 +631,12 @@ BOOST_AUTO_TEST_CASE(send_auto_map) { ep.set_auto_map_topic_alias_send(true); + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -638,7 +652,7 @@ BOOST_AUTO_TEST_CASE(send_auto_map) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack == pv); + BOOST_TEST(connack == *pv); } auto [ec1, pid1] = ep.async_acquire_unique_packet_id(as::as_tuple(as::use_future)).get(); @@ -849,6 +863,12 @@ BOOST_AUTO_TEST_CASE(send_auto_replace) { ep.set_auto_replace_topic_alias_send(true); + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -865,7 +885,7 @@ BOOST_AUTO_TEST_CASE(send_auto_replace) { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack == pv); + BOOST_TEST(connack == *pv); } auto [ec1, pid1] = ep.async_acquire_unique_packet_id(as::as_tuple(as::use_future)).get(); @@ -1025,6 +1045,12 @@ BOOST_AUTO_TEST_CASE(recv_client) { auto init = [&] { + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -1041,7 +1067,7 @@ BOOST_AUTO_TEST_CASE(recv_client) { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack == pv); + BOOST_TEST(connack == *pv); } }; @@ -1202,7 +1228,7 @@ BOOST_AUTO_TEST_CASE(recv_client) { {publish_reg_t2}, {publish_use_ta2}, {publish_reg_t3}, // error and disconnect - {am::errc::make_error_code(am::errc::connection_reset)}, + {connack}, {publish_use_ta3}, // error and disconnect {am::errc::make_error_code(am::errc::connection_reset)}, @@ -1218,7 +1244,7 @@ BOOST_AUTO_TEST_CASE(recv_client) { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_reg_t1 == pv); + BOOST_TEST(publish_reg_t1 == *pv); } // recv publish_use_ta1 @@ -1226,7 +1252,7 @@ BOOST_AUTO_TEST_CASE(recv_client) { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_exp_t1 == pv); + BOOST_TEST(publish_exp_t1 == *pv); } // recv publish_reg_t2 @@ -1234,7 +1260,7 @@ BOOST_AUTO_TEST_CASE(recv_client) { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_reg_t2 == pv); + BOOST_TEST(publish_reg_t2 == *pv); } // recv publish_use_ta2 @@ -1242,7 +1268,7 @@ BOOST_AUTO_TEST_CASE(recv_client) { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_exp_t2 == pv); + BOOST_TEST(publish_exp_t2 == *pv); } @@ -1260,18 +1286,11 @@ BOOST_AUTO_TEST_CASE(recv_client) { // recv publish_reg_t3 (invalid) { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); - BOOST_TEST(pv.get_if() != nullptr); + BOOST_TEST(!pv); BOOST_TEST(ec == am::disconnect_reason_code::topic_alias_invalid); } BOOST_TEST(close_called); - // recv close - { - auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); - BOOST_TEST(pv.get_if() != nullptr); - BOOST_TEST(ec == am::errc::connection_reset); - } - init(); close_called = false; @@ -1288,7 +1307,7 @@ BOOST_AUTO_TEST_CASE(recv_client) { // recv publish_use_ta3 { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); - BOOST_TEST(pv.get_if() != nullptr); + BOOST_TEST(!pv); BOOST_TEST(ec == am::disconnect_reason_code::topic_alias_invalid); } BOOST_TEST(close_called); @@ -1296,7 +1315,7 @@ BOOST_AUTO_TEST_CASE(recv_client) { // recv close { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); - BOOST_TEST(pv.get_if() != nullptr); + BOOST_TEST(!pv); BOOST_TEST(ec == am::errc::connection_reset); } @@ -1306,21 +1325,21 @@ BOOST_AUTO_TEST_CASE(recv_client) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_reg_t1_again == pv); + BOOST_TEST(publish_reg_t1_again == *pv); } // recv publish_upd_t3 { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_upd_t3 == pv); + BOOST_TEST(publish_upd_t3 == *pv); } // recv publish_use_ta1 { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_exp_t3 == pv); + BOOST_TEST(publish_exp_t3 == *pv); } ep.async_close(as::as_tuple(as::use_future)).get(); guard.reset(); @@ -1377,11 +1396,13 @@ BOOST_AUTO_TEST_CASE(recv_server) { auto init = [&] { + // connection established as server + ep.underlying_accepted(); // recv connect { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connect == pv); + BOOST_TEST(connect == *pv); } // send connack @@ -1555,28 +1576,28 @@ BOOST_AUTO_TEST_CASE(recv_server) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_reg_t1 == pv); + BOOST_TEST(publish_reg_t1 == *pv); } // recv publish_use_ta1 { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_exp_t1 == pv); + BOOST_TEST(publish_exp_t1 == *pv); } // recv publish_reg_t2 { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_reg_t2 == pv); + BOOST_TEST(publish_reg_t2 == *pv); } // recv publish_use_ta2 { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_exp_t2 == pv); + BOOST_TEST(publish_exp_t2 == *pv); } bool close_called = false; @@ -1593,14 +1614,14 @@ BOOST_AUTO_TEST_CASE(recv_server) { // recv publish_reg_t3 (invalid) { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); - BOOST_TEST(pv.get_if() != nullptr); + BOOST_TEST(!pv); BOOST_TEST(ec == am::disconnect_reason_code::topic_alias_invalid); } BOOST_TEST(close_called); // recv close { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); - BOOST_TEST(pv.get_if() != nullptr); + BOOST_TEST(!pv); BOOST_TEST(ec == am::errc::connection_reset); } @@ -1619,14 +1640,14 @@ BOOST_AUTO_TEST_CASE(recv_server) { // recv publish_use_ta3 { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); - BOOST_TEST(pv.get_if() != nullptr); + BOOST_TEST(!pv); BOOST_TEST(ec == am::disconnect_reason_code::topic_alias_invalid); } BOOST_TEST(close_called); // recv close { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); - BOOST_TEST(pv.get_if() != nullptr); + BOOST_TEST(!pv); BOOST_TEST(ec == am::errc::connection_reset); } @@ -1635,14 +1656,14 @@ BOOST_AUTO_TEST_CASE(recv_server) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_upd_t3 == pv); + BOOST_TEST(publish_upd_t3 == *pv); } // recv publish_use_ta1 { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(publish_exp_t3 == pv); + BOOST_TEST(publish_exp_t3 == *pv); } ep.async_close(as::as_tuple(as::use_future)).get(); @@ -1690,6 +1711,12 @@ BOOST_AUTO_TEST_CASE(send_error) { } ); + // underlying handshake + { + auto [ec] = ep.async_underlying_handshake(as::as_tuple(as::use_future)).get(); + BOOST_TEST(!ec); + } + // send connect ep.next_layer().set_write_packet_checker( [&](am::packet_variant wp) { @@ -1705,7 +1732,7 @@ BOOST_AUTO_TEST_CASE(send_error) { { auto [ec, pv] = ep.async_recv(as::as_tuple(as::use_future)).get(); BOOST_TEST(!ec); - BOOST_TEST(connack == pv); + BOOST_TEST(connack == *pv); } { diff --git a/test/unit/ut_error.cpp b/test/unit/ut_error.cpp index 8fb528bb7..0a4825a60 100644 --- a/test/unit/ut_error.cpp +++ b/test/unit/ut_error.cpp @@ -9,7 +9,7 @@ #include -#include +#include BOOST_AUTO_TEST_SUITE(ut_error) diff --git a/test/unit/ut_packet_id.cpp b/test/unit/ut_packet_id.cpp index 55f58d913..32370ee4b 100644 --- a/test/unit/ut_packet_id.cpp +++ b/test/unit/ut_packet_id.cpp @@ -9,8 +9,8 @@ #include -#include -#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet_id) diff --git a/test/unit/ut_packet_v3_1_1_connack.cpp b/test/unit/ut_packet_v3_1_1_connack.cpp index a0c5010e2..dec4d9eef 100644 --- a/test/unit/ut_packet_v3_1_1_connack.cpp +++ b/test/unit/ut_packet_v3_1_1_connack.cpp @@ -16,9 +16,9 @@ struct v311_connack; struct v311_connack_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v3_1_1_connect.cpp b/test/unit/ut_packet_v3_1_1_connect.cpp index b15293f2c..acba11066 100644 --- a/test/unit/ut_packet_v3_1_1_connect.cpp +++ b/test/unit/ut_packet_v3_1_1_connect.cpp @@ -16,9 +16,9 @@ struct v311_connect; struct v311_connect_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v3_1_1_disconnect.cpp b/test/unit/ut_packet_v3_1_1_disconnect.cpp index fe4db9073..564d8927f 100644 --- a/test/unit/ut_packet_v3_1_1_disconnect.cpp +++ b/test/unit/ut_packet_v3_1_1_disconnect.cpp @@ -16,9 +16,9 @@ struct v311_disconnect; struct v311_disconnect_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v3_1_1_pingreq.cpp b/test/unit/ut_packet_v3_1_1_pingreq.cpp index 8dacd095e..67708ccfe 100644 --- a/test/unit/ut_packet_v3_1_1_pingreq.cpp +++ b/test/unit/ut_packet_v3_1_1_pingreq.cpp @@ -16,9 +16,9 @@ struct v311_pingreq; struct v311_pingreq_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v3_1_1_pingresp.cpp b/test/unit/ut_packet_v3_1_1_pingresp.cpp index 16d8db6ab..6fb402736 100644 --- a/test/unit/ut_packet_v3_1_1_pingresp.cpp +++ b/test/unit/ut_packet_v3_1_1_pingresp.cpp @@ -16,9 +16,9 @@ struct v311_pingresp; struct v311_pingresp_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v3_1_1_puback.cpp b/test/unit/ut_packet_v3_1_1_puback.cpp index e496b4893..b2d39b68c 100644 --- a/test/unit/ut_packet_v3_1_1_puback.cpp +++ b/test/unit/ut_packet_v3_1_1_puback.cpp @@ -18,9 +18,9 @@ struct v311_puback_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v3_1_1_pubcomp.cpp b/test/unit/ut_packet_v3_1_1_pubcomp.cpp index 265afda30..fa8fee890 100644 --- a/test/unit/ut_packet_v3_1_1_pubcomp.cpp +++ b/test/unit/ut_packet_v3_1_1_pubcomp.cpp @@ -17,9 +17,9 @@ struct v311_pubcomp_pid4; struct v311_pubcomp_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v3_1_1_publish.cpp b/test/unit/ut_packet_v3_1_1_publish.cpp index 4c928b32c..5f7825d9e 100644 --- a/test/unit/ut_packet_v3_1_1_publish.cpp +++ b/test/unit/ut_packet_v3_1_1_publish.cpp @@ -19,9 +19,9 @@ struct v311_publish_pid4; struct v311_publish_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v3_1_1_pubrec.cpp b/test/unit/ut_packet_v3_1_1_pubrec.cpp index e6e3f86f2..e9696af4e 100644 --- a/test/unit/ut_packet_v3_1_1_pubrec.cpp +++ b/test/unit/ut_packet_v3_1_1_pubrec.cpp @@ -17,9 +17,9 @@ struct v311_pubrec_pid4; struct v311_pubrec_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v3_1_1_pubrel.cpp b/test/unit/ut_packet_v3_1_1_pubrel.cpp index 63f56d608..0426c9d54 100644 --- a/test/unit/ut_packet_v3_1_1_pubrel.cpp +++ b/test/unit/ut_packet_v3_1_1_pubrel.cpp @@ -17,9 +17,9 @@ struct v311_pubrel_pid4; struct v311_pubrel_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v3_1_1_suback.cpp b/test/unit/ut_packet_v3_1_1_suback.cpp index 4c980d611..c10ae6ecf 100644 --- a/test/unit/ut_packet_v3_1_1_suback.cpp +++ b/test/unit/ut_packet_v3_1_1_suback.cpp @@ -17,9 +17,9 @@ struct v311_suback_pid4; struct v311_suback_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v3_1_1_subscribe.cpp b/test/unit/ut_packet_v3_1_1_subscribe.cpp index 3c2e8df3e..582ef8e87 100644 --- a/test/unit/ut_packet_v3_1_1_subscribe.cpp +++ b/test/unit/ut_packet_v3_1_1_subscribe.cpp @@ -17,9 +17,9 @@ struct v311_subscribe_pid4; struct v311_subscribe_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v3_1_1_unsuback.cpp b/test/unit/ut_packet_v3_1_1_unsuback.cpp index f9428d9b4..1cf0fc0a2 100644 --- a/test/unit/ut_packet_v3_1_1_unsuback.cpp +++ b/test/unit/ut_packet_v3_1_1_unsuback.cpp @@ -17,9 +17,9 @@ struct v311_unsuback_pid4; struct v311_unsuback_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v3_1_1_unsubscribe.cpp b/test/unit/ut_packet_v3_1_1_unsubscribe.cpp index 906ba99d6..f64454bff 100644 --- a/test/unit/ut_packet_v3_1_1_unsubscribe.cpp +++ b/test/unit/ut_packet_v3_1_1_unsubscribe.cpp @@ -17,9 +17,9 @@ struct v311_unsubscribe_pid4; struct v311_unsubscribe_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v5_auth.cpp b/test/unit/ut_packet_v5_auth.cpp index a3bf2ad9e..71b3a387d 100644 --- a/test/unit/ut_packet_v5_auth.cpp +++ b/test/unit/ut_packet_v5_auth.cpp @@ -19,9 +19,9 @@ struct v5_auth_prop_len_last; struct v5_auth_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v5_connack.cpp b/test/unit/ut_packet_v5_connack.cpp index 2ec21dccc..629800fb2 100644 --- a/test/unit/ut_packet_v5_connack.cpp +++ b/test/unit/ut_packet_v5_connack.cpp @@ -16,9 +16,9 @@ struct v5_connack; struct v5_connack_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v5_connect.cpp b/test/unit/ut_packet_v5_connect.cpp index 61c3d7689..26fc82bcd 100644 --- a/test/unit/ut_packet_v5_connect.cpp +++ b/test/unit/ut_packet_v5_connect.cpp @@ -16,9 +16,9 @@ struct v5_connect; struct v5_connect_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v5_disconnect.cpp b/test/unit/ut_packet_v5_disconnect.cpp index 7b7876210..fbe90eb8f 100644 --- a/test/unit/ut_packet_v5_disconnect.cpp +++ b/test/unit/ut_packet_v5_disconnect.cpp @@ -19,9 +19,9 @@ struct v5_disconnect_prop_len_last; struct v5_disconnect_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v5_pingreq.cpp b/test/unit/ut_packet_v5_pingreq.cpp index ad03e86a7..b8a3e371a 100644 --- a/test/unit/ut_packet_v5_pingreq.cpp +++ b/test/unit/ut_packet_v5_pingreq.cpp @@ -16,9 +16,9 @@ struct v5_pingreq; struct v5_pingreq_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v5_pingresp.cpp b/test/unit/ut_packet_v5_pingresp.cpp index 3583de8fe..bbb8bcbbe 100644 --- a/test/unit/ut_packet_v5_pingresp.cpp +++ b/test/unit/ut_packet_v5_pingresp.cpp @@ -16,9 +16,9 @@ struct v5_pingresp; struct v5_pingresp_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v5_puback.cpp b/test/unit/ut_packet_v5_puback.cpp index ce9dbf48e..c17e34616 100644 --- a/test/unit/ut_packet_v5_puback.cpp +++ b/test/unit/ut_packet_v5_puback.cpp @@ -20,9 +20,9 @@ struct v5_puback_prop_len_last; struct v5_puback_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v5_pubcomp.cpp b/test/unit/ut_packet_v5_pubcomp.cpp index 1ea1aed88..3722a7e77 100644 --- a/test/unit/ut_packet_v5_pubcomp.cpp +++ b/test/unit/ut_packet_v5_pubcomp.cpp @@ -20,9 +20,9 @@ struct v5_pubcomp_prop_len_last; struct v5_pubcomp_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v5_publish.cpp b/test/unit/ut_packet_v5_publish.cpp index f9d7f28c8..79c91bbdc 100644 --- a/test/unit/ut_packet_v5_publish.cpp +++ b/test/unit/ut_packet_v5_publish.cpp @@ -20,9 +20,9 @@ struct v5_publish_topic_alias; struct v5_publish_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v5_pubrec.cpp b/test/unit/ut_packet_v5_pubrec.cpp index e46b99e42..c4f1bf00e 100644 --- a/test/unit/ut_packet_v5_pubrec.cpp +++ b/test/unit/ut_packet_v5_pubrec.cpp @@ -20,9 +20,9 @@ struct v5_pubrec_prop_len_last; struct v5_pubrec_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v5_pubrel.cpp b/test/unit/ut_packet_v5_pubrel.cpp index 4112c26c1..72f644f1b 100644 --- a/test/unit/ut_packet_v5_pubrel.cpp +++ b/test/unit/ut_packet_v5_pubrel.cpp @@ -20,9 +20,9 @@ struct v5_pubrel_prop_len_last; struct v5_pubrel_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v5_suback.cpp b/test/unit/ut_packet_v5_suback.cpp index 19c4a1c16..568b1d1c1 100644 --- a/test/unit/ut_packet_v5_suback.cpp +++ b/test/unit/ut_packet_v5_suback.cpp @@ -17,9 +17,9 @@ struct v5_suback_pid4; struct v5_suback_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v5_subscribe.cpp b/test/unit/ut_packet_v5_subscribe.cpp index 1f2bb97e1..c21cb72cf 100644 --- a/test/unit/ut_packet_v5_subscribe.cpp +++ b/test/unit/ut_packet_v5_subscribe.cpp @@ -17,9 +17,9 @@ struct v5_subscribe_pid4; struct v5_subscribe_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v5_unsuback.cpp b/test/unit/ut_packet_v5_unsuback.cpp index 10c9053dd..b8f3e9d91 100644 --- a/test/unit/ut_packet_v5_unsuback.cpp +++ b/test/unit/ut_packet_v5_unsuback.cpp @@ -17,9 +17,9 @@ struct v5_unsuback_pid4; struct v5_unsuback_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_v5_unsubscribe.cpp b/test/unit/ut_packet_v5_unsubscribe.cpp index 5bf6293a7..c55c8c357 100644 --- a/test/unit/ut_packet_v5_unsubscribe.cpp +++ b/test/unit/ut_packet_v5_unsubscribe.cpp @@ -17,9 +17,9 @@ struct v5_unsubscribe_pid4; struct v5_unsubscribe_error; BOOST_AUTO_TEST_SUITE_END() -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_packet) diff --git a/test/unit/ut_packet_variant.cpp b/test/unit/ut_packet_variant.cpp index e35ba16a6..6ed1a6bb4 100644 --- a/test/unit/ut_packet_variant.cpp +++ b/test/unit/ut_packet_variant.cpp @@ -10,19 +10,12 @@ #include -#include +#include BOOST_AUTO_TEST_SUITE(ut_packet_variant) namespace am = async_mqtt; -BOOST_AUTO_TEST_CASE( monostate ) { - am::packet_variant v; - BOOST_CHECK(!v.type()); - BOOST_CHECK(v.const_buffer_sequence().empty()); - BOOST_TEST(boost::lexical_cast(v) == ""); -} - BOOST_AUTO_TEST_CASE( stringize ) { am::packet_variant v{am::v3_1_1::pingreq_packet{}}; BOOST_TEST(boost::lexical_cast(v) == "v3_1_1::pingreq{}"); diff --git a/test/unit/ut_prop_variant.cpp b/test/unit/ut_prop_variant.cpp index e20715f31..f5db3304f 100644 --- a/test/unit/ut_prop_variant.cpp +++ b/test/unit/ut_prop_variant.cpp @@ -10,8 +10,8 @@ #include #include -#include -#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_prop_variant) @@ -38,17 +38,13 @@ BOOST_AUTO_TEST_CASE(payload_format_indicator) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(!ec); } @@ -56,97 +52,73 @@ BOOST_AUTO_TEST_CASE(payload_format_indicator) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -170,17 +142,13 @@ BOOST_AUTO_TEST_CASE(message_expiry_interval) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(!ec); } @@ -188,97 +156,73 @@ BOOST_AUTO_TEST_CASE(message_expiry_interval) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -302,17 +246,13 @@ BOOST_AUTO_TEST_CASE(content_type) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(!ec); } @@ -320,97 +260,73 @@ BOOST_AUTO_TEST_CASE(content_type) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -434,17 +350,13 @@ BOOST_AUTO_TEST_CASE(response_topic) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(!ec); } @@ -452,97 +364,73 @@ BOOST_AUTO_TEST_CASE(response_topic) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -566,17 +454,13 @@ BOOST_AUTO_TEST_CASE(correlation_data) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(!ec); } @@ -584,97 +468,73 @@ BOOST_AUTO_TEST_CASE(correlation_data) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -698,17 +558,13 @@ BOOST_AUTO_TEST_CASE(subscription_identifier) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(!ec); } @@ -716,97 +572,73 @@ BOOST_AUTO_TEST_CASE(subscription_identifier) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -830,25 +662,19 @@ BOOST_AUTO_TEST_CASE(session_expiry_interval) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(!ec); } @@ -856,89 +682,67 @@ BOOST_AUTO_TEST_CASE(session_expiry_interval) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -962,9 +766,7 @@ BOOST_AUTO_TEST_CASE(assigned_client_identifier) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(!ec); } @@ -972,105 +774,79 @@ BOOST_AUTO_TEST_CASE(assigned_client_identifier) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -1094,9 +870,7 @@ BOOST_AUTO_TEST_CASE(server_keep_alive) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(!ec); } @@ -1104,105 +878,79 @@ BOOST_AUTO_TEST_CASE(server_keep_alive) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -1226,25 +974,19 @@ BOOST_AUTO_TEST_CASE(authentication_method) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(!ec); } @@ -1252,89 +994,67 @@ BOOST_AUTO_TEST_CASE(authentication_method) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -1358,25 +1078,19 @@ BOOST_AUTO_TEST_CASE(authentication_data) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(!ec); } @@ -1384,89 +1098,67 @@ BOOST_AUTO_TEST_CASE(authentication_data) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -1490,9 +1182,7 @@ BOOST_AUTO_TEST_CASE(request_problem_information) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(!ec); } @@ -1500,105 +1190,79 @@ BOOST_AUTO_TEST_CASE(request_problem_information) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -1622,9 +1286,7 @@ BOOST_AUTO_TEST_CASE(will_delay_interval) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(!ec); } @@ -1632,105 +1294,79 @@ BOOST_AUTO_TEST_CASE(will_delay_interval) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -1754,9 +1390,7 @@ BOOST_AUTO_TEST_CASE(request_response_information) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(!ec); } @@ -1764,105 +1398,79 @@ BOOST_AUTO_TEST_CASE(request_response_information) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -1886,9 +1494,7 @@ BOOST_AUTO_TEST_CASE(response_information) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(!ec); } @@ -1896,105 +1502,79 @@ BOOST_AUTO_TEST_CASE(response_information) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -2018,17 +1598,13 @@ BOOST_AUTO_TEST_CASE(server_reference) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(!ec); } @@ -2036,97 +1612,73 @@ BOOST_AUTO_TEST_CASE(server_reference) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -2150,73 +1702,55 @@ BOOST_AUTO_TEST_CASE(reason_string) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(!ec); } @@ -2224,41 +1758,31 @@ BOOST_AUTO_TEST_CASE(reason_string) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -2282,17 +1806,13 @@ BOOST_AUTO_TEST_CASE(receive_maximum) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(!ec); } @@ -2300,97 +1820,73 @@ BOOST_AUTO_TEST_CASE(receive_maximum) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -2414,17 +1910,13 @@ BOOST_AUTO_TEST_CASE(topic_alias_maximum) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(!ec); } @@ -2432,97 +1924,73 @@ BOOST_AUTO_TEST_CASE(topic_alias_maximum) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -2546,9 +2014,7 @@ BOOST_AUTO_TEST_CASE(topic_alias) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(!ec); } @@ -2556,105 +2022,79 @@ BOOST_AUTO_TEST_CASE(topic_alias) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -2678,9 +2118,7 @@ BOOST_AUTO_TEST_CASE(maximum_qos) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(!ec); } @@ -2688,105 +2126,79 @@ BOOST_AUTO_TEST_CASE(maximum_qos) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -2810,9 +2222,7 @@ BOOST_AUTO_TEST_CASE(retain_available) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(!ec); } @@ -2820,105 +2230,79 @@ BOOST_AUTO_TEST_CASE(retain_available) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -2942,113 +2326,85 @@ BOOST_AUTO_TEST_CASE(user_property) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(!ec); } @@ -3074,17 +2430,13 @@ BOOST_AUTO_TEST_CASE(maximum_packet_size) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(!ec); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(!ec); } @@ -3092,97 +2444,73 @@ BOOST_AUTO_TEST_CASE(maximum_packet_size) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -3206,9 +2534,7 @@ BOOST_AUTO_TEST_CASE(wildcard_subscription_available) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(!ec); } @@ -3216,105 +2542,79 @@ BOOST_AUTO_TEST_CASE(wildcard_subscription_available) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -3338,9 +2638,7 @@ BOOST_AUTO_TEST_CASE(subscription_identifier_available) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(!ec); } @@ -3348,105 +2646,79 @@ BOOST_AUTO_TEST_CASE(subscription_identifier_available) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } @@ -3470,9 +2742,7 @@ BOOST_AUTO_TEST_CASE(shared_subscription_available) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !!am::make_property_variant(wbuf, am::property_location::connack, ec) - ); + am::make_property_variant(wbuf, am::property_location::connack, ec); BOOST_TEST(!ec); } @@ -3480,105 +2750,79 @@ BOOST_AUTO_TEST_CASE(shared_subscription_available) { { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::connect, ec) - ); + am::make_property_variant(wbuf, am::property_location::connect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::publish, ec) - ); + am::make_property_variant(wbuf, am::property_location::publish, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::will, ec) - ); + am::make_property_variant(wbuf, am::property_location::will, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::puback, ec) - ); + am::make_property_variant(wbuf, am::property_location::puback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrec, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrec, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubrel, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubrel, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::pubcomp, ec) - ); + am::make_property_variant(wbuf, am::property_location::pubcomp, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::subscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::subscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::suback, ec) - ); + am::make_property_variant(wbuf, am::property_location::suback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsubscribe, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsubscribe, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::unsuback, ec) - ); + am::make_property_variant(wbuf, am::property_location::unsuback, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::disconnect, ec) - ); + am::make_property_variant(wbuf, am::property_location::disconnect, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } { auto wbuf{buf}; am::error_code ec; - BOOST_TEST( - !am::make_property_variant(wbuf, am::property_location::auth, ec) - ); + am::make_property_variant(wbuf, am::property_location::auth, ec); BOOST_TEST(ec == am::disconnect_reason_code::malformed_packet); } } diff --git a/test/unit/ut_prop_variant_no_assert.cpp b/test/unit/ut_prop_variant_no_assert.cpp deleted file mode 100644 index 9bdcc09c6..000000000 --- a/test/unit/ut_prop_variant_no_assert.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright Takatoshi Kondo 2022 -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -#define BOOST_DISABLE_ASSERTS - -#include "../common/test_main.hpp" -#include "../common/global_fixture.hpp" - -#include - -#include - - -#include -#include - -BOOST_AUTO_TEST_SUITE(ut_prop_variant_no_assert) - -namespace am = async_mqtt; - -BOOST_AUTO_TEST_CASE(monostate) { - am::property_variant pv; - BOOST_TEST(pv.id() == static_cast(0)); - BOOST_TEST(pv.num_of_const_buffer_sequence() == 0); - BOOST_TEST(pv.const_buffer_sequence().size() == 0); - BOOST_TEST(pv.size() == 0); -} - -BOOST_AUTO_TEST_SUITE_END() diff --git a/test/unit/ut_property.cpp b/test/unit/ut_property.cpp index 6fb559b87..d68188699 100644 --- a/test/unit/ut_property.cpp +++ b/test/unit/ut_property.cpp @@ -11,9 +11,9 @@ #include // for operator<<() test -#include -#include -#include +#include +#include +#include BOOST_AUTO_TEST_SUITE(ut_property) diff --git a/test/unit/ut_retained_topic_map_broker.cpp b/test/unit/ut_retained_topic_map_broker.cpp index e12ae20ea..aec7b430d 100644 --- a/test/unit/ut_retained_topic_map_broker.cpp +++ b/test/unit/ut_retained_topic_map_broker.cpp @@ -9,7 +9,7 @@ #include #include -#include +#include BOOST_AUTO_TEST_SUITE(ut_retained_topic_map_broker) diff --git a/test/unit/ut_strm.cpp b/test/unit/ut_strm.cpp index 1d56b4178..e6089bb00 100644 --- a/test/unit/ut_strm.cpp +++ b/test/unit/ut_strm.cpp @@ -11,9 +11,9 @@ #include -#include +#include #include -#include +#include #include "stub_socket.hpp" diff --git a/test/unit/ut_subscription_map_broker.cpp b/test/unit/ut_subscription_map_broker.cpp index ca0e30164..e8c672438 100644 --- a/test/unit/ut_subscription_map_broker.cpp +++ b/test/unit/ut_subscription_map_broker.cpp @@ -16,7 +16,7 @@ #include #include -#include +#include BOOST_AUTO_TEST_SUITE(ut_subscription_map_broker) diff --git a/test/unit/ut_topic_sharename.cpp b/test/unit/ut_topic_sharename.cpp index 617970483..3ad9697aa 100644 --- a/test/unit/ut_topic_sharename.cpp +++ b/test/unit/ut_topic_sharename.cpp @@ -7,7 +7,7 @@ #include "../common/test_main.hpp" #include "../common/global_fixture.hpp" -#include +#include BOOST_AUTO_TEST_SUITE(ut_topic_sharename) diff --git a/test/unit/ut_topic_subopts.cpp b/test/unit/ut_topic_subopts.cpp index 529fb4c3c..7c0802451 100644 --- a/test/unit/ut_topic_subopts.cpp +++ b/test/unit/ut_topic_subopts.cpp @@ -7,7 +7,7 @@ #include "../common/test_main.hpp" #include "../common/global_fixture.hpp" -#include +#include BOOST_AUTO_TEST_SUITE(ut_topic_subopts) diff --git a/tool/CMakeLists.txt b/tool/CMakeLists.txt index aefbe1b5e..6e8187bde 100644 --- a/tool/CMakeLists.txt +++ b/tool/CMakeLists.txt @@ -25,6 +25,15 @@ foreach(source_file ${exec_PROGRAMS}) target_include_directories(${source_file_we} PRIVATE include) target_link_libraries(${source_file_we} async_mqtt_iface) + if(ASYNC_MQTT_MRDOCS) + target_compile_definitions( + ${source_file_we} + PUBLIC + ASYNC_MQTT_MRDOCS + ) + endif() + + if(WIN32 AND ASYNC_MQTT_USE_STATIC_OPENSSL) target_link_libraries(${source_file_we} Crypt32) endif() @@ -47,6 +56,33 @@ foreach(source_file ${exec_PROGRAMS}) target_link_libraries(${source_file_we} Boost::program_options cli::cli) endforeach() +# Separate compiled broker +if(ASYNC_MQTT_BUILD_LIB) + +add_executable(broker_separate broker.cpp) +add_dependencies(broker_separate async_mqtt_asio_bind async_mqtt_protocol) +target_compile_definitions(broker_separate PRIVATE ASYNC_MQTT_SEPARATE_COMPILATION) +target_include_directories(broker_separate PRIVATE include) +target_link_libraries(broker_separate async_mqtt_iface async_mqtt_asio_bind async_mqtt_protocol) +if(ASYNC_MQTT_USE_LOG) + target_compile_definitions( + broker_separate + PUBLIC + $,,BOOST_LOG_DYN_LINK> + ) + target_link_libraries( + broker_separate Boost::log + ) +endif() +target_compile_definitions( + broker_separate + PUBLIC + $,,BOOST_PROGRAM_OPTIONS_DYN_LINK> +) +target_link_libraries(broker_separate Boost::program_options) + +endif() + if(UNIX) file(COPY broker.conf DESTINATION "${CMAKE_CURRENT_BINARY_DIR}" ) file(COPY auth.json DESTINATION "${CMAKE_CURRENT_BINARY_DIR}" ) diff --git a/tool/bench.cpp b/tool/bench.cpp index 7df7dd7a6..0dba9b0d2 100644 --- a/tool/bench.cpp +++ b/tool/bench.cpp @@ -233,23 +233,23 @@ struct bench { // forwarding callbacks void operator()(ClientInfo* pci = nullptr) { - proc(am::error_code{}, am::packet_variant{}, {}, pci, ev_type::other); + proc(am::error_code{}, std::nullopt, {}, pci, ev_type::other); } void operator()(am::error_code ec, ClientInfo* pci = nullptr, ev_type ect = ev_type::other) { - proc(ec, am::packet_variant{}, {}, pci, ect); + proc(ec, std::nullopt, {}, pci, ect); } - void operator()(am::error_code const& ec, am::packet_variant pv, ClientInfo* pci = nullptr) { - proc(ec, am::force_move(pv), {}, pci, ev_type::recv_packet); + void operator()(am::error_code const& ec, std::optional pv_opt, ClientInfo* pci = nullptr) { + proc(ec, am::force_move(pv_opt), {}, pci, ev_type::recv_packet); } void operator()(am::error_code const& ec, am::packet_id_type pid, ClientInfo* pci = nullptr) { pci->pid = pid; - proc(ec, am::packet_variant{}, pid, pci, ev_type::acquire_result); + proc(ec, std::nullopt, pid, pci, ev_type::acquire_result); } private: void proc( boost::system::error_code ec, - am::packet_variant pv, + std::optional pv_opt, am::packet_id_type pid, ClientInfo* pci, ev_type evt @@ -281,8 +281,7 @@ struct bench { } // Handshake underlying layer - yield am::async_underlying_handshake( - pci->c.next_layer(), + yield pci->c.async_underlying_handshake( pci->host, pci->port, as::append( @@ -379,7 +378,7 @@ struct bench { pci ) ); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::connack_packet const& p) { if (p.code() == am::connect_reason_code::success) { @@ -516,7 +515,7 @@ struct bench { pci ) ); - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::suback_packet const& p) { if (p.entries().front() == am::suback_reason_code::granted_qos_0 || @@ -747,9 +746,9 @@ struct bench { } else if (evt == ev_type::recv_packet) { // pub received - BOOST_ASSERT(pv); + BOOST_ASSERT(pv_opt); pub_recv ret = pub_recv::cont; - pv.visit( + pv_opt->visit( am::overload { [&](am::v5::publish_packet const& p) { ret = recv_publish( diff --git a/tool/broker.cpp b/tool/broker.cpp index 5a6a55617..db19f32c3 100644 --- a/tool/broker.cpp +++ b/tool/broker.cpp @@ -279,7 +279,7 @@ void run_broker(boost::program_options::variables_map const& vm) { as::make_strand(con_ioc_getter().get_executor()) ); epsp->set_bulk_write(vm["bulk_write"].as()); - epsp->set_bulk_read_buffer_size(vm["bulk_read_buf_size"].as()); + epsp->set_read_buffer_size(vm["read_buf_size"].as()); auto& lowest_layer = epsp->lowest_layer(); mqtt_ac->async_accept( lowest_layer, @@ -291,6 +291,7 @@ void run_broker(boost::program_options::variables_map const& vm) { } else { apply_socket_opts(lowest_layer); + epsp->underlying_accepted(); brk.handle_accept(epv_type{force_move(epsp)}); } mqtt_async_accept(); @@ -323,7 +324,7 @@ void run_broker(boost::program_options::variables_map const& vm) { as::make_strand(con_ioc_getter().get_executor()) ); epsp->set_bulk_write(vm["bulk_write"].as()); - epsp->set_bulk_read_buffer_size(vm["bulk_read_buf_size"].as()); + epsp->set_read_buffer_size(vm["read_buf_size"].as()); auto& lowest_layer = epsp->lowest_layer(); ws_ac->async_accept( lowest_layer, @@ -344,6 +345,7 @@ void run_broker(boost::program_options::variables_map const& vm) { << "WS accept error:" << ec.message(); } else { + epsp->underlying_accepted(); brk.handle_accept(epv_type{force_move(epsp)}); } } @@ -420,7 +422,7 @@ void run_broker(boost::program_options::variables_map const& vm) { *mqtts_ctx ); epsp->set_bulk_write(vm["bulk_write"].as()); - epsp->set_bulk_read_buffer_size(vm["bulk_read_buf_size"].as()); + epsp->set_read_buffer_size(vm["read_buf_size"].as()); auto& lowest_layer = epsp->lowest_layer(); mqtts_ac->async_accept( lowest_layer, @@ -442,6 +444,7 @@ void run_broker(boost::program_options::variables_map const& vm) { << "TLS handshake error:" << ec.message(); } else { + epsp->underlying_accepted(); brk.handle_accept(epv_type{force_move(epsp)}, *username); } } @@ -516,7 +519,7 @@ void run_broker(boost::program_options::variables_map const& vm) { *wss_ctx ); epsp->set_bulk_write(vm["bulk_write"].as()); - epsp->set_bulk_read_buffer_size(vm["bulk_read_buf_size"].as()); + epsp->set_read_buffer_size(vm["read_buf_size"].as()); auto& lowest_layer = epsp->lowest_layer(); wss_ac->async_accept( lowest_layer, @@ -548,6 +551,7 @@ void run_broker(boost::program_options::variables_map const& vm) { << "WS accept error:" << ec.message(); } else { + epsp->underlying_accepted(); brk.handle_accept(epv_type{force_move(epsp)}, *username); } } @@ -733,9 +737,9 @@ int main(int argc, char *argv[]) { "Set bulk write mode for all connections" ) ( - "bulk_read_buf_size", - boost::program_options::value()->default_value(0), - "If 0(default), disable bulk read. Otherwise the buffer size of internal async_read_some() call for bulk read" + "read_buf_size", + boost::program_options::value()->default_value(65535), + "Buffer size of internal async_read_some() buffer" ) ( "recycling_allocator", diff --git a/tool/client_cli.cpp b/tool/client_cli.cpp index 71b76b134..32498396e 100644 --- a/tool/client_cli.cpp +++ b/tool/client_cli.cpp @@ -767,14 +767,17 @@ class network_manager { } // forwarding callbacks - void operator()(am::error_code const& ec = am::error_code{}, am::packet_variant pv = am::packet_variant{}) { - proc(ec, am::force_move(pv)); + void operator()( + am::error_code const& ec = am::error_code{}, + std::optional pv_opt = std::nullopt + ) { + proc(ec, am::force_move(pv_opt)); } private: void proc( am::error_code const& ec, - am::packet_variant pv + std::optional pv_opt ) { reenter (coro_) { yield { @@ -808,8 +811,7 @@ class network_manager { sei_ = vm_["sei"].template as(); // Handshake underlying layer - am::async_underlying_handshake( - ep_.next_layer(), + ep_.async_underlying_handshake( host_, boost::lexical_cast(port), *this @@ -874,7 +876,7 @@ class network_manager { std::cout << color_none; return; } - pv.visit( + pv_opt->visit( am::overload { [&](am::v3_1_1::publish_packet const& p) { std::cout << color_recv; diff --git a/tool/include/broker/broker.hpp b/tool/include/broker/broker.hpp index f2e05fca8..617fde38b 100644 --- a/tool/include/broker/broker.hpp +++ b/tool/include/broker/broker.hpp @@ -56,7 +56,7 @@ class broker { void async_read_packet(epsp_type epsp) { auto recv_proc = [this, epsp] - (error_code const& ec, packet_variant pv) mutable { + (error_code const& ec, std::optional pv_opt) mutable { if (ec) { ASYNC_MQTT_LOG("mqtt_broker", info) << ASYNC_MQTT_ADD_VALUE(address, epsp.get_address()) @@ -67,7 +67,8 @@ class broker { ); return; } - BOOST_ASSERT(pv); + BOOST_ASSERT(pv_opt); + auto& pv{*pv_opt}; pv.visit( overload { [&](v3_1_1::connect_packet& p) { diff --git a/tool/include/broker/endpoint_variant.hpp b/tool/include/broker/endpoint_variant.hpp index 7e866922c..4aa2294be 100644 --- a/tool/include/broker/endpoint_variant.hpp +++ b/tool/include/broker/endpoint_variant.hpp @@ -10,7 +10,7 @@ #include #include #include -#include +#include namespace async_mqtt { diff --git a/tool/include/broker/inflight_message.hpp b/tool/include/broker/inflight_message.hpp index 28965bbd0..411a4e7f0 100644 --- a/tool/include/broker/inflight_message.hpp +++ b/tool/include/broker/inflight_message.hpp @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include diff --git a/tool/include/broker/offline_message.hpp b/tool/include/broker/offline_message.hpp index 38d6db3dc..d6de11148 100644 --- a/tool/include/broker/offline_message.hpp +++ b/tool/include/broker/offline_message.hpp @@ -17,13 +17,13 @@ #include #include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include #include diff --git a/tool/include/broker/retain_type.hpp b/tool/include/broker/retain_type.hpp index 80e2f70d1..2fdcdc514 100644 --- a/tool/include/broker/retain_type.hpp +++ b/tool/include/broker/retain_type.hpp @@ -10,8 +10,8 @@ #include #include -#include -#include +#include +#include namespace async_mqtt { diff --git a/tool/include/broker/session_state.hpp b/tool/include/broker/session_state.hpp index d95df3533..fb01f0d7a 100644 --- a/tool/include/broker/session_state.hpp +++ b/tool/include/broker/session_state.hpp @@ -15,7 +15,7 @@ #include #include -#include +#include #include #include diff --git a/tool/include/broker/subscription.hpp b/tool/include/broker/subscription.hpp index 388a09511..2eb490fb0 100644 --- a/tool/include/broker/subscription.hpp +++ b/tool/include/broker/subscription.hpp @@ -10,7 +10,7 @@ #include #include -#include +#include #include #include