├── .github ├── depends │ └── boost.sh └── workflows │ └── gha.yml ├── .gitignore ├── CHANGELOG.adoc ├── CMakeLists.txt ├── LICENSE ├── README.md ├── cmake ├── Config.cmake.in └── createcmakeconfig.cmake ├── codecov.yml ├── doc ├── antora.yml ├── build_antora.sh ├── copy_example.sh ├── local-playbook.yml ├── modules │ └── ROOT │ │ ├── images │ │ ├── bench.png │ │ ├── con_on_x_map.svg │ │ ├── con_rvcon.svg │ │ ├── connection.svg │ │ ├── layer.svg │ │ ├── maximum_packet_size.svg │ │ ├── receive_maximum.svg │ │ ├── request_response1.svg │ │ ├── request_response2.svg │ │ ├── rv_connection.svg │ │ ├── topic_alias1.svg │ │ ├── topic_alias2.svg │ │ └── topic_alias3.svg │ │ ├── nav.adoc │ │ └── pages │ │ ├── CHANGELOG.adoc │ │ ├── codingrule.adoc │ │ ├── comparison.adoc │ │ ├── config.adoc │ │ ├── customize.adoc │ │ ├── functionality │ │ ├── connect_timeout.adoc │ │ ├── error_report.adoc │ │ ├── keep_session.adoc │ │ ├── logging.adoc │ │ ├── maximum_packet_size.adoc │ │ ├── non_packet_based.adoc │ │ ├── packet_based.adoc │ │ ├── packet_id.adoc │ │ ├── receive_maximum.adoc │ │ ├── request_response.adoc │ │ ├── resend.adoc │ │ ├── thread_safe.adoc │ │ └── topic_alias.adoc │ │ ├── goal.adoc │ │ ├── header.adoc │ │ ├── index.adoc │ │ ├── older.adoc │ │ ├── performance.adoc │ │ ├── quicklook.adoc │ │ ├── reference.adoc │ │ ├── requirements.adoc │ │ ├── sansio.adoc │ │ ├── separate.adoc │ │ ├── tool │ │ ├── bench.adoc │ │ ├── broker.adoc │ │ ├── client_cli.adoc │ │ ├── container.adoc │ │ └── trial.adoc │ │ └── tutorial │ │ ├── client.adoc │ │ ├── cpp20_coro.adoc │ │ ├── create_endpoint.adoc │ │ ├── send_recv.adoc │ │ └── sl_coro.adoc ├── mrdocs.yml ├── package-lock.json ├── package.json └── tagfiles │ └── async_mqtt-doxygen.tag.xml ├── docker ├── README.md ├── bench.sh ├── broker.sh ├── client_cli.sh ├── conf │ ├── auth.json │ ├── bench.conf │ ├── broker.conf │ ├── cacert.pem │ ├── cli.conf │ ├── client.crt.pem │ ├── client.key.pem │ ├── server.crt.pem │ └── server.key.pem └── create_image │ ├── Dockerfile │ └── Dockerfile.ubuntu ├── example ├── CMakeLists.txt ├── cl_cpp17_mqtt_pub.cpp ├── cl_cpp17_mqtt_sub.cpp ├── cl_cpp20coro_mqtt.cpp ├── cl_cpp20coro_mqtt_pub.cpp ├── cl_cpp20coro_mqtt_sub.cpp ├── cn_mqtt_client.cpp ├── cn_mqtt_pub.cpp ├── cn_mqtt_sub.cpp ├── custom_logger.cpp ├── ep_cb_mqtt_client.cpp ├── ep_cpp20coro_mqtt_client.cpp ├── ep_future_mqtt_client.cpp ├── ep_slcoro_mqtt_client.cpp ├── ep_slcoro_mqtts_client.cpp ├── ep_slcoro_ws_client.cpp ├── ep_slcoro_wss_client.cpp ├── footprint.cpp ├── locked_cout.hpp ├── rvcn_mqtt_client.cpp ├── separate_client │ ├── CMakeLists.txt │ └── main.cpp ├── separate_client_manual │ ├── CMakeLists.txt │ ├── main.cpp │ └── src.cpp ├── separate_endpoint │ ├── CMakeLists.txt │ └── main.cpp ├── separate_endpoint_manual │ ├── CMakeLists.txt │ ├── main.cpp │ └── src.cpp ├── separate_protocol │ ├── CMakeLists.txt │ └── main.cpp └── separate_protocol_manual │ ├── CMakeLists.txt │ ├── main.cpp │ └── src.cpp ├── gen_all.py ├── include ├── CMakeLists.txt └── async_mqtt │ ├── all.hpp │ ├── asio_bind │ ├── client.hpp │ ├── client_fwd.hpp │ ├── detail │ │ ├── client_impl_fwd.hpp │ │ ├── client_packet_type_getter.hpp │ │ ├── endpoint_impl_fwd.hpp │ │ ├── instantiate_helper.hpp │ │ └── stream_layer.hpp │ ├── endpoint.hpp │ ├── endpoint_fwd.hpp │ ├── filter.hpp │ ├── impl │ │ ├── client_acquire_unique_packet_id.hpp │ │ ├── client_acquire_unique_packet_id.ipp │ │ ├── client_acquire_unique_packet_id_wait_until.hpp │ │ ├── client_acquire_unique_packet_id_wait_until.ipp │ │ ├── client_auth.hpp │ │ ├── client_auth.ipp │ │ ├── client_close.hpp │ │ ├── client_close.ipp │ │ ├── client_disconnect.hpp │ │ ├── client_disconnect.ipp │ │ ├── client_impl.hpp │ │ ├── client_instantiate.hpp │ │ ├── client_instantiate_direct.hpp │ │ ├── client_misc.hpp │ │ ├── client_misc.ipp │ │ ├── client_publish.hpp │ │ ├── client_publish.ipp │ │ ├── client_recv.hpp │ │ ├── client_recv.ipp │ │ ├── client_register_packet_id.hpp │ │ ├── client_register_packet_id.ipp │ │ ├── client_release_packet_id.hpp │ │ ├── client_release_packet_id.ipp │ │ ├── client_start.hpp │ │ ├── client_start.ipp │ │ ├── client_subscribe.hpp │ │ ├── client_subscribe.ipp │ │ ├── client_underlying_handshake.hpp │ │ ├── client_unsubscribe.hpp │ │ ├── client_unsubscribe.ipp │ │ ├── endpoint_acquire_unique_packet_id.hpp │ │ ├── endpoint_acquire_unique_packet_id.ipp │ │ ├── endpoint_acquire_unique_packet_id_wait_until.hpp │ │ ├── endpoint_acquire_unique_packet_id_wait_until.ipp │ │ ├── endpoint_add_retry.ipp │ │ ├── endpoint_close.hpp │ │ ├── endpoint_close.ipp │ │ ├── endpoint_get_stored_packets.hpp │ │ ├── endpoint_get_stored_packets.ipp │ │ ├── endpoint_impl.hpp │ │ ├── endpoint_instantiate.hpp │ │ ├── endpoint_instantiate_direct.hpp │ │ ├── endpoint_misc.hpp │ │ ├── endpoint_misc.ipp │ │ ├── endpoint_recv.hpp │ │ ├── endpoint_recv.ipp │ │ ├── endpoint_register_packet_id.hpp │ │ ├── endpoint_register_packet_id.ipp │ │ ├── endpoint_regulate_for_store.hpp │ │ ├── endpoint_regulate_for_store.ipp │ │ ├── endpoint_release_packet_id.hpp │ │ ├── endpoint_release_packet_id.ipp │ │ ├── endpoint_restore_packets.hpp │ │ ├── endpoint_restore_packets.ipp │ │ ├── endpoint_send.hpp │ │ ├── endpoint_underlying_handshake.hpp │ │ ├── stream.hpp │ │ ├── stream_close.hpp │ │ ├── stream_fwd.hpp │ │ ├── stream_impl.hpp │ │ ├── stream_impl_fwd.hpp │ │ ├── stream_read.hpp │ │ ├── stream_underlying_handshake.hpp │ │ └── stream_write_packet.hpp │ ├── predefined_layer │ │ ├── customized_basic_stream.hpp │ │ ├── customized_ssl_stream.hpp │ │ ├── customized_websocket_stream.hpp │ │ ├── mqtt.hpp │ │ ├── mqtts.hpp │ │ ├── ws.hpp │ │ └── wss.hpp │ └── stream_customize.hpp │ ├── protocol │ ├── buffer_to_packet_variant.hpp │ ├── connection.hpp │ ├── connection_fwd.hpp │ ├── connection_status.hpp │ ├── detail │ │ └── connection_impl_fwd.hpp │ ├── error.hpp │ ├── event │ │ ├── close.hpp │ │ ├── event_variant.hpp │ │ ├── packet_id_released.hpp │ │ ├── packet_received.hpp │ │ ├── send.hpp │ │ └── timer.hpp │ ├── impl │ │ ├── buffer_to_packet_variant.ipp │ │ ├── connection_impl.hpp │ │ ├── connection_impl.ipp │ │ ├── connection_instantiate.hpp │ │ ├── connection_instantiate_direct.hpp │ │ ├── connection_send.ipp │ │ ├── connection_status_impl.ipp │ │ ├── error.hpp │ │ ├── packet_id_manager.hpp │ │ ├── rv_connection.hpp │ │ ├── rv_connection.ipp │ │ ├── rv_connection_instantiate.hpp │ │ ├── rv_connection_instantiate_direct.hpp │ │ ├── store.hpp │ │ └── timer_impl.ipp │ ├── packet │ │ ├── control_packet_type.hpp │ │ ├── detail │ │ │ ├── base_property.hpp │ │ │ ├── fixed_header.hpp │ │ │ └── is_payload.hpp │ │ ├── impl │ │ │ ├── connect_flags.hpp │ │ │ ├── copy_to_static_vector.hpp │ │ │ ├── get_protocol_version.hpp │ │ │ ├── packet_helper.hpp │ │ │ ├── packet_variant.hpp │ │ │ ├── packet_variant.ipp │ │ │ ├── property.hpp │ │ │ ├── property.ipp │ │ │ ├── property_variant.hpp │ │ │ ├── property_variant.ipp │ │ │ ├── session_present.hpp │ │ │ ├── v3_1_1_connack.ipp │ │ │ ├── v3_1_1_connect.ipp │ │ │ ├── v3_1_1_disconnect.ipp │ │ │ ├── v3_1_1_pingreq.ipp │ │ │ ├── v3_1_1_pingresp.ipp │ │ │ ├── v3_1_1_puback.ipp │ │ │ ├── v3_1_1_pubcomp.ipp │ │ │ ├── v3_1_1_publish.hpp │ │ │ ├── v3_1_1_publish.ipp │ │ │ ├── v3_1_1_pubrec.ipp │ │ │ ├── v3_1_1_pubrel.ipp │ │ │ ├── v3_1_1_suback.ipp │ │ │ ├── v3_1_1_subscribe.ipp │ │ │ ├── v3_1_1_unsuback.ipp │ │ │ ├── v3_1_1_unsubscribe.ipp │ │ │ ├── v5_auth.ipp │ │ │ ├── v5_connack.ipp │ │ │ ├── v5_connect.ipp │ │ │ ├── v5_disconnect.ipp │ │ │ ├── v5_pingreq.ipp │ │ │ ├── v5_pingresp.ipp │ │ │ ├── v5_puback.ipp │ │ │ ├── v5_pubcomp.ipp │ │ │ ├── v5_publish.hpp │ │ │ ├── v5_publish.ipp │ │ │ ├── v5_pubrec.ipp │ │ │ ├── v5_pubrel.ipp │ │ │ ├── v5_suback.ipp │ │ │ ├── v5_subscribe.ipp │ │ │ ├── v5_unsuback.ipp │ │ │ ├── v5_unsubscribe.ipp │ │ │ └── validate_property.hpp │ │ ├── packet_fwd.hpp │ │ ├── packet_helper.hpp │ │ ├── packet_id_type.hpp │ │ ├── packet_iterator.hpp │ │ ├── packet_traits.hpp │ │ ├── packet_variant.hpp │ │ ├── packet_variant_fwd.hpp │ │ ├── property.hpp │ │ ├── property_id.hpp │ │ ├── property_variant.hpp │ │ ├── pubopts.hpp │ │ ├── qos.hpp │ │ ├── qos_util.hpp │ │ ├── store_packet_variant.hpp │ │ ├── store_packet_variant_fwd.hpp │ │ ├── subopts.hpp │ │ ├── topic_sharename.hpp │ │ ├── topic_subopts.hpp │ │ ├── v3_1_1_connack.hpp │ │ ├── v3_1_1_connect.hpp │ │ ├── v3_1_1_disconnect.hpp │ │ ├── v3_1_1_pingreq.hpp │ │ ├── v3_1_1_pingresp.hpp │ │ ├── v3_1_1_puback.hpp │ │ ├── v3_1_1_pubcomp.hpp │ │ ├── v3_1_1_publish.hpp │ │ ├── v3_1_1_pubrec.hpp │ │ ├── v3_1_1_pubrel.hpp │ │ ├── v3_1_1_suback.hpp │ │ ├── v3_1_1_subscribe.hpp │ │ ├── v3_1_1_unsuback.hpp │ │ ├── v3_1_1_unsubscribe.hpp │ │ ├── v5_auth.hpp │ │ ├── v5_connack.hpp │ │ ├── v5_connect.hpp │ │ ├── v5_disconnect.hpp │ │ ├── v5_pingreq.hpp │ │ ├── v5_pingresp.hpp │ │ ├── v5_puback.hpp │ │ ├── v5_pubcomp.hpp │ │ ├── v5_publish.hpp │ │ ├── v5_pubrec.hpp │ │ ├── v5_pubrel.hpp │ │ ├── v5_suback.hpp │ │ ├── v5_subscribe.hpp │ │ ├── v5_unsuback.hpp │ │ ├── v5_unsubscribe.hpp │ │ └── will.hpp │ ├── protocol_version.hpp │ ├── role.hpp │ ├── rv_connection.hpp │ └── timer.hpp │ ├── separate │ ├── src.hpp │ ├── src_client.hpp │ ├── src_connection.hpp │ ├── src_endpoint.hpp │ └── src_rv_connection.hpp │ └── util │ ├── buffer.hpp │ ├── detail │ └── is_iterator.hpp │ ├── endian_convert.hpp │ ├── host_port.hpp │ ├── inline.hpp │ ├── ioc_queue.hpp │ ├── json_like_out.hpp │ ├── log.hpp │ ├── log_severity.hpp │ ├── move.hpp │ ├── overload.hpp │ ├── scope_guard.hpp │ ├── setup_log.hpp │ ├── shared_ptr_array.hpp │ ├── static_vector.hpp │ ├── string_view_helper.hpp │ ├── topic_alias_recv.hpp │ ├── topic_alias_send.hpp │ ├── utf8validate.hpp │ ├── value_allocator.hpp │ └── variable_bytes.hpp ├── lib └── CMakeLists.txt ├── llvm-gcov.sh ├── makedoc.sh ├── test ├── CMakeLists.txt ├── args_provider.sh ├── certs │ ├── cacert.pem │ ├── client.crt.pem │ ├── client.key.pem │ ├── mosquitto.org.crt │ ├── server.crt.pem │ └── server.key.pem ├── common │ ├── global_fixture.hpp │ └── test_main.hpp ├── system │ ├── CMakeLists.txt │ ├── broker_runner.hpp │ ├── coro_base.hpp │ ├── st_auth.cpp │ ├── st_auth.json │ ├── st_broker.conf │ ├── st_cancel.cpp │ ├── st_conflict_cid.cpp │ ├── st_cpp20coro_client.cpp │ ├── st_cpp20coro_client_direct.cpp │ ├── st_cpp20coro_client_direct_default.cpp │ ├── st_cpp20coro_client_direct_default_error.cpp │ ├── st_cpp20coro_client_direct_error.cpp │ ├── st_gencid.cpp │ ├── st_inflight.cpp │ ├── st_invalid.cpp │ ├── st_keep_alive.cpp │ ├── st_mqtt_connect.cpp │ ├── st_mqtts_connect.cpp │ ├── st_offline.cpp │ ├── st_order.cpp │ ├── st_pub.cpp │ ├── st_reqres.cpp │ ├── st_retain.cpp │ ├── st_shared_sub.cpp │ ├── st_sub.cpp │ ├── st_will.cpp │ ├── st_ws_connect.cpp │ └── st_wss_connect.cpp └── unit │ ├── CMakeLists.txt │ ├── cpp20coro_stub_socket.hpp │ ├── stub_socket.hpp │ ├── test_allocate_buffer.hpp │ ├── ut_broker_security.cpp │ ├── ut_buffer.cpp │ ├── ut_code.cpp │ ├── ut_connection.cpp │ ├── ut_connection_status.cpp │ ├── ut_cpp20coro_broker.cpp │ ├── ut_cpp20coro_cl.cpp │ ├── ut_cpp20coro_ep.cpp │ ├── ut_cpp20coro_exec.cpp │ ├── ut_ep_alloc.cpp │ ├── ut_ep_con_discon.cpp │ ├── ut_ep_keep_alive.cpp │ ├── ut_ep_packet_error.cpp │ ├── ut_ep_pid.cpp │ ├── ut_ep_recv_filter.cpp │ ├── ut_ep_recv_max.cpp │ ├── ut_ep_size_max.cpp │ ├── ut_ep_store.cpp │ ├── ut_ep_topic_alias.cpp │ ├── ut_error.cpp │ ├── ut_host_port.cpp │ ├── ut_multi_file1.cpp │ ├── ut_multi_file2.cpp │ ├── ut_null_strand.cpp │ ├── ut_packet_id.cpp │ ├── ut_packet_v3_1_1_connack.cpp │ ├── ut_packet_v3_1_1_connect.cpp │ ├── ut_packet_v3_1_1_disconnect.cpp │ ├── ut_packet_v3_1_1_pingreq.cpp │ ├── ut_packet_v3_1_1_pingresp.cpp │ ├── ut_packet_v3_1_1_puback.cpp │ ├── ut_packet_v3_1_1_pubcomp.cpp │ ├── ut_packet_v3_1_1_publish.cpp │ ├── ut_packet_v3_1_1_pubrec.cpp │ ├── ut_packet_v3_1_1_pubrel.cpp │ ├── ut_packet_v3_1_1_suback.cpp │ ├── ut_packet_v3_1_1_subscribe.cpp │ ├── ut_packet_v3_1_1_unsuback.cpp │ ├── ut_packet_v3_1_1_unsubscribe.cpp │ ├── ut_packet_v5_auth.cpp │ ├── ut_packet_v5_connack.cpp │ ├── ut_packet_v5_connect.cpp │ ├── ut_packet_v5_disconnect.cpp │ ├── ut_packet_v5_pingreq.cpp │ ├── ut_packet_v5_pingresp.cpp │ ├── ut_packet_v5_puback.cpp │ ├── ut_packet_v5_pubcomp.cpp │ ├── ut_packet_v5_publish.cpp │ ├── ut_packet_v5_pubrec.cpp │ ├── ut_packet_v5_pubrel.cpp │ ├── ut_packet_v5_suback.cpp │ ├── ut_packet_v5_subscribe.cpp │ ├── ut_packet_v5_unsuback.cpp │ ├── ut_packet_v5_unsubscribe.cpp │ ├── ut_packet_variant.cpp │ ├── ut_prop_variant.cpp │ ├── ut_property.cpp │ ├── ut_retained_topic_map.cpp │ ├── ut_retained_topic_map_broker.cpp │ ├── ut_static_assert_fail_client.cpp │ ├── ut_static_assert_fail_server.cpp │ ├── ut_strm.cpp │ ├── ut_subscription_map.cpp │ ├── ut_subscription_map_broker.cpp │ ├── ut_timer.cpp │ ├── ut_topic_alias.cpp │ ├── ut_topic_sharename.cpp │ ├── ut_topic_subopts.cpp │ ├── ut_unique_scope_guard.cpp │ ├── ut_utf8validate.cpp │ └── ut_value_allocator.cpp ├── tool ├── CMakeLists.txt ├── auth.json ├── bench.conf ├── bench.cpp ├── broker.conf ├── broker.cpp ├── cli.conf ├── client_cli.cpp ├── cpp20coro_broker.cpp ├── include │ ├── broker │ │ ├── broker.hpp │ │ ├── constant.hpp │ │ ├── endpoint_variant.hpp │ │ ├── external │ │ │ └── picosha2.h │ │ ├── fixed_core_map.hpp │ │ ├── inflight_message.hpp │ │ ├── mutex.hpp │ │ ├── offline_message.hpp │ │ ├── retain_type.hpp │ │ ├── retained_messages.hpp │ │ ├── retained_topic_map.hpp │ │ ├── security.hpp │ │ ├── session_state.hpp │ │ ├── session_state_fwd.hpp │ │ ├── shared_target.hpp │ │ ├── shared_target_impl.hpp │ │ ├── sub_con_map.hpp │ │ ├── subscription.hpp │ │ ├── subscription_map.hpp │ │ ├── tags.hpp │ │ ├── topic_filter.hpp │ │ └── uuid.hpp │ └── coro_broker │ │ ├── broker.hpp │ │ └── session_state.hpp └── locked_cout.hpp └── update_picosha2.sh /.github/depends/boost.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | usage() 4 | { 5 | cat <async_mqttconnectionrv_connectionuser_custom_connection -------------------------------------------------------------------------------- /doc/modules/ROOT/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:reference.adoc[] 2 | * History 3 | ** xref:CHANGELOG.adoc[Changelog] 4 | ** xref:older.adoc[] 5 | * Introduction 6 | ** xref:requirements.adoc[] 7 | ** xref:goal.adoc[] 8 | * Quick Look 9 | ** xref:quicklook.adoc[] 10 | ** xref:performance.adoc[] 11 | ** xref:comparison.adoc[] 12 | * Tutorial 13 | ** xref:header.adoc[] 14 | ** xref:tutorial/client.adoc[] 15 | ** Endpoint 16 | *** xref:tutorial/create_endpoint.adoc[] 17 | *** xref:tutorial/cpp20_coro.adoc[] 18 | *** xref:tutorial/sl_coro.adoc[] 19 | *** xref:tutorial/send_recv.adoc[] 20 | * Functionality 21 | ** xref:functionality/packet_based.adoc[] 22 | ** xref:functionality/non_packet_based.adoc[] 23 | ** xref:functionality/packet_id.adoc[] 24 | ** xref:functionality/connect_timeout.adoc[] 25 | ** xref:functionality/keep_session.adoc[] 26 | ** xref:functionality/resend.adoc[] 27 | ** xref:functionality/topic_alias.adoc[] 28 | ** xref:functionality/request_response.adoc[] 29 | ** xref:functionality/receive_maximum.adoc[] 30 | ** xref:functionality/maximum_packet_size.adoc[] 31 | ** xref:functionality/thread_safe.adoc[] 32 | ** xref:functionality/logging.adoc[] 33 | ** xref:functionality/error_report.adoc[] 34 | * xref:sansio.adoc[] 35 | * Customize/Config 36 | ** xref:customize.adoc[] 37 | ** xref:config.adoc[] 38 | ** xref:separate.adoc[] 39 | * Tools 40 | ** xref:tool/container.adoc[] 41 | ** xref:tool/trial.adoc[] 42 | ** xref:tool/broker.adoc[] 43 | ** xref:tool/client_cli.adoc[] 44 | ** xref:tool/bench.adoc[] 45 | * Contribution 46 | ** xref:codingrule.adoc[] 47 | * link:http://github.com/redboltz/async_mqtt[Repository] 48 | -------------------------------------------------------------------------------- /doc/modules/ROOT/pages/CHANGELOG.adoc: -------------------------------------------------------------------------------- 1 | ../../../../CHANGELOG.adoc -------------------------------------------------------------------------------- /doc/modules/ROOT/pages/config.adoc: -------------------------------------------------------------------------------- 1 | = Config 2 | 3 | == cmake 4 | 5 | |=== 6 | |Flag|Effects 7 | 8 | |ASYNC_MQTT_USE_TLS|Enables TLS for tools (broker, bench, client_cli, ...) 9 | |ASYNC_MQTT_USE_WS|Enables Websocket for tools (broker, bench, client_cli, ...) (compilation time becomes longer). See <>. 10 | |ASYNC_MQTT_USE_LOG|Enable logging via Boost.Log 11 | |ASYNC_MQTT_PRINT_PAYLOAD|Output payload when publish packet is output 12 | |ASYNC_MQTT_BUILD_UNIT_TESTS|Build unit tests 13 | |ASYNC_MQTT_BUILD_SYSTEM_TESTS|Build system tests. The system tests requires broker. 14 | |ASYNC_MQTT_BUILD_TOOLS|Build tools (broker, bench, etc) 15 | |ASYNC_MQTT_BUILD_EXAMPLES|Build examples 16 | |ASYNC_MQTT_BUILD_EXAMPLES_SEPARATE|Build examples for separate library build. It requires much memory. 17 | |ASYNC_MQTT_BUILD_LIB|Build separate compiled library 18 | |=== 19 | 20 | If you want to use TLS, Websocket, and Websocket on TLS, you don't need to define ASYNC_MQTT_USE_TLS and/or ASYNC_MQTT_USE_WS. Simply include the following files that are not included in `async_mqtt/all.hpp`. 21 | 22 | For TLS: 23 | ```cpp 24 | #include 25 | ``` 26 | 27 | For Websocket 28 | ```cpp 29 | #include 30 | ``` 31 | 32 | For Websocket on TLS 33 | ```cpp 34 | #include 35 | ``` 36 | 37 | 38 | == C++ preprocessor macro 39 | 40 | |=== 41 | |Flag|Effects 42 | 43 | |ASYNC_MQTT_USE_TLS|Enables TLS 44 | |ASYNC_MQTT_USE_WS|Enables Websockets (compilation time becomes longer), See <>. 45 | |ASYNC_MQTT_USE_LOG|Enable logging via Boost.Log 46 | |ASYNC_MQTT_PRINT_PAYLOAD|Output payload when publish packet is output 47 | |ASYNC_MQTT_SEPARATE_COMPILATION|Enables xref:separate.adoc[Separate Compilation Mode] 48 | |=== 49 | 50 | 51 | == Make faster compilation time [[faster-compile]] 52 | 53 | xref:separate.adoc[Separate Compilation Mode] for async_mqtt and https://www.boost.org/libs/beast/doc/html/beast/config/configuration_preprocessor_defin.html[Boost.Beast] would solve the long compilation time. -------------------------------------------------------------------------------- /doc/modules/ROOT/pages/functionality/connect_timeout.adoc: -------------------------------------------------------------------------------- 1 | = Connect Timeout 2 | 3 | Before thinking about connection timeout, we need to define what a connection is. Here is a typical connection sequence: 4 | 5 | 1. `async_underlying_handshake` (resolves hostname, TCP, TLS, and WebSocket handshake if required) 6 | 2. Send MQTT CONNECT packet 7 | 3. Receive MQTT CONNACK packet 8 | 9 | Typically, the user can set a timer before Step 1 and cancel the timer after Step 3. If the timer expires, call the `close()` function. 10 | 11 | == PINGRESP timeout 12 | 13 | After the MQTT connection is established (Step 3 is finished successfully), if the underlying connection is disconnected, then the `recv()` function returns an error. However, if the broker is frozen or the disconnect is not detected but actually disconnected, the client needs to know the status of the connection. 14 | 15 | In this case, you can use `set_pingresp_recv_timeout()` and send a PINGREQ packet. 16 | 17 | == set_pingresp_recv_timeout() 18 | 19 | * cpp:async_mqtt::client::set_pingresp_recv_timeout[set_pingresp_recv_timeout() for client] 20 | * cpp:async_mqtt::basic_endpoint::set_pingresp_recv_timeout[set_pingresp_recv_timeout() for endpoint] 21 | 22 | 23 | The parameter is in milliseconds. You need to call this function before sending the MQTT CONNECT packet. The timer is automatically set when the PINGREQ packet is sent. If a PINGRESP packet is received from the broker, the timer is canceled. If the timer expires, the connection is disconnected from the client side. Finally, the client gets an error from the `async_recv()` function. 24 | 25 | == sending PINGREQ packet 26 | 27 | You can create a PINGREQ packet and send it manually. Alternatively, you can set the keep_alive value in the CONNECT packet to a value greater than 0. Then, the client will automatically start sending PINGREQ packets if the keep_alive seconds pass without any packet being sent. 28 | 29 | NOTE: If keep_alive is set to a value greater than 0, the broker also starts checking the client connection status. If the broker doesn't receive any packet from the client during keep_alive * 1.5 seconds, the connection is closed by the broker. 30 | -------------------------------------------------------------------------------- /doc/modules/ROOT/pages/functionality/error_report.adoc: -------------------------------------------------------------------------------- 1 | = Error Reporting 2 | 3 | == Send 4 | `async_*` functions report errors as follows: 5 | 6 | |=== 7 | | Phase | Error Type 8 | 9 | | Packet Construction *1 | `cpp:async_mqtt::connect_reason_code[connect_reason_code]` if the packet is CONNECT and the error is specific to the connection. Otherwise, `cpp:async_mqtt::disconnect_reason_code[disconnect_reason_code]`. 10 | e.g., Invalid argument passed. 11 | | Packet Send Validation | `cpp:async_mqtt::disconnect_reason_code[disconnect_reason_code]`. 12 | e.g., Sending packet at an invalid time. 13 | | Sending | Error code from the underlying layer (`boost::system::error_code`). 14 | e.g., Bad file descriptor. 15 | |=== 16 | 17 | *1 `cpp:async_mqtt::client::async_start[client::async_start]` ,`cpp:async_mqtt::client::async_subscribe[client::async_subscribe]` ,`cpp:async_mqtt::client::async_unsubscribe[client::async_unsubscribe]` ,`cpp:async_mqtt::client::async_disconnect[client::async_disconnect]` , and `cpp:async_mqtt::client::async_auth[client::async_auth]` support internal packet construction. 18 | 19 | == Receive 20 | 21 | `async_*` functions report errors as follows: 22 | 23 | |=== 24 | | Phase | Error Type 25 | 26 | | Receiving | Error code from the underlying layer (`boost::system::error_code`). 27 | e.g., End of file. 28 | | Packet Construction *2 | `cpp:async_mqtt::connect_reason_code[connect_reason_code]` if the packet is CONNECT and the error is specific to the connection. Otherwise, `cpp:async_mqtt::disconnect_reason_code[disconnect_reason_code]`. 29 | e.g., Malformed packet. 30 | | Received Packet Validation | `cpp:async_mqtt::disconnect_reason_code[disconnect_reason_code]`. 31 | e.g., Receiving packet at an invalid time. 32 | |=== 33 | 34 | *2 When `cpp:async_mqtt::endpoint[endpoint]` is used as a broker, a CONNECT packet will be received. 35 | -------------------------------------------------------------------------------- /doc/modules/ROOT/pages/functionality/maximum_packet_size.adoc: -------------------------------------------------------------------------------- 1 | = Maximum Packet Size 2 | 3 | 4 | The Maximum Packet Size is a way to control the size of all packets. If a node sends a packet larger than the Maximum Packet Size, it is considered a protocol error. The counterpart disconnects the connection with a DISCONNECT packet with Reason Code 0x95 (Packet too large). 5 | 6 | == Notifying Maximum Packet Size 7 | 8 | 9 | There are two independent Maximum Packet Size limits. 10 | 11 | image::maximum_packet_size.svg[maximum_packet_size] 12 | -------------------------------------------------------------------------------- /doc/modules/ROOT/pages/functionality/request_response.adoc: -------------------------------------------------------------------------------- 1 | = Request/Response 2 | 3 | MQTT's communication model is a pub/sub model. In order to realize Request/Response on the pub/sub model, MQTT v5.0 uses the following mechanism. 4 | 5 | image::request_response1.svg[request_response] 6 | 7 | == Client 8 | 9 | async_mqtt doesn't perform any special treatment for Request/Response. Simply send a CONNECT packet with the `RequestResponseInformation` property set to 1, and then receive the CONNACK packet. If the CONNACK packet includes `ResponseInformation`, you can obtain `ResponseInformation` from it and subscribe to it. 10 | 11 | == Broker 12 | 13 | The broker part of async_mqtt supports Request/Response. When the broker receives a CONNECT packet with `RequestResponseInformation` set to 1, it automatically generates `ResponseInformation` and sends back a CONNACK packet with it. `ResponseInformation` is the `TopicName` for the response, so the client can use it as the `ResponseTopic` property when sending a PUBLISH packet. 14 | The async_mqtt broker has authentication/authorization support. The generated topic can be subscribed to only by the client that sent `RequestResponseInformation`. The generated topic can be published to by all clients. 15 | 16 | == Correlation Data 17 | 18 | See https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901115 19 | 20 | The client has only one `ResponseTopic` and uses it for all requests. The request receiver client could be different, so the responses could be mixed. To distinguish the correct response, `CorrelationData` can be used. See the following diagram. 21 | 22 | 23 | image::request_response2.svg[request_response] 24 | 25 | client1 got the ResponseInformation R1 and uses it as ResponseTopic. Both client2 and client3 receive the same ResponseTopic and use it for publish back the response. 26 | If control PUBLISH packet contains not only ResponseTopic but also CorrelationData, then the receiver just set the CorrelationData to the response PUBLISH packet. 27 | 28 | client1 can choose any string as CorrelationData. Typically, choose unpredictable string to avoid malformed response. 29 | client1 needs to manage a CorrelationData-Request map to check the corresponding request. 30 | -------------------------------------------------------------------------------- /doc/modules/ROOT/pages/functionality/thread_safe.adoc: -------------------------------------------------------------------------------- 1 | = Thread Safety 2 | 3 | == Single Threaded 4 | 5 | You can call both asynchronous (async) and synchronous (sync) APIs without any special precautions. 6 | 7 | == Multi-threaded 8 | 9 | All distinct objects are not thread-safe. To access shared `client` and/or `endpoint` objects, construct them with a strand-wrapped executor for the underlying layer's argument. The `async_*` member functions of `client` and `endpoint` will dispatch to the executor. As a result of the strand's effect, your asynchronous processes will be serialized. 10 | 11 | The following synchronous member functions are accessed directly. Therefore, you need to introduce locks or explicitly dispatch to the executor. 12 | 13 | 14 | |=== 15 | |endpoint member function | effects 16 | 17 | |cpp:async_mqtt::basic_endpoint::acquire_unique_packet_id[acquire_unique_packet_id]|Acquire the new unique packet_id 18 | |cpp:async_mqtt::basic_endpoint::register_packet_id[register_packet_id]|Register the packet_id 19 | |cpp:async_mqtt::basic_endpoint::release_packet_id[release_packet_id]|Release the packet_id 20 | |cpp:async_mqtt::basic_endpoint::get_qos2_publish_handled_pids[get_qos2_publish_handled_pids]|Get already PUBLISH recv CompletionToken is invoked packet_ids 21 | |cpp:async_mqtt::basic_endpoint::restore_qos2_publish_handled_pids[restore_qos2_publish_handled_pids]|Restore already PUBLISH recv CompletionToken is invoked packet_ids 22 | |cpp:async_mqtt::basic_endpoint::restore_packets[restore_packets]|Restore pacets as stored packets 23 | |cpp:async_mqtt::basic_endpoint::get_stored_packets[get_stored_packets]|Get stored packets 24 | |cpp:async_mqtt::basic_endpoint::get_protocol_version[get_protocol_version]|Get MQTT protocol version 25 | |=== 26 | 27 | |=== 28 | |client member function | effects 29 | 30 | |cpp:async_mqtt::client::acquire_unique_packet_id[acquire_unique_packet_id]|Acquire the new unique packet_id 31 | |cpp:async_mqtt::client::register_packet_id[register_packet_id]|Register the packet_id 32 | |cpp:async_mqtt::client::release_packet_id[release_packet_id]|Release the packet_id 33 | |=== 34 | -------------------------------------------------------------------------------- /doc/modules/ROOT/pages/goal.adoc: -------------------------------------------------------------------------------- 1 | = Design Goal 2 | 3 | == MQTT Conformance 4 | 5 | async_mqtt fully supports all functionalities of MQTT v3.1.1 and v5.0, allowing users to send and receive every type of MQTT packet. For features that require stateful connection management, async_mqtt provides robust support. 6 | 7 | == I/O Independent (Sans-I/O) 8 | 9 | async_mqtt offers a pure MQTT protocol library that is completely independent of any I/O implementation. It works with any I/O platform, including stub implementations. 10 | 11 | == Asio Friendly 12 | 13 | In addition to its pure MQTT protocol library, async_mqtt provides Boost.Asio I/O bindings, making it highly Asio-friendly. It supports Asio-style completion tokens—including the default tokens—allowing users to bind executors, cancellation slots, and allocators. Moreover, async_mqtt is compatible with coroutines and supports Asio-style multiple completion waiting. 14 | 15 | == High Performance 16 | 17 | async_mqtt is designed for high-performance communication. Recognizing that balancing latency and throughput can be a trade-off, it allows configuration on a per-`endpoint` and per-`client` basis. This flexibility makes async_mqtt suitable not only for MQTT clients but also for high-performance brokers. For further details, see the xref:performance.adoc[performance] page. 18 | 19 | == Support for Various Underlying Layers 20 | 21 | async_mqtt supports a wide range of underlying layers, including TCP, TLS, and WebSocket, as well as user-defined layers such as test stubs. 22 | 23 | == Support for Both Detailed Low-Level Operations and Convenient High-Level Operations 24 | 25 | async_mqtt caters to diverse development needs by supporting detailed low-level operations alongside convenient high-level APIs. Through the `endpoint` component, it allows granular control—such as sending any MQTT packet at any time—while the higher-level `client` component (built on top of the `endpoint`) provides a more streamlined interface for typical use cases. 26 | 27 | == Support for Broker Cluster Development 28 | 29 | async_mqtt is also well-suited for broker development. In broker cluster environments where inter-broker communication is critical, async_mqtt supports expanded-length packet identifiers to meet these requirements. 30 | -------------------------------------------------------------------------------- /doc/modules/ROOT/pages/header.adoc: -------------------------------------------------------------------------------- 1 | = Header Files 2 | 3 | == Add Include Path 4 | 5 | Add the `async_mqtt/include` directory to your include path. 6 | 7 | == Convenient Header 8 | 9 | To enable all functionalities (except for specific underlying layers), include: 10 | 11 | ```cpp 12 | #include 13 | ``` 14 | 15 | == Underlying Layer Headers 16 | 17 | === For TCP on MQTT 18 | 19 | ```cpp 20 | #include 21 | ``` 22 | 23 | This header is included in `async_mqtt/all.hpp`. 24 | 25 | === For TLS on MQTT 26 | 27 | ```cpp 28 | #include 29 | ``` 30 | 31 | This header is **not** included in `async_mqtt/all.hpp`. 32 | 33 | === For WebSocket on MQTT 34 | 35 | ```cpp 36 | #include 37 | ``` 38 | 39 | This header is **not** included in `async_mqtt/all.hpp`. 40 | 41 | === For WebSocket/TLS on MQTT 42 | 43 | ```cpp 44 | #include 45 | ``` 46 | 47 | This header is **not** included in `async_mqtt/all.hpp`. 48 | 49 | == Directory Structure 50 | 51 | ```cpp 52 | async_mqtt/all.hpp # Convenient header 53 | /asio_bind/ # Boost.Asio binding for endpoint/client 54 | /protocol/ # I/O-independent MQTT protocol state machine 55 | /separate/ # Headers for separate compilation 56 | /util/ # Common utilities 57 | ``` 58 | 59 | == I/O-Independent MQTT Protocol Machine 60 | 61 | If you don't need Boost.Asio bindings, you can include: 62 | 63 | ```cpp 64 | #include 65 | ``` 66 | 67 | This header is included in `async_mqtt/all.hpp`. 68 | 69 | == Logging 70 | 71 | To enable logging, include: 72 | 73 | ```cpp 74 | #include 75 | #include 76 | ``` 77 | 78 | These headers are included in `async_mqtt/all.hpp`. 79 | -------------------------------------------------------------------------------- /doc/modules/ROOT/pages/index.adoc: -------------------------------------------------------------------------------- 1 | = async_mqtt 2 | 3 | http://github.com/redboltz/async_mqtt 4 | 5 | Copyright © 2024 Takatoshi Kondo 6 | 7 | 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) 8 | -------------------------------------------------------------------------------- /doc/modules/ROOT/pages/older.adoc: -------------------------------------------------------------------------------- 1 | = Older versions' documents 2 | 3 | * link:../../10.0.0/index.html[10.0.0] 4 | * link:../../9.0.2/index.html[9.0.2] 5 | * link:../../9.0.1/index.html[9.0.1] 6 | * link:../../9.0.0/index.html[9.0.0] 7 | * link:../../8.0.1/index.html[8.0.1] 8 | * link:../../8.0.0/index.html[8.0.0] 9 | * link:../../7.0.0/index.html[7.0.0] 10 | * link:../../6.0.0/index.html[6.0.0] 11 | * link:../../5.1.2/index.html[5.1.2] 12 | * link:../../5.1.1/index.html[5.1.1] 13 | * link:../../5.1.0/index.html[5.1.0] 14 | * link:../../5.0.0/index.html[5.0.0] 15 | * link:../../4.1.0/html/index.html[4.1.0] 16 | * link:../../4.0.0/html/index.html[4.0.0] 17 | * link:../../3.0.0/html/index.html[3.0.0] 18 | * link:../../2.0.0/html/index.html[2.0.0] 19 | * link:../../1.0.9/html/index.html[1.0.9] 20 | * link:../../1.0.8/html/index.html[1.0.8] 21 | * link:../../1.0.7/html/index.html[1.0.7] 22 | * link:../../1.0.6/html/index.html[1.0.6] 23 | * link:../../1.0.5/html/index.html[1.0.5] 24 | * link:../../1.0.4/html/index.html[1.0.4] 25 | * link:../../1.0.3/html/index.html[1.0.3] 26 | * link:../../1.0.2/html/index.html[1.0.2] 27 | * link:../../1.0.1/html/index.html[1.0.1] 28 | * link:../../1.0.0/html/index.html[1.0.0] 29 | -------------------------------------------------------------------------------- /doc/modules/ROOT/pages/performance.adoc: -------------------------------------------------------------------------------- 1 | = Performance 2 | 3 | I've measured how many publishes per second can async_mqtt broker treated. 4 | 5 | == Environment 6 | 7 | AWS EC2 c5.4xlarge, c5.12xlarge 8 | 9 | - Benchmark targets 10 | - mosquitto version:2.0.11 11 | - async_mqtt 1.0.6 12 | 13 | Single broker, multiple clients. 14 | clients are genereted by https://github.com/redboltz/async_mqtt/tree/main/docker bench.sh 15 | 16 | It publishes packets and receive it. Measure RTT(Round trip time). 17 | Each clinet 100 publish/second (pps). Increase the number of clients until RTT over 1second. 18 | For example, the number of client is 6,000, that means 600,000 (600K) pps. 19 | Publish payload is 1024 bytes. 20 | 21 | == Result 22 | 23 | === QoS0 24 | 25 | |=== 26 | |ec2\broker|mosquitto|async_mqtt 27 | 28 | |c5.4xlarge|90|250 29 | |c5.12xlarge|90|610 30 | |=== 31 | 32 | value is Kpps (Kilo publish per second) 33 | 34 | === QoS1 35 | 36 | |=== 37 | |ec2\broker|mosquitto|async_mqtt 38 | 39 | |c5.4xlarge|52|155 40 | |c5.12xlarge|52|390 41 | |=== 42 | 43 | value is Kpps (Kilo publish per second) 44 | 45 | === QoS2 46 | 47 | |=== 48 | |ec2\broker|mosquitto|async_mqtt 49 | 50 | |c5.4xlarge|28|89 51 | |c5.12xlarge|28|210 52 | |=== 53 | 54 | value is Kpps (Kilo publish per second) 55 | 56 | ifdef::env-github[image::img/bench.png[]] 57 | ifndef::env-github[image::bench.png[]] 58 | -------------------------------------------------------------------------------- /doc/modules/ROOT/pages/requirements.adoc: -------------------------------------------------------------------------------- 1 | = Requirements 2 | 3 | async_mqtt requires: 4 | 5 | * *C++17:* Robust support for most language features. 6 | 7 | * *Boost:* Boost 1.84.0 or later 8 | ** If you don't build test, Boost 1.82.0 or later 9 | 10 | * *OpenSSL:* If you need TLS connection. 11 | -------------------------------------------------------------------------------- /doc/modules/ROOT/pages/tool/bench.adoc: -------------------------------------------------------------------------------- 1 | = bench 2 | 3 | `bench` is a performance measuring utility. 4 | 5 | `bench` has Boost.ProgramOptions style options. https://github.com/redboltz/async_mqtt/blob/main/tool/bench.conf is config file. You can also set command line options. The command line options are higher priority than file options. 6 | -------------------------------------------------------------------------------- /doc/modules/ROOT/pages/tool/container.adoc: -------------------------------------------------------------------------------- 1 | = Run async_mqtt broker/client on the docker container 2 | 3 | You can run async_mqtt broker, benchmarking tool, and CLI client using docker. 4 | 5 | See https://github.com/redboltz/async_mqtt/tree/main/docker 6 | 7 | == Preparation 8 | 9 | ``` 10 | git clone https://github.com/redboltz/async_mqtt.git 11 | cd async_mqtt 12 | cd docker 13 | ``` 14 | 15 | == Run broker 16 | 17 | ``` 18 | ./broker.sh 19 | ``` 20 | 21 | If you don't have executing docker permission, then run as follows: 22 | 23 | ``` 24 | sudo ./broker.sh 25 | ``` 26 | 27 | == Run client_cli 28 | 29 | On another terminal: 30 | 31 | ``` 32 | ./client_cli.sh --host host.docker.internal 33 | ``` 34 | 35 | If you don't have executing docker permission, then run as follows: 36 | 37 | ``` 38 | sudo ./client_cli.sh --host host.docker.internal 39 | ``` 40 | 41 | Then, you can communicate to the broker container on the same machine. 42 | 43 | You can subscribe and publish as follows: 44 | 45 | ``` 46 | cli> sub t1 1 47 | cli> pub t1 hello 1 48 | cli> exit 49 | ``` 50 | 51 | Red colored message is command response. 52 | Cyan colored message is received packet. 53 | 54 | Also you can connect mosquitto.org as follows. 55 | 56 | ``` 57 | ./client_cli --host test.mosquitto.rog 58 | ``` 59 | -------------------------------------------------------------------------------- /doc/modules/ROOT/pages/tool/trial.adoc: -------------------------------------------------------------------------------- 1 | = Free trial broker on cloud 2 | 3 | You can connect to the broker `async-mqtt.redboltz.net` for testing. 4 | 5 | |=== 6 | |port|protocol|client_cli.sh access 7 | 8 | |1883|MQTT on TCP|./client_cli.sh --host async-mqtt.redboltz.net --port 1883 --protocol mqtt 9 | |8883|MQTT on TLS|./client_cli.sh --host async-mqtt.redboltz.net --port 8883 --protocol mqtts 10 | |10080|MQTT on Websocket|./client_cli.sh --host async-mqtt.redboltz.net --port 10080 --protocol ws 11 | |10443|MQTT on Websocket(TLS)|./client_cli.sh --host async-mqtt.redboltz.net --port 10443 --protocol wss 12 | |=== 13 | 14 | == Important notice 15 | 16 | You are free to use it for any application, but please do not abuse or rely upon it for anything of importance. This server runs on an very low spec vps. It is not intended to demonstrate any performance characteristics. 17 | Please don't publish anything sensitive, anybody could be listening. 18 | -------------------------------------------------------------------------------- /doc/mrdocs.yml: -------------------------------------------------------------------------------- 1 | # Copyright Takatoshi Kondo 2024 2 | # 3 | # Distributed under the Boost Software License, Version 1.0. 4 | # (See accompanying file LICENSE_1_0.txt or copy at 5 | # http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | # Input 8 | source-root: .. 9 | input: 10 | # Directories that contain documented source files 11 | include: 12 | - ../include 13 | # Patterns to filter out the source-files in the directories 14 | file-patterns: 15 | - '*.hpp' 16 | 17 | # Filters 18 | filters: 19 | symbols: 20 | exclude: 21 | - 'std::*' 22 | - 'boost::system' 23 | - 'boost::system::*' 24 | - 'boost::asio' 25 | - 'boost::asio::*' 26 | include: 27 | - 'async_mqtt::client' 28 | - 'async_mqtt::endpoint' 29 | - 'async_mqtt::basic_endpoint' 30 | - 'async_mqtt::layer_customize' 31 | - 'async_mqtt::protocol' 32 | inaccessible-members: never 33 | inaccessible-bases: never 34 | 35 | # Generator 36 | generate: adoc 37 | base-url: https://www.github.com/redboltz/async_mqtt/blob/main/include/ 38 | 39 | # Style 40 | verbose: true 41 | multipage: true 42 | 43 | cmake: '-D CMAKE_CXX_STANDARD=17 -D ASYNC_MQTT_BUILD_MRDOCS=ON' 44 | -------------------------------------------------------------------------------- /doc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "@antora/cli": "3.1.3", 4 | "@antora/site-generator": "3.1.3", 5 | "antora": "3.1.3" 6 | }, 7 | "dependencies": { 8 | "@cppalliance/antora-cpp-reference-extension": "^0.0.5", 9 | "@cppalliance/antora-cpp-tagfiles-extension": "^0.0.4", 10 | "@cppalliance/asciidoctor-boost-links": "^0.0.2", 11 | "@antora/expand-path-helper": "^2.0.0", 12 | "@antora/lunr-extension": "^1.0.0-alpha.8", 13 | "@asciidoctor/tabs": "^1.0.0-beta.3" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /docker/bench.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | TAG=latest 3 | if [[ "$#" -ne 0 && "$1" != -* ]] ; 4 | then 5 | TAG=$1 6 | shift 7 | fi 8 | echo "tag $TAG is used" 9 | docker pull redboltz/async_mqtt:$TAG 10 | docker run -v $PWD/conf:/var/async_mqtt_build/tool/conf --add-host=host.docker.internal:host-gateway -it redboltz/async_mqtt:$TAG ../bench $@ 11 | -------------------------------------------------------------------------------- /docker/broker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | TAG=latest 3 | if [[ "$#" -ne 0 && "$1" != -* ]] ; 4 | then 5 | TAG=$1 6 | shift 7 | fi 8 | echo "tag $TAG is used" 9 | docker pull redboltz/async_mqtt:$TAG 10 | docker run -v $PWD/conf:/var/async_mqtt_build/tool/conf -p 1883:1883 -p 8883:8883 -p 10080:10080 -p 10443:10443 -it redboltz/async_mqtt:$TAG ../broker $@ 11 | -------------------------------------------------------------------------------- /docker/client_cli.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | TAG=latest 3 | if [[ "$#" -ne 0 && "$1" != -* ]] ; 4 | then 5 | TAG=$1 6 | shift 7 | fi 8 | echo "tag $TAG is used" 9 | docker pull redboltz/async_mqtt:$TAG 10 | docker run -v $PWD/conf:/var/async_mqtt_build/tool/conf --add-host=host.docker.internal:host-gateway -it redboltz/async_mqtt:$TAG ../client_cli $@ 11 | -------------------------------------------------------------------------------- /docker/conf/broker.conf: -------------------------------------------------------------------------------- 1 | # Default configuration for async_mqtt Broker 2 | # print program options 3 | silent=false 4 | # log severity 0:fatal, 1:error, 2:warning, 3:info, 4:debug, 5:trace 5 | verbose=1 6 | # Log is colored by level 7 | colored_log=true 8 | # for TLS 9 | certificate=server.crt.pem 10 | private_key=server.key.pem 11 | # for Client Certificate Verification 12 | verify_file=cacert.pem 13 | # for MQTT auth 14 | auth_file=auth.json 15 | 16 | # 0 means automatic 17 | # Num of vCPU 18 | iocs=0 19 | 20 | # 0 means automatic 21 | # min(4 or Num of vCPU) 22 | threads_per_ioc=0 23 | 24 | # Fixed CPU core mapping by ioc 25 | # When set true, ioc index is mapped to core 26 | # e.g. if thread0,1,2,3 mapped ioc0 then they are 27 | # mapped to core0 28 | # Normally, set false is recommended. 29 | # OS doing well. 30 | fixed_core_map=false 31 | 32 | # Socket config (underlying layer) 33 | # tcp_no_delay=true 34 | # send_buf_size=131072 35 | # recv_buf_size=16384 36 | 37 | # Library Internal behavior 38 | # bulk_write=false 39 | # read_buf_size=65536 40 | 41 | 42 | # allocator config 43 | # recycling_allocator=true 44 | 45 | # Configuration for TCP 46 | [tcp] 47 | port=1883 48 | 49 | # Configuration for TLS 50 | [tls] 51 | port=8883 52 | 53 | # Configuration for Websocket 54 | [ws] 55 | port=10080 56 | 57 | # Configuration for Websocket with TLS 58 | [wss] 59 | port=10443 60 | -------------------------------------------------------------------------------- /docker/conf/cacert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDAzCCAeugAwIBAgIUU03m5DevP1EHB/mDSdiWnesMIDwwDQYJKoZIhvcNAQEL 3 | BQAwETEPMA0GA1UEAwwGcm9vdGNhMB4XDTIwMDkyOTAyMTcxNFoXDTQ4MDIxNTAy 4 | MTcxNFowETEPMA0GA1UEAwwGcm9vdGNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A 5 | MIIBCgKCAQEA2Avsj2Y0lzsLmM5jrND1/EmpKTNhYlNITsvsk0Pq43zVLJkLs3JH 6 | DfEmmOnICdibniqpvbzX4i5aKM3V83iBsKIXBXVEf5+0lPwYbhgNZK5VfskP2jw0 7 | epH6hlj03S/DlszZtS9MsGabWCkWN0wpEKAk39wW90Flr6AKpg4bXnEcBDG+k04y 8 | PfhUjNvamhThjrsGYrMBg/EUmvqxhirUxq862zjD3rgOGOepm0NCEDmNwvlKXDA8 9 | SN7aZMO8ZO+/R8JiJBOb2Q3XUYVXJt7erxrHt0AZ5JpkYZscPZeEYHEKf0xnxq0e 10 | C2W9h0OWeKr6/7gTY0Vvc1gy5ff8JDgFbwIDAQABo1MwUTAdBgNVHQ4EFgQUhZUL 11 | PUzCqzmAXn+NjfAIB4grCo0wHwYDVR0jBBgwFoAUhZULPUzCqzmAXn+NjfAIB4gr 12 | Co0wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAQd6INt2vReUr 13 | 8NKde+W36JLbRxMR6rmbljS6MpqUTIcqw9htNQpv+/zi+FUcyFjaS8gF4e3eHDs2 14 | lssGL9tnP3OPUzsHpqaqjHbcghg+9l9WmLjV5x3zsYiW9qkdnd7UH+2s559J8xP9 15 | HsNALP2mtdre0p4nzW9Wa5srvLTYIwfZP2IJbp1JlYfBzBZ2DIddI9D+RIQY4Ban 16 | /Zts58FYjivtn9z5jN+RQ/z5BUiQdkuxqZG0R6syfrvorqgTlzEIzrwlWIlsqNFl 17 | 3IrtRIAjd1U9D8P4xzHj/3kQyRcUXmNlq6npod+bZdx1/xF33LR343KZfv0c01C6 18 | K4ngI65jVQ== 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /docker/conf/cli.conf: -------------------------------------------------------------------------------- 1 | ## connection settings 2 | 3 | # hostname or IP address of the target broker 4 | host=localhost 5 | 6 | # MQTT typical port is 1883. MQTTS typical port is 8883 7 | port=1883 8 | 9 | # mqtt, mqtts, ws, or wss 10 | protocol=mqtt 11 | 12 | # v3.1.1 or v5 13 | mqtt_version=v5 14 | 15 | # MQTT username for all clients 16 | #usermane=user1 17 | 18 | # MQTT password for all clients 19 | #password=mypassword 20 | 21 | # MQTT Client Identifier. 22 | #client_id=cid1 23 | 24 | # MQTT CleanStart(v5) CleanSession(v3.1.1). true or false 25 | clean_start=true 26 | 27 | # CA certificate file. it is used only protocol mqtts and wss 28 | #verify_file=cacert.pem 29 | 30 | # Client Certificate (chain) file 31 | #certificate=client.crt.pem 32 | 33 | # Client Certificate key file 34 | #private_key=client.key.pem 35 | 36 | # Web-Scoket path. it is used only protocol ws and wss 37 | #ws_path=/ 38 | 39 | # MQTT v5 Session Expiry Interval (seconds) 40 | sei=0 41 | 42 | # log level. 0 to 5. fatal, error, warning, info, debug, and trace 43 | # 0 1 2 3 4 5 44 | verbose=2 45 | # Log is colored by level 46 | colored_log=true 47 | -------------------------------------------------------------------------------- /docker/conf/client.crt.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDcTCCAlmgAwIBAgIUQ1J1bxX3IoBolCv6kfpckYag7WYwDQYJKoZIhvcNAQEL 3 | BQAwETEPMA0GA1UEAwwGcm9vdGNhMB4XDTIxMDUyMTEwMTAzNFoXDTQ4MTAwNjEw 4 | MTAzNFowDzENMAsGA1UEAwwEY2lkMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC 5 | AQoCggEBAKkTZadltzY+ylAIap6AoFtEE137ZxU1rItTcAhOMeEpCL1w1Wdxm6oo 6 | setmjnnX+0asS8V6niRfFGr08CMbRWPwEoNcfb8YSidgmSOF2OW+aay9A7R99H/i 7 | c+OAa1KO0laEoBl4cYKl976gwrooFu4wznYCXAPzUrOLQxAWY+vbUnYJHfLBiXdp 8 | 4/b/6bdNV5Ot3/ZpzaKayEozvXjL1DJrQq+vL9+avOHKG+h+Smh1d4SogcNENvsn 9 | /73Cw7PGnXb8niguxd6vjjFfe4F1SbRBxU9WBtcQxBHbJPxRU2JEA2QtxmU9th/T 10 | 3RCUsPoxbwPL0k5DaajURrtXpotDk7MCAwEAAaOBwjCBvzBMBgNVHSMERTBDgBSF 11 | lQs9TMKrOYBef42N8AgHiCsKjaEVpBMwETEPMA0GA1UEAwwGcm9vdGNhghRTTebk 12 | N68/UQcH+YNJ2Jad6wwgPDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIFoDATBgNVHSUE 13 | DDAKBggrBgEFBQcDAjAxBglghkgBhvhCAQ0EJBYiT3BlblNTTCBDZXJ0aWZpY2F0 14 | ZSBmb3IgU1NMIENsaWVudDAPBgNVHREECDAGggRjaWQxMA0GCSqGSIb3DQEBCwUA 15 | A4IBAQAX9VAlG6wfBJpKUY1lxui2nTfk0JsYY+6enc+/G8WNNL1fobeJUwCKzdTQ 16 | SQPzg4qYpxbqV1qn4X3cQfHXvdgvVfWUNYH9eGnKLe6PH/e1F/qC5T7G2SFe4uQ9 17 | VOOHt4R9zOX6BuYCfwTKwt0+dbLuR7RONzM8MIzfCdbbfOvmcvq6+9vS5WrHgxGE 18 | dzCM8B7hp0DTtpTEAFnXDCPTViN1QCTmfTGvEDIgMRI8xXB20oCN/SEUtxJ4vleu 19 | dpjLJIXPrbzXKB8czmLFCJg3tOgRqRi9BtT4+IR8THqq/SFWRCp3C9JsZipgnwu5 20 | HqX8HmgF0F09RZMKRACwhZXF9ELA 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /docker/conf/client.key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEAqRNlp2W3Nj7KUAhqnoCgW0QTXftnFTWsi1NwCE4x4SkIvXDV 3 | Z3Gbqiix62aOedf7RqxLxXqeJF8UavTwIxtFY/ASg1x9vxhKJ2CZI4XY5b5prL0D 4 | tH30f+Jz44BrUo7SVoSgGXhxgqX3vqDCuigW7jDOdgJcA/NSs4tDEBZj69tSdgkd 5 | 8sGJd2nj9v/pt01Xk63f9mnNoprISjO9eMvUMmtCr68v35q84cob6H5KaHV3hKiB 6 | w0Q2+yf/vcLDs8addvyeKC7F3q+OMV97gXVJtEHFT1YG1xDEEdsk/FFTYkQDZC3G 7 | ZT22H9PdEJSw+jFvA8vSTkNpqNRGu1emi0OTswIDAQABAoIBAEbgU7/NuvTpc4QD 8 | UzaosxAvRHMkXX0dp/wr+Q3yQaSiwAAyGbOog1ncf2Ev99AKA1MIDSd2lG6o0PVZ 9 | QoVk/Dy9ufUJQ8lk1EkXjHrAtEDzBnecML5sAp/NfUlEXzkXmAMey8KBpAvhqS5n 10 | U9oXzi0BlrsPmCUrzmJnobBPwolvE83OR0zTQKbRBzH26PStYgFnDolJmexFHAAh 11 | q1if+JgwosTYliXtzB4SOF1+psMjGDX8SLYHaInIfvAVrJTx9Y/1ykk1102Oak5h 12 | v3qAV5QW3qG8709EU5iFWfmwwaOJcttN7FlZ9GptyssPLkOFF6pmgqDdSvz+FG86 13 | Qj1pw7kCgYEA2h5bQFp2IcxZKeeM5ouwlwt1AhOMBdkAy9QAXmg7exro0fQbI6px 14 | g6JbB7aTDqCRfq1tjlix2wkFjEu+vsGifg/JifRpBa9FO5qiunuXjIn73Vu5zoEU 15 | cCv/0y/abCFjuAeJ5VQdeIs6SKC5WZN6UTtmgA+eVkPIFphvqoB7RDUCgYEAxnCT 16 | pKGsQRlxYB7qpAQvBgBogI0vD7weIosKEYZfFJeKPXf2O+mI4l2hlGXi9N75Hwax 17 | Wen8+4TXMw9sSyTKPlcmdbCNRKGHc+TjjnNURofVVcLqyn/6Ht6DsgvgqYuZKiKl 18 | PiwUrcS8ay1aTwlHKk+tJV+3S1a5jykwhc5YJUcCgYEAr1yMnNad91plrU0eeRSB 19 | 604oynyQrPrkqvtNOJmwiK7/1Bzf3PLhxKU5bqAY5z+s+h3Q4QrqI2HDdiJHvvHL 20 | BHMI48L+1LUvglY20psfIrylJDjkz+PzXKPjUBU/FIRbuc9FzHyuHQZC27Vsj1oE 21 | k16gcAEemdhw+8merYQSlqkCgYB5Jwo9HSfZpvr9QGLpOFStSVqEAa6V4LhVRqYj 22 | BPLP06Vm2fLPqUkVSyz3OS1Taz6VnrRwvNbjiLsKRYRMbG29md+1QtE88ZGNRFVa 23 | BzeQyCWLcrF+aJwAdMHa1j2Xxc8BVp2kU61cWhzfIpVcY8G7J2ICy2lQ6eXobbFe 24 | QBi4yQKBgH0yOAUk3vC5FVaFvFzohJ8yFM9OjwrSuoaAKHFtRroAUgBtX1dTRSKg 25 | /GzeJdsA0vH4bfZKKxaFgRo+RfAi9s6ZmxBQWf6MgB1PlU1IWNVYqBceZZ97j7Ln 26 | wscsOgt0Sa7CPpE3Ww8P6dX3leH1/uRYgAC97p61h+rXVPHTIgl0 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /docker/conf/server.crt.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDUjCCAjqgAwIBAgIUQ1J1bxX3IoBolCv6kfpckYag7WUwDQYJKoZIhvcNAQEL 3 | BQAwETEPMA0GA1UEAwwGcm9vdGNhMB4XDTIxMDUyMTEwMTAxOVoXDTQ4MTAwNjEw 4 | MTAxOVowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOC 5 | AQ8AMIIBCgKCAQEArhWwTP0YY40Dc9xgLHvy4rm0NLM2JJvqQJcVryfQb3SIisYx 6 | KQx41biCzOyFE+5/ZO0VLSKUD7QdOAZIaARVzWSgNuOSj5ed0IAsBKkEOF/1oozn 7 | ww0efPNM51ahy1heG0pLeRBPeyHPRyvAOsVYgmkdkxnOFAFPl/rPYgmYAW7SWfvx 8 | V6kI7DLfo50MpohqGFiPnvwpXtLTMH9Wl/ChA0XGDSFyqZC1PI9EtWCkw6nwiauV 9 | F/8/p8HNJ9+Mq5MmdKmHaLsrddy07nIvg3lShYWXevRVi1vK1fLIHYrU6jYNpY3I 10 | 3X0C97Y2sa61MceIRy3Eum7PVH06gtwUjIreGQIDAQABo4GeMIGbMEwGA1UdIwRF 11 | MEOAFIWVCz1Mwqs5gF5/jY3wCAeIKwqNoRWkEzARMQ8wDQYDVQQDDAZyb290Y2GC 12 | FFNN5uQ3rz9RBwf5g0nYlp3rDCA8MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgQwMB0G 13 | A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAUBgNVHREEDTALgglsb2NhbGhv 14 | c3QwDQYJKoZIhvcNAQELBQADggEBAEKKkTIxtVUrRyT+9RspolZdheK9dWqPGQCP 15 | mDKnHON8nhK2VGUgqEBwQOU9tHsluimQY3XhQowEsOFLV1dgIt4fdUuHDheCD1RI 16 | wkDdO/d/dZDk83ViuRFiPyZsRmVXIR49QkXQsvh8/q6EG9peVCiPlxLJE5n3ITa9 17 | P9019WJ16BMrVaJqQHI5kYLGIFrb2HD0SUdQj0ORr0mwsGdZCk3Y08d92Wgicgg+ 18 | 74Qqdl8jiZnluShUAZeUa5KvOz5SAFHePOkE8fj6klIFUcUamAKrwxaaGNUs0NXo 19 | JgUwwL3L9QVgt4dmmsNB4NEM5Kref8A+Py1WfLVetIW8t9wNWb8= 20 | -----END CERTIFICATE----- 21 | -------------------------------------------------------------------------------- /docker/conf/server.key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpAIBAAKCAQEArhWwTP0YY40Dc9xgLHvy4rm0NLM2JJvqQJcVryfQb3SIisYx 3 | KQx41biCzOyFE+5/ZO0VLSKUD7QdOAZIaARVzWSgNuOSj5ed0IAsBKkEOF/1oozn 4 | ww0efPNM51ahy1heG0pLeRBPeyHPRyvAOsVYgmkdkxnOFAFPl/rPYgmYAW7SWfvx 5 | V6kI7DLfo50MpohqGFiPnvwpXtLTMH9Wl/ChA0XGDSFyqZC1PI9EtWCkw6nwiauV 6 | F/8/p8HNJ9+Mq5MmdKmHaLsrddy07nIvg3lShYWXevRVi1vK1fLIHYrU6jYNpY3I 7 | 3X0C97Y2sa61MceIRy3Eum7PVH06gtwUjIreGQIDAQABAoIBAFvo9YjgQ4UjyUPd 8 | gSVbV5Qeqab9S0Ou0dHCMt+kLKb7pq9mDkR24kEsRlq9MVGhpL77cSfATt2voZGX 9 | t5i7WTW0v+Xa5uFLEjYnxZW8So8dEsn8jMxtW8BqkBq/oXKDuEO+SPSlCOGgqxgP 10 | YFFnKeDIcKXehPAI9SXvdJh1Kjzuj9K81QfYDDbc30424p5qotW8F1ldJN6T709R 11 | DqKttvLPO1lsr43kjMLwT5pbpdvFS4H2TweeC4y/woM6LUKehlMPVO39aop0MOfF 12 | aGQj0OGjAfhfmjVvG1DGT++sdO5+CaRAUj7XDAX7y7fELCbovrQqKnxBeCg4Z6yF 13 | zkicDwUCgYEA1LYJ8EeR83I1uuo18eZvebQYTIukoFVdHYBqTO+SiP4cot0p8UrX 14 | rkGPDrM5Hhl20n6tWR20CImEDbkKuEHX9IwwxJJwAqg5M1UbHtW0re3eLQeBn5GW 15 | JP2mfjK6ffTWuOcqXzt6VhRnIqLk1TacQSKxXD3FmSn17/tZ53jRptMCgYEA0YNE 16 | pCNxxLqBFuF46gr/z7lSLk3iNqe/Xw4uwXa8JeGdyHfI+bvqRm1xOnrJhlvAONL2 17 | 8lq/y1Ye6m8SBxDHco92GuSov4WQL45MjO1lEx3/xe6lVdo27huzyG0wiD27MQGV 18 | PR011JqB+cnZVM4Nj3rG87JLQr8AAgnAHIfXq+MCgYBJwFBT2kzVjtzoUPqhQ9eU 19 | 6Aegyq4q1U4yw2qYAFzbWNgO9AXt3phHl/2FCEkekY+sTjXGd1ELwLpjk6wO1O2O 20 | oejqzyc9FJy4mqKLn2dFAvuMu1SLQgxACR5oFSiqMXEdrTD40gOJwws7bCVRc9zb 21 | jK7YH6bagzz9lzXF1xNB9wKBgQCRTpZztHV6ONPBF72xrNFAs0ow/SlQOMV8WqzI 22 | 1t2k9DZnS9Sih9by44KtSW2tdsL5Zi+JZLEyiFdGxqPdLKD3blI+UqpKsoqOwQWM 23 | lDUOrjavg1U+FusT9ziYYEpRo2bJlUx5J2InQsW0hW7q50H2afPEHrsd3rRVtYd9 24 | AiXtewKBgQC3z+7k6av30wvnStXWKTb4utPmvhAU+T8iXOM/3nq83S+OMArcAX9b 25 | 5xcccDK9iy1s7MnLrA2NIJwmKCOk0OMcxWLHLyyC5X2tOc0uVGZau4aF4HsI63O6 26 | eVP9RpwPSu8vMOZf4SWNlcv5iq/zH1KFW5wR/JNTAwYf0xgyb+rgYA== 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /docker/create_image/Dockerfile: -------------------------------------------------------------------------------- 1 | Dockerfile.ubuntu -------------------------------------------------------------------------------- /docker/create_image/Dockerfile.ubuntu: -------------------------------------------------------------------------------- 1 | FROM ubuntu 2 | RUN apt-get upgrade -y \ 3 | && apt-get update -y \ 4 | && apt-get install wget -y \ 5 | && apt-get install git -y \ 6 | && apt-get install cmake -y \ 7 | && apt-get remove --purge g++ -y\ 8 | && apt-get remove --purge gcc -y\ 9 | && apt-get install gcc-12 -y \ 10 | && apt-get install g++-12 -y \ 11 | && update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 1 \ 12 | && update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 1 \ 13 | && apt-get install clang -y \ 14 | && apt-get install libssl-dev -y \ 15 | && apt-get install bzip2 -y \ 16 | && apt-get clean -y 17 | RUN wget https://archives.boost.io/release/1.85.0/source/boost_1_85_0.tar.bz2 \ 18 | && tar xf boost_1_85_0.tar.bz2 \ 19 | && cd boost_1_85_0 \ 20 | && ./bootstrap.sh \ 21 | && ./b2 link=static,shared address-model=64 install \ 22 | && cd .. \ 23 | && rm -rf boost_1_85_0 boost_1_85_0.tar.bz2 24 | RUN mkdir -p /var/async_mqtt 25 | 26 | WORKDIR /var 27 | ARG ASYNC_MQTT_VERSION 28 | RUN git clone https://github.com/redboltz/async_mqtt.git -b ${ASYNC_MQTT_VERSION} \ 29 | && mkdir async_mqtt_build \ 30 | && cd async_mqtt_build \ 31 | && cmake \ 32 | -DCMAKE_CXX_COMPILER=clang++ \ 33 | -DCMAKE_BUILD_TYPE=Release \ 34 | -DCMAKE_CXX_FLAGS="-std=c++17 -O3" \ 35 | -DASYNC_MQTT_USE_TLS=ON \ 36 | -DASYNC_MQTT_USE_WS=ON \ 37 | -DASYNC_MQTT_USE_LOG=ON \ 38 | -DASYNC_MQTT_BUILD_TOOLS=ON \ 39 | /var/async_mqtt \ 40 | && cmake --build . --target broker bench client_cli \ 41 | && rm -rf `find . -name "*.o"` 42 | WORKDIR /var/async_mqtt_build/tool/conf 43 | -------------------------------------------------------------------------------- /example/locked_cout.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2019 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_LOCKED_COUT_HPP) 8 | #define ASYNC_MQTT_LOCKED_COUT_HPP 9 | 10 | #include 11 | #include 12 | 13 | class locked_stream { 14 | public: 15 | locked_stream(std::ostream& stream) 16 | :lock_(mtx_), 17 | stream_(stream) {} 18 | 19 | friend 20 | locked_stream&& operator<<(locked_stream&& s, std::ostream& (*arg)(std::ostream&)) { 21 | s.stream_ << arg; 22 | return std::move(s); 23 | } 24 | 25 | template 26 | friend 27 | locked_stream&& operator<<(locked_stream&& s, Arg&& arg) { 28 | s.stream_ << std::forward(arg); 29 | return std::move(s); 30 | } 31 | 32 | private: 33 | static std::mutex mtx_; 34 | std::unique_lock lock_; 35 | std::ostream& stream_; 36 | 37 | }; 38 | 39 | std::mutex locked_stream::mtx_{}; 40 | 41 | inline 42 | locked_stream locked_cout() { 43 | return locked_stream(std::cout); 44 | } 45 | 46 | #endif // ASYNC_MQTT_LOCKED_COUT_HPP 47 | -------------------------------------------------------------------------------- /example/separate_client/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(separate_client) 2 | 3 | add_executable( 4 | separate_client 5 | main.cpp 6 | ) 7 | add_dependencies(separate_client async_mqtt_asio_bind async_mqtt_protocol) 8 | 9 | # Without this setting added, azure pipelines completely fails to find the boost libraries. No idea why. 10 | if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") 11 | LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) 12 | endif() 13 | 14 | target_link_libraries(separate_client PRIVATE async_mqtt_iface async_mqtt_asio_bind async_mqtt_protocol) 15 | target_compile_definitions(separate_client PRIVATE ASYNC_MQTT_SEPARATE_COMPILATION) 16 | 17 | if(ASYNC_MQTT_USE_LOG) 18 | target_compile_definitions( 19 | separate_client 20 | PRIVATE 21 | $,,BOOST_LOG_DYN_LINK> 22 | ) 23 | target_link_libraries( 24 | separate_client PRIVATE Boost::log Boost::log_setup 25 | ) 26 | endif() 27 | 28 | target_compile_definitions( 29 | separate_client 30 | PRIVATE 31 | $,,BOOST_PROGRAM_OPTIONS_DYN_LINK> 32 | ) 33 | -------------------------------------------------------------------------------- /example/separate_client_manual/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(separate_client_manual) 2 | 3 | add_executable( 4 | separate_client_manual 5 | src.cpp 6 | main.cpp 7 | ) 8 | 9 | # Without this setting added, azure pipelines completely fails to find the boost libraries. No idea why. 10 | if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") 11 | LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) 12 | endif() 13 | 14 | target_compile_definitions(separate_client_manual PRIVATE ASYNC_MQTT_SEPARATE_COMPILATION) 15 | 16 | if(ASYNC_MQTT_USE_LOG) 17 | target_compile_definitions( 18 | separate_client_manual 19 | PRIVATE 20 | $,,BOOST_LOG_DYN_LINK> 21 | ) 22 | target_link_libraries( 23 | separate_client_manual PRIVATE async_mqtt_iface Boost::log Boost::log_setup 24 | ) 25 | endif() 26 | 27 | target_compile_definitions( 28 | separate_client_manual 29 | PRIVATE 30 | $,,BOOST_PROGRAM_OPTIONS_DYN_LINK> 31 | ) 32 | -------------------------------------------------------------------------------- /example/separate_client_manual/src.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2023 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | // example: overriding custom instantiate configuration 8 | #define ASYNC_MQTT_PP_ROLE (async_mqtt::role::client) 9 | #define ASYNC_MQTT_PP_SIZE (2) 10 | #define ASYNC_MQTT_PP_PROTOCOL (async_mqtt::protocol::mqtt) 11 | 12 | #include 13 | #include 14 | -------------------------------------------------------------------------------- /example/separate_endpoint/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(separate_endpoint) 2 | 3 | add_executable( 4 | separate_endpoint 5 | main.cpp 6 | ) 7 | add_dependencies(separate_endpoint async_mqtt_asio_bind async_mqtt_protocol) 8 | 9 | # Without this setting added, azure pipelines completely fails to find the boost libraries. No idea why. 10 | if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") 11 | LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) 12 | endif() 13 | 14 | target_link_libraries(separate_endpoint PRIVATE async_mqtt_iface async_mqtt_asio_bind async_mqtt_protocol) 15 | target_compile_definitions(separate_endpoint PRIVATE ASYNC_MQTT_SEPARATE_COMPILATION) 16 | 17 | if(ASYNC_MQTT_USE_LOG) 18 | target_compile_definitions( 19 | separate_endpoint 20 | PRIVATE 21 | $,,BOOST_LOG_DYN_LINK> 22 | ) 23 | target_link_libraries( 24 | separate_endpoint PRIVATE Boost::log Boost::log_setup 25 | ) 26 | endif() 27 | 28 | target_compile_definitions( 29 | separate_endpoint 30 | PRIVATE 31 | $,,BOOST_PROGRAM_OPTIONS_DYN_LINK> 32 | ) 33 | -------------------------------------------------------------------------------- /example/separate_endpoint_manual/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(separate_endpoint_manual) 2 | 3 | add_executable( 4 | separate_endpoint_manual 5 | src.cpp 6 | main.cpp 7 | ) 8 | 9 | # Without this setting added, azure pipelines completely fails to find the boost libraries. No idea why. 10 | if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") 11 | LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) 12 | endif() 13 | 14 | target_compile_definitions(separate_endpoint_manual PRIVATE ASYNC_MQTT_SEPARATE_COMPILATION) 15 | 16 | if(ASYNC_MQTT_USE_LOG) 17 | target_compile_definitions( 18 | separate_endpoint_manual 19 | PRIVATE 20 | $,,BOOST_LOG_DYN_LINK> 21 | ) 22 | target_link_libraries( 23 | separate_endpoint_manual PRIVATE async_mqtt_iface Boost::log Boost::log_setup 24 | ) 25 | endif() 26 | 27 | target_compile_definitions( 28 | separate_endpoint_manual 29 | PRIVATE 30 | $,,BOOST_PROGRAM_OPTIONS_DYN_LINK> 31 | ) 32 | -------------------------------------------------------------------------------- /example/separate_endpoint_manual/src.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2023 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | // example: overriding custom instantiate configuration 8 | #define ASYNC_MQTT_PP_ROLE (async_mqtt::role::client) 9 | #define ASYNC_MQTT_PP_SIZE (2) 10 | #define ASYNC_MQTT_PP_PROTOCOL (async_mqtt::protocol::mqtt) 11 | 12 | #include 13 | #include 14 | -------------------------------------------------------------------------------- /example/separate_protocol/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(separate_protocol) 2 | 3 | add_executable( 4 | separate_protocol 5 | main.cpp 6 | ) 7 | add_dependencies(separate_protocol async_mqtt_protocol) 8 | 9 | # Without this setting added, azure pipelines completely fails to find the boost libraries. No idea why. 10 | if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") 11 | LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) 12 | endif() 13 | 14 | target_link_libraries(separate_protocol PRIVATE async_mqtt_iface async_mqtt_protocol) 15 | target_compile_definitions(separate_protocol PRIVATE ASYNC_MQTT_SEPARATE_COMPILATION) 16 | 17 | if(ASYNC_MQTT_USE_LOG) 18 | target_compile_definitions( 19 | separate_protocol 20 | PRIVATE 21 | $,,BOOST_LOG_DYN_LINK> 22 | ) 23 | target_link_libraries( 24 | separate_protocol PRIVATE Boost::log Boost::log_setup 25 | ) 26 | endif() 27 | 28 | target_compile_definitions( 29 | separate_protocol 30 | PRIVATE 31 | $,,BOOST_PROGRAM_OPTIONS_DYN_LINK> 32 | ) 33 | -------------------------------------------------------------------------------- /example/separate_protocol_manual/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(separate_protocol_manual) 2 | 3 | add_executable( 4 | separate_protocol_manual 5 | src.cpp 6 | main.cpp 7 | ) 8 | 9 | # Without this setting added, azure pipelines completely fails to find the boost libraries. No idea why. 10 | if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") 11 | LINK_DIRECTORIES(${Boost_LIBRARY_DIRS}) 12 | endif() 13 | 14 | target_compile_definitions(separate_protocol_manual PRIVATE ASYNC_MQTT_SEPARATE_COMPILATION) 15 | 16 | if(ASYNC_MQTT_USE_LOG) 17 | target_compile_definitions( 18 | separate_protocol_manual 19 | PRIVATE 20 | $,,BOOST_LOG_DYN_LINK> 21 | ) 22 | target_link_libraries( 23 | separate_protocol_manual PRIVATE async_mqtt_iface Boost::log Boost::log_setup 24 | ) 25 | endif() 26 | 27 | target_compile_definitions( 28 | separate_protocol_manual 29 | PRIVATE 30 | $,,BOOST_PROGRAM_OPTIONS_DYN_LINK> 31 | ) 32 | -------------------------------------------------------------------------------- /example/separate_protocol_manual/src.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2023 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | // example: overriding custom instantiate configuration 8 | #define ASYNC_MQTT_PP_ROLE (async_mqtt::role::client) 9 | #define ASYNC_MQTT_PP_SIZE (2) 10 | 11 | #include 12 | -------------------------------------------------------------------------------- /gen_all.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import os 3 | import re 4 | 5 | files = [p for p in glob.glob('**/*', root_dir='include', recursive=True) 6 | if re.search('\.(h|hpp)$', p)] 7 | 8 | print( 9 | r'''// Copyright Takatoshi Kondo 2023 10 | // 11 | // Distributed under the Boost Software License, Version 1.0. 12 | // (See accompanying file LICENSE_1_0.txt or copy at 13 | // http://www.boost.org/LICENSE_1_0.txt) 14 | 15 | #if !defined(ASYNC_MQTT_ALL_HPP) 16 | #define ASYNC_MQTT_ALL_HPP 17 | ''' 18 | ) 19 | 20 | for file in sorted(files, key=lambda file: (file, file.count('/'))): 21 | if file.find("/all.hpp") != -1: 22 | continue 23 | if file.find("/separate/") != -1: 24 | continue 25 | if file.find("/broker/") != -1: 26 | continue 27 | if file.find("/impl/") != -1: 28 | continue 29 | if file.find("/detail/") != -1: 30 | continue 31 | if file.find("/predefined_layer/") != -1 and file.find("/predefined_layer/mqtt.hpp") == -1: 32 | continue 33 | if file.find("/picosha2.h") != -1: 34 | continue 35 | print("#include <{}>".format(file)) 36 | print( 37 | r''' 38 | #endif // ASYNC_MQTT_ALL_HPP''' 39 | ) 40 | -------------------------------------------------------------------------------- /include/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_library(${PROJECT_NAME} INTERFACE) 2 | 3 | target_link_libraries(${PROJECT_NAME} INTERFACE Threads::Threads Boost::boost) 4 | 5 | if(ASYNC_MQTT_USE_STATIC_OPENSSL) 6 | # Unfortunately, cmake doesn't automatically detect that statically linked openssl 7 | # requires at least two more libs to be linked. "dl" is for dynamic library linking 8 | # and zlib is for basic compression functionality. 9 | # There is currently no way to specify statically linked zlib. 10 | target_link_libraries(${PROJECT_NAME} INTERFACE $<$:${CMAKE_DL_LIBS} ZLIB::ZLIB>) 11 | endif() 12 | 13 | target_link_libraries(${PROJECT_NAME} INTERFACE $<$:OpenSSL::SSL>) 14 | 15 | target_include_directories(${PROJECT_NAME} 16 | INTERFACE 17 | $ 18 | ) 19 | 20 | target_compile_definitions(${PROJECT_NAME} INTERFACE $<$:ASYNC_MQTT_USE_TLS>) 21 | target_compile_definitions(${PROJECT_NAME} INTERFACE $<$:ASYNC_MQTT_USE_WS>) 22 | target_compile_definitions(${PROJECT_NAME} INTERFACE $<$:ASYNC_MQTT_USE_STR_CHECK>) 23 | target_compile_definitions(${PROJECT_NAME} INTERFACE $<$:ASYNC_MQTT_USE_LOG>) 24 | target_compile_definitions(${PROJECT_NAME} INTERFACE $<$:ASYNC_MQTT_PRINT_PAYLOAD>) 25 | 26 | install(DIRECTORY . DESTINATION include FILES_MATCHING PATTERN "*.hpp" PATTERN "*.h" PATTERN "*.ipp") 27 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/client_fwd.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_CLIENT_FWD_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_CLIENT_FWD_HPP 9 | 10 | #include // for std::size_t 11 | 12 | #include 13 | #include 14 | 15 | namespace async_mqtt { 16 | 17 | /** 18 | * @brief MQTT client for casual usecases 19 | * 20 | * #### Thread Safety 21 | * @li Distinct objects: Safe 22 | * @li Shared objects: Unsafe 23 | * 24 | * #### predefined next layer types for NextLayer: 25 | * @li @ref protocol::mqtt 26 | * @li @ref protocol::mqtts 27 | * @li @ref protocol::ws 28 | * @li @ref protocol::wss 29 | * 30 | * @tparam Version MQTT protocol version. 31 | * @tparam NextLayer Just next layer for basic_endpoint. mqtt, mqtts, ws, and wss are predefined. 32 | */ 33 | template 34 | class client; 35 | 36 | } // namespace async_mqtt 37 | 38 | #endif // ASYNC_MQTT_ASIO_BIND_CLIENT_FWD_HPP 39 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/detail/client_impl_fwd.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2024 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_DETAIL_CLIENT_IMPL_FWD_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_DETAIL_CLIENT_IMPL_FWD_HPP 9 | 10 | #include 11 | 12 | namespace async_mqtt::detail { 13 | 14 | template 15 | class client_impl; 16 | 17 | } // namespace async_mqtt::detail 18 | 19 | #endif // ASYNC_MQTT_ASIO_BIND_DETAIL_CLIENT_IMPL_FWD_HPP 20 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/detail/client_packet_type_getter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2024 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_DETAIL_CLIENT_PACKET_TYPE_GETTER_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_DETAIL_CLIENT_PACKET_TYPE_GETTER_HPP 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace async_mqtt::detail { 16 | 17 | #define ASYNC_MQTT_PACKET_TYPE_GETTER(packet) \ 18 | template \ 19 | struct BOOST_PP_CAT(meta_,packet) { \ 20 | using type = v5::BOOST_PP_CAT(packet, _packet); \ 21 | }; \ 22 | template <> \ 23 | struct BOOST_PP_CAT(meta_,packet) { \ 24 | using type = v3_1_1::BOOST_PP_CAT(packet, _packet); \ 25 | }; 26 | 27 | ASYNC_MQTT_PACKET_TYPE_GETTER(connect) 28 | ASYNC_MQTT_PACKET_TYPE_GETTER(connack) 29 | ASYNC_MQTT_PACKET_TYPE_GETTER(subscribe) 30 | ASYNC_MQTT_PACKET_TYPE_GETTER(suback) 31 | ASYNC_MQTT_PACKET_TYPE_GETTER(unsubscribe) 32 | ASYNC_MQTT_PACKET_TYPE_GETTER(unsuback) 33 | ASYNC_MQTT_PACKET_TYPE_GETTER(publish) 34 | ASYNC_MQTT_PACKET_TYPE_GETTER(puback) 35 | ASYNC_MQTT_PACKET_TYPE_GETTER(pubrec) 36 | ASYNC_MQTT_PACKET_TYPE_GETTER(pubrel) 37 | ASYNC_MQTT_PACKET_TYPE_GETTER(pubcomp) 38 | ASYNC_MQTT_PACKET_TYPE_GETTER(pingreq) 39 | ASYNC_MQTT_PACKET_TYPE_GETTER(pingresp) 40 | ASYNC_MQTT_PACKET_TYPE_GETTER(disconnect) 41 | 42 | #undef ASYNC_MQTT_PACKET_TYPE_GETTER 43 | 44 | #define ASYNC_MQTT_PACKET_TYPE(version, packet) \ 45 | using BOOST_PP_CAT(packet, _packet) = typename BOOST_PP_CAT(detail::meta_, packet::type); 46 | 47 | } // namespace async_mqtt::detail 48 | 49 | #endif // ASYNC_MQTT_ASIO_BIND_DETAIL_CLIENT_PACKET_TYPE_GETTER_HPP 50 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/detail/endpoint_impl_fwd.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_DETAIL_ENDPOINT_IMPL_FWD_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_DETAIL_ENDPOINT_IMPL_FWD_HPP 9 | 10 | #include // for std::size_t 11 | #include 12 | 13 | namespace async_mqtt::detail { 14 | 15 | template 16 | class basic_endpoint_impl; 17 | 18 | } // namespace async_mqtt::detail 19 | 20 | #endif // ASYNC_MQTT_ASIO_BIND_DETAIL_ENDPOINT_IMPL_FWD_HPP 21 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/detail/stream_layer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_DETAIL_STREAM_LAYER_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_DETAIL_STREAM_LAYER_HPP 9 | 10 | #include 11 | 12 | namespace async_mqtt::detail { 13 | 14 | template 15 | std::false_type has_next_layer_impl(void*); 16 | 17 | template 18 | auto has_next_layer_impl(decltype(nullptr)) -> 19 | decltype(std::declval().next_layer(), std::true_type{}); 20 | 21 | template 22 | using has_next_layer = decltype(has_next_layer_impl(nullptr)); 23 | 24 | 25 | template::value> 26 | struct lowest_layer_type_impl { 27 | using type = typename std::remove_reference::type; 28 | }; 29 | 30 | template 31 | struct lowest_layer_type_impl { 32 | using type = typename lowest_layer_type_impl< 33 | decltype(std::declval().next_layer())>::type; 34 | }; 35 | 36 | template 37 | using lowest_layer_type = typename lowest_layer_type_impl::type; 38 | 39 | template 40 | T& 41 | get_lowest_layer_impl(T& t, std::false_type) noexcept { 42 | return t; 43 | } 44 | 45 | template 46 | lowest_layer_type& 47 | get_lowest_layer_impl(T& t, std::true_type) noexcept { 48 | return 49 | get_lowest_layer_impl( 50 | t.next_layer(), 51 | has_next_layer::type>{} 52 | ); 53 | } 54 | 55 | template 56 | lowest_layer_type& get_lowest_layer(T& t) noexcept { 57 | return 58 | detail::get_lowest_layer_impl( 59 | t, 60 | has_next_layer{} 61 | ); 62 | } 63 | 64 | } // namespace async_mqtt::detail 65 | 66 | 67 | #endif // ASYNC_MQTT_ASIO_BIND_DETAIL_STREAM_LAYER_HPP 68 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/endpoint_fwd.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_ENDPOINT_FWD_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_ENDPOINT_FWD_HPP 9 | 10 | #include // for std::size_t 11 | 12 | #include 13 | 14 | namespace async_mqtt { 15 | 16 | /** 17 | * @brief MQTT endpoint corresponding to the connection 18 | * 19 | * #### Thread Safety 20 | * @li Distinct objects: Safe 21 | * @li Shared objects: Unsafe 22 | * 23 | * #### predefined next layer types for NextLayer: 24 | * @li @ref protocol::mqtt 25 | * @li @ref protocol::mqtts 26 | * @li @ref protocol::ws 27 | * @li @ref protocol::wss 28 | * 29 | * @tparam Role role for packet sendable checking 30 | * @tparam PacketIdBytes MQTT spec is 2. You can use `endpoint` for that. 31 | * @tparam NextLayer Just next layer for basic_endpoint. mqtt, mqtts, ws, and wss are predefined. 32 | */ 33 | template 34 | class basic_endpoint; 35 | 36 | /** 37 | * @brief Type alias for @ref basic_endpoint with PacketIdBytes set to 2. 38 | * This is for typical use cases (e.g., MQTT client). 39 | * 40 | * #### Thread Safety 41 | * @li Distinct objects: Safe 42 | * @li Shared objects: Unsafe 43 | * 44 | * @tparam Role role for packet sendable checking 45 | * @tparam NextLayer Just next layer for basic_endpoint. mqtt, mqtts, ws, and wss are predefined. 46 | */ 47 | template 48 | using endpoint = basic_endpoint; 49 | 50 | } // namespace async_mqtt 51 | 52 | #endif // ASYNC_MQTT_ASIO_BIND_ENDPOINT_FWD_HPP 53 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/filter.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_FILTER_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_FILTER_HPP 9 | 10 | namespace async_mqtt { 11 | 12 | /** 13 | * @brief receive packet filter 14 | */ 15 | enum class filter { 16 | match, ///< matched control_packet_type is target 17 | except ///< no matched control_packet_type is target 18 | }; 19 | 20 | } // namespace async_mqtt 21 | 22 | #endif // ASYNC_MQTT_ASIO_BIND_FILTER_HPP 23 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/impl/client_acquire_unique_packet_id.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_ACQUIRE_UNIQUE_PACKET_ID_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_ACQUIRE_UNIQUE_PACKET_ID_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace async_mqtt { 14 | 15 | template 16 | template 17 | auto 18 | client::async_acquire_unique_packet_id( 19 | CompletionToken&& token 20 | ) { 21 | BOOST_ASSERT(impl_); 22 | return 23 | as::async_initiate< 24 | CompletionToken, 25 | void(error_code, packet_id_type) 26 | >( 27 | []( 28 | auto handler, 29 | std::shared_ptr impl 30 | ) { 31 | impl_type::async_acquire_unique_packet_id( 32 | force_move(impl), 33 | force_move(handler) 34 | ); 35 | }, 36 | token, 37 | impl_ 38 | ); 39 | } 40 | 41 | // sync version 42 | 43 | template 44 | inline 45 | std::optional 46 | client::acquire_unique_packet_id() { 47 | BOOST_ASSERT(impl_); 48 | return impl_->acquire_unique_packet_id(); 49 | } 50 | 51 | } // namespace async_mqtt 52 | 53 | #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) 54 | #include 55 | #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) 56 | 57 | #endif // ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_ACQUIRE_UNIQUE_PACKET_ID_HPP 58 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/impl/client_acquire_unique_packet_id.ipp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_IMPL_CLIENT_ACQUIRE_UNIQUE_PACKET_ID_IPP) 8 | #define ASYNC_MQTT_IMPL_CLIENT_ACQUIRE_UNIQUE_PACKET_ID_IPP 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace async_mqtt::detail { 15 | 16 | template 17 | ASYNC_MQTT_HEADER_ONLY_INLINE 18 | void 19 | client_impl::async_acquire_unique_packet_id( 20 | this_type_sp impl, 21 | as::any_completion_handler< 22 | void(error_code, packet_id_type) 23 | > handler 24 | ) { 25 | impl->ep_.async_acquire_unique_packet_id(force_move(handler)); 26 | } 27 | 28 | // sync version 29 | 30 | template 31 | ASYNC_MQTT_HEADER_ONLY_INLINE 32 | std::optional 33 | client_impl::acquire_unique_packet_id() { 34 | return ep_.acquire_unique_packet_id(); 35 | } 36 | 37 | } // namespace async_mqtt::detail 38 | 39 | #include 40 | 41 | #endif // ASYNC_MQTT_IMPL_CLIENT_ACQUIRE_UNIQUE_PACKET_ID_IPP 42 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/impl/client_acquire_unique_packet_id_wait_until.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_ACQUIRE_UNIQUE_PACKET_ID_WAIT_UNTIL_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_ACQUIRE_UNIQUE_PACKET_ID_WAIT_UNTIL_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace async_mqtt { 14 | 15 | template 16 | template 17 | auto 18 | client::async_acquire_unique_packet_id_wait_until( 19 | CompletionToken&& token 20 | ) { 21 | BOOST_ASSERT(impl_); 22 | return 23 | as::async_initiate< 24 | CompletionToken, 25 | void(error_code, packet_id_type) 26 | >( 27 | []( 28 | auto handler, 29 | std::shared_ptr impl 30 | ) { 31 | impl_type::async_acquire_unique_packet_id_wait_until( 32 | force_move(impl), 33 | force_move(handler) 34 | ); 35 | }, 36 | token, 37 | impl_ 38 | ); 39 | } 40 | 41 | } // namespace async_mqtt 42 | 43 | #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) 44 | #include 45 | #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) 46 | 47 | #endif // ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_ACQUIRE_UNIQUE_PACKET_ID_WAIT_UNTIL_HPP 48 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/impl/client_acquire_unique_packet_id_wait_until.ipp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_IMPL_CLIENT_ACQUIRE_UNIQUE_PACKET_ID_WAIT_UNTIL_IPP) 8 | #define ASYNC_MQTT_IMPL_CLIENT_ACQUIRE_UNIQUE_PACKET_ID_WAIT_UNTIL_IPP 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace async_mqtt::detail { 15 | 16 | template 17 | ASYNC_MQTT_HEADER_ONLY_INLINE 18 | void 19 | client_impl::async_acquire_unique_packet_id_wait_until( 20 | this_type_sp impl, 21 | as::any_completion_handler< 22 | void(error_code, packet_id_type) 23 | > handler 24 | ) { 25 | impl->ep_.async_acquire_unique_packet_id_wait_until(force_move(handler)); 26 | } 27 | 28 | } // namespace async_mqtt::detail 29 | 30 | #include 31 | 32 | #endif // ASYNC_MQTT_IMPL_CLIENT_ACQUIRE_UNIQUE_PACKET_ID_WAIT_UNTIL_IPP 33 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/impl/client_close.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_CLOSE_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_CLOSE_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace async_mqtt { 14 | 15 | template 16 | template 17 | auto 18 | client::async_close( 19 | CompletionToken&& token 20 | ) { 21 | BOOST_ASSERT(impl_); 22 | return 23 | as::async_initiate< 24 | CompletionToken, 25 | void() 26 | >( 27 | []( 28 | auto handler, 29 | std::shared_ptr impl 30 | ) { 31 | impl_type::async_close( 32 | force_move(impl), 33 | force_move(handler) 34 | ); 35 | }, 36 | token, 37 | impl_ 38 | ); 39 | } 40 | 41 | } // namespace async_mqtt 42 | 43 | #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) 44 | #include 45 | #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) 46 | 47 | #endif // ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_CLOSE_HPP 48 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/impl/client_close.ipp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_IMPL_CLIENT_CLOSE_IPP) 8 | #define ASYNC_MQTT_IMPL_CLIENT_CLOSE_IPP 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace async_mqtt::detail { 15 | 16 | template 17 | ASYNC_MQTT_HEADER_ONLY_INLINE 18 | void 19 | client_impl::async_close( 20 | this_type_sp impl, 21 | as::any_completion_handler< 22 | void() 23 | > handler 24 | ) { 25 | impl->ep_.async_close(force_move(handler)); 26 | } 27 | 28 | } // namespace async_mqtt::detail 29 | 30 | #include 31 | 32 | #endif // ASYNC_MQTT_IMPL_CLIENT_CLOSE_IPP 33 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/impl/client_instantiate.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2024 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_INSTANTIATE_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_INSTANTIATE_HPP 9 | 10 | #if defined(ASYNC_MQTT_SEPARATE_COMPILATION) && defined(ASYNC_MQTT_INDIVIDUAL_INSTANTIATE) 11 | 12 | #include 13 | 14 | #endif // defined(ASYNC_MQTT_SEPARATE_COMPILATION) && defined(ASYNC_MQTT_INDIVIDUAL_INSTANTIATE) 15 | 16 | #endif // ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_INSTANTIATE_HPP 17 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/impl/client_instantiate_direct.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2024 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_INSTANTIATE_DIRECT_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_INSTANTIATE_DIRECT_HPP 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | #define ASYNC_MQTT_INSTANTIATE_EACH(a_version, a_protocol) \ 16 | namespace async_mqtt { \ 17 | namespace detail { \ 18 | template \ 19 | class client_impl; \ 20 | } \ 21 | template \ 22 | class client; \ 23 | } // namespace async_mqtt 24 | 25 | #define ASYNC_MQTT_PP_GENERATE(r, product) \ 26 | BOOST_PP_EXPAND( \ 27 | ASYNC_MQTT_INSTANTIATE_EACH \ 28 | BOOST_PP_SEQ_TO_TUPLE( \ 29 | product \ 30 | ) \ 31 | ) 32 | 33 | BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_VERSION)(ASYNC_MQTT_PP_PROTOCOL)) 34 | 35 | #undef ASYNC_MQTT_PP_GENERATE 36 | #undef ASYNC_MQTT_INSTANTIATE_EACH 37 | 38 | 39 | #endif // ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_INSTANTIATE_DIRECT_HPP 40 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/impl/client_recv.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_RECV_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_RECV_HPP 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace async_mqtt { 18 | 19 | template 20 | template 21 | auto 22 | client::async_recv( 23 | CompletionToken&& token 24 | ) { 25 | ASYNC_MQTT_LOG("mqtt_api", info) 26 | << ASYNC_MQTT_ADD_VALUE(address, this) 27 | << "recv"; 28 | BOOST_ASSERT(impl_); 29 | return 30 | as::async_initiate< 31 | CompletionToken, 32 | void(error_code, std::optional) 33 | >( 34 | []( 35 | auto handler, 36 | std::shared_ptr impl 37 | ) { 38 | impl_type::async_recv( 39 | force_move(impl), 40 | force_move(handler) 41 | ); 42 | }, 43 | token, 44 | impl_ 45 | ); 46 | } 47 | 48 | } // namespace async_mqtt 49 | 50 | #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) 51 | #include 52 | #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) 53 | 54 | #endif // ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_RECV_HPP 55 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/impl/client_register_packet_id.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_REGISTER_PACKET_ID_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_REGISTER_PACKET_ID_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace async_mqtt { 14 | 15 | template 16 | template 17 | auto 18 | client::async_register_packet_id( 19 | packet_id_type pid, 20 | CompletionToken&& token 21 | ) { 22 | BOOST_ASSERT(impl_); 23 | return 24 | as::async_initiate< 25 | CompletionToken, 26 | void(error_code) 27 | >( 28 | []( 29 | auto handler, 30 | std::shared_ptr impl, 31 | packet_id_type pid 32 | ) { 33 | impl_type::async_register_packet_id( 34 | force_move(impl), 35 | pid, 36 | force_move(handler) 37 | ); 38 | }, 39 | token, 40 | impl_, 41 | pid 42 | ); 43 | } 44 | 45 | // sync version 46 | 47 | template 48 | inline 49 | bool 50 | client::register_packet_id(packet_id_type packet_id) { 51 | BOOST_ASSERT(impl_); 52 | return impl_->register_packet_id(packet_id); 53 | } 54 | 55 | 56 | } // namespace async_mqtt 57 | 58 | #endif // ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_REGISTER_PACKET_ID_HPP 59 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/impl/client_register_packet_id.ipp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_IMPL_CLIENT_REGISTER_PACKET_ID_IPP) 8 | #define ASYNC_MQTT_IMPL_CLIENT_REGISTER_PACKET_ID_IPP 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace async_mqtt::detail { 15 | 16 | template 17 | ASYNC_MQTT_HEADER_ONLY_INLINE 18 | void 19 | client_impl::async_register_packet_id( 20 | this_type_sp impl, 21 | packet_id_type pid, 22 | as::any_completion_handler< 23 | void(error_code) 24 | > handler 25 | ) { 26 | impl->ep_.async_register_packet_id(pid, force_move(handler)); 27 | } 28 | 29 | // sync version 30 | 31 | template 32 | inline 33 | bool 34 | client_impl::register_packet_id(packet_id_type packet_id) { 35 | return ep_.register_packet_id(packet_id); 36 | } 37 | 38 | } // namespace async_mqtt::detail 39 | 40 | #include 41 | 42 | #endif // ASYNC_MQTT_IMPL_CLIENT_REGISTER_PACKET_ID_IPP 43 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/impl/client_release_packet_id.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_RELEASE_PACKET_ID_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_RELEASE_PACKET_ID_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace async_mqtt { 14 | 15 | template 16 | template 17 | auto 18 | client::async_release_packet_id( 19 | packet_id_type pid, 20 | CompletionToken&& token 21 | ) { 22 | BOOST_ASSERT(impl_); 23 | return 24 | as::async_initiate< 25 | CompletionToken, 26 | void() 27 | >( 28 | []( 29 | auto handler, 30 | std::shared_ptr impl, 31 | packet_id_type pid 32 | ) { 33 | impl_type::async_release_packet_id( 34 | force_move(impl), 35 | pid, 36 | force_move(handler) 37 | ); 38 | }, 39 | token, 40 | impl_, 41 | pid 42 | ); 43 | } 44 | 45 | // sync version 46 | 47 | template 48 | inline 49 | void 50 | client::release_packet_id(packet_id_type packet_id) { 51 | BOOST_ASSERT(impl_); 52 | impl_->release_packet_id(packet_id); 53 | } 54 | 55 | } // namespace async_mqtt 56 | 57 | #endif // ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_RELEASE_PACKET_ID_HPP 58 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/impl/client_release_packet_id.ipp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_IMPL_CLIENT_RELEASE_PACKET_ID_IPP) 8 | #define ASYNC_MQTT_IMPL_CLIENT_RELEASE_PACKET_ID_IPP 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace async_mqtt::detail { 15 | 16 | template 17 | ASYNC_MQTT_HEADER_ONLY_INLINE 18 | void 19 | client_impl::async_release_packet_id( 20 | this_type_sp impl, 21 | packet_id_type pid, 22 | as::any_completion_handler< 23 | void() 24 | > handler 25 | ) { 26 | impl->ep_.async_release_packet_id(pid, force_move(handler)); 27 | } 28 | 29 | // sync version 30 | 31 | template 32 | inline 33 | void 34 | client_impl::release_packet_id(packet_id_type packet_id) { 35 | ep_.release_packet_id(packet_id); 36 | } 37 | 38 | } // namespace async_mqtt::detail 39 | 40 | #include 41 | 42 | #endif // ASYNC_MQTT_IMPL_CLIENT_RELEASE_PACKET_ID_IPP 43 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/impl/client_underlying_handshake.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2024 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_UNDERLYING_HANDSHAKE_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_UNDERLYING_HANDSHAKE_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace async_mqtt { 14 | 15 | namespace detail { 16 | 17 | template 18 | template 19 | auto 20 | client_impl::async_underlying_handshake( 21 | Args&&... args 22 | ) { 23 | return ep_.async_underlying_handshake(std::forward(args)...); 24 | } 25 | 26 | } // namespace detail 27 | 28 | template 29 | template 30 | auto 31 | client::async_underlying_handshake( 32 | Args&&... args 33 | ) { 34 | BOOST_ASSERT(impl_); 35 | return impl_->async_underlying_handshake(std::forward(args)...); 36 | } 37 | 38 | } // namespace async_mqtt 39 | 40 | #endif // ASYNC_MQTT_ASIO_BIND_IMPL_CLIENT_UNDERLYING_HANDSHAKE_HPP 41 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/impl/endpoint_acquire_unique_packet_id.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_IMPL_ENDPOINT_ACQUIRE_UNIQUE_PACKET_ID_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_IMPL_ENDPOINT_ACQUIRE_UNIQUE_PACKET_ID_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace async_mqtt { 14 | 15 | template 16 | template 17 | auto 18 | basic_endpoint::async_acquire_unique_packet_id( 19 | CompletionToken&& token 20 | ) { 21 | ASYNC_MQTT_LOG("mqtt_api", info) 22 | << ASYNC_MQTT_ADD_VALUE(address, this) 23 | << "acquire_unique_packet_id"; 24 | BOOST_ASSERT(impl_); 25 | return 26 | as::async_initiate< 27 | CompletionToken, 28 | void(error_code, typename basic_packet_id_type::type) 29 | >( 30 | []( 31 | auto handler, 32 | std::shared_ptr impl 33 | ) { 34 | impl_type::async_acquire_unique_packet_id( 35 | force_move(impl), 36 | force_move(handler) 37 | ); 38 | }, 39 | token, 40 | impl_ 41 | ); 42 | } 43 | 44 | } // namespace async_mqtt 45 | 46 | #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) 47 | #include 48 | #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) 49 | 50 | #endif // ASYNC_MQTT_ASIO_BIND_IMPL_ENDPOINT_ACQUIRE_UNIQUE_PACKET_ID_HPP 51 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/impl/endpoint_acquire_unique_packet_id_wait_until.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_IMPL_ENDPOINT_ACQUIRE_UNIQUE_PACKET_ID_WAIT_UNTIL_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_IMPL_ENDPOINT_ACQUIRE_UNIQUE_PACKET_ID_WAIT_UNTIL_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace async_mqtt { 14 | 15 | template 16 | template 17 | auto 18 | basic_endpoint::async_acquire_unique_packet_id_wait_until( 19 | CompletionToken&& token 20 | ) { 21 | ASYNC_MQTT_LOG("mqtt_api", info) 22 | << ASYNC_MQTT_ADD_VALUE(address, this) 23 | << "acquire_unique_packet_id_wait_until"; 24 | BOOST_ASSERT(impl_); 25 | return 26 | as::async_initiate< 27 | CompletionToken, 28 | void(error_code, typename basic_packet_id_type::type) 29 | >( 30 | []( 31 | auto handler, 32 | std::shared_ptr impl 33 | ) { 34 | impl_type::async_acquire_unique_packet_id_wait_until( 35 | force_move(impl), 36 | force_move(handler) 37 | ); 38 | }, 39 | token, 40 | impl_ 41 | ); 42 | } 43 | 44 | } // namespace async_mqtt 45 | 46 | #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) 47 | #include 48 | #include 49 | #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) 50 | 51 | #endif // ASYNC_MQTT_ASIO_BIND_IMPL_ENDPOINT_ACQUIRE_UNIQUE_PACKET_ID_WAIT_UNTIL_HPP 52 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/impl/endpoint_instantiate.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2024 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_IMPL_ENDPOINT_INSTANTIATE_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_IMPL_ENDPOINT_INSTANTIATE_HPP 9 | 10 | #if defined(ASYNC_MQTT_SEPARATE_COMPILATION) && defined(ASYNC_MQTT_INDIVIDUAL_INSTANTIATE) 11 | 12 | #include 13 | 14 | #endif // defined(ASYNC_MQTT_SEPARATE_COMPILATION) && defined(ASYNC_MQTT_INDIVIDUAL_INSTANTIATE) 15 | 16 | #endif // ASYNC_MQTT_ASIO_BIND_IMPL_ENDPOINT_INSTANTIATE_HPP 17 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/impl/endpoint_instantiate_direct.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2024 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_IMPL_ENDPOINT_INSTANTIATE_DIRECT_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_IMPL_ENDPOINT_INSTANTIATE_DIRECT_HPP 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | #define ASYNC_MQTT_INSTANTIATE_EACH(a_role, a_size, a_protocol) \ 16 | namespace async_mqtt { \ 17 | namespace detail { \ 18 | template \ 19 | class basic_endpoint_impl; \ 20 | } \ 21 | template \ 22 | class basic_endpoint; \ 23 | } // namespace async_mqtt 24 | 25 | #define ASYNC_MQTT_PP_GENERATE(r, product) \ 26 | BOOST_PP_EXPAND( \ 27 | ASYNC_MQTT_INSTANTIATE_EACH \ 28 | BOOST_PP_SEQ_TO_TUPLE( \ 29 | product \ 30 | ) \ 31 | ) 32 | 33 | BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_ROLE)(ASYNC_MQTT_PP_SIZE)(ASYNC_MQTT_PP_PROTOCOL)) 34 | 35 | #undef ASYNC_MQTT_PP_GENERATE 36 | #undef ASYNC_MQTT_INSTANTIATE_EACH 37 | 38 | #endif // ASYNC_MQTT_ASIO_BIND_IMPL_ENDPOINT_INSTANTIATE_DIRECT_HPP 39 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/impl/stream_fwd.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_IMPL_STREAM_FWD_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_IMPL_STREAM_FWD_HPP 9 | 10 | namespace async_mqtt { 11 | 12 | template 13 | class stream; 14 | 15 | } // namespace async_mqtt 16 | 17 | #endif // ASYNC_MQTT_ASIO_BIND_IMPL_STREAM_FWD_HPP 18 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/impl/stream_impl_fwd.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_IMPL_STREAM_IMPL_FWD_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_IMPL_STREAM_IMPL_FWD_HPP 9 | 10 | namespace async_mqtt::detail { 11 | 12 | template 13 | class stream_impl; 14 | 15 | } // namespace async_mqtt::detail 16 | 17 | #endif // ASYNC_MQTT_ASIO_BIND_IMPL_STREAM_IMPL_FWD_HPP 18 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/impl/stream_underlying_handshake.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_UTIL_IMPL_STREAM_UNDERLYING_HANDSHAKE_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_UTIL_IMPL_STREAM_UNDERLYING_HANDSHAKE_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | namespace async_mqtt { 19 | 20 | namespace hana = boost::hana; 21 | 22 | namespace detail { 23 | 24 | template 25 | template < 26 | typename... Args 27 | > 28 | auto 29 | stream_impl:: 30 | async_underlying_handshake( 31 | this_type_sp impl, 32 | Args&&... args 33 | ) { 34 | return layer_customize::async_handshake( 35 | impl->next_layer(), 36 | std::forward(args)... 37 | ); 38 | } 39 | 40 | } // namespace detail 41 | 42 | template 43 | template < 44 | typename... Args 45 | > 46 | auto 47 | stream::async_underlying_handshake( 48 | Args&&... args 49 | ) { 50 | BOOST_ASSERT(impl_); 51 | 52 | return impl_type::async_underlying_handshake( 53 | impl_, 54 | std::forward(args)... 55 | ); 56 | } 57 | 58 | 59 | } // namespace async_mqtt 60 | 61 | #endif // ASYNC_MQTT_ASIO_BIND_UTIL_IMPL_STREAM_UNDERLYING_HANDSHAKE_HPP 62 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/predefined_layer/mqtt.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_PREDEFINED_LAYER_MQTT_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_PREDEFINED_LAYER_MQTT_HPP 9 | 10 | #include 11 | 12 | #include 13 | 14 | namespace async_mqtt { 15 | 16 | namespace as = boost::asio; 17 | 18 | namespace protocol { 19 | 20 | /** 21 | * @brief Type alias of Boost.Asio TCP socket 22 | * 23 | */ 24 | using mqtt = as::basic_stream_socket; 25 | 26 | 27 | /** 28 | * @brief resovling name and connect TCP layer 29 | * @param layer TCP layer 30 | * @param host host name or IP address to connect 31 | * @param port port number to connect 32 | * @param token completion token. signature is void(error_code) 33 | * @return deduced by token 34 | * 35 | */ 36 | template < 37 | typename Socket, 38 | typename Executor, 39 | typename CompletionToken = as::default_completion_token_t< 40 | Executor 41 | > 42 | > 43 | auto 44 | async_underlying_handshake( 45 | as::basic_stream_socket& layer, 46 | std::string_view host, 47 | std::string_view port, 48 | CompletionToken&& token = as::default_completion_token_t{} 49 | ); 50 | 51 | } // namespace protocol 52 | 53 | } // namespace async_mqtt 54 | 55 | #endif // ASYNC_MQTT_ASIO_BIND_PREDEFINED_LAYER_MQTT_HPP 56 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/predefined_layer/mqtts.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_PREDEFINED_LAYER_MQTTS_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_PREDEFINED_LAYER_MQTTS_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace async_mqtt { 14 | 15 | namespace as = boost::asio; 16 | namespace tls = as::ssl; // for backword compatilibity 17 | 18 | namespace protocol { 19 | 20 | /** 21 | * @brief Type alias of boost::asio::ssl::stream of mqtt 22 | * @brief predefined underlying layer (TLS) 23 | * 24 | */ 25 | using mqtts = as::ssl::stream; 26 | 27 | 28 | /** 29 | * @brief TLS handshake 30 | * This function does underlying layers handshaking prior to TLS handshake 31 | * @param layer TLS layer 32 | * @param host host name or IP address to connect 33 | * @param port port number to connect 34 | * @param token completion token. signature is void(error_code) 35 | * @return deduced by token 36 | * 37 | */ 38 | template < 39 | typename NextLayer, 40 | typename CompletionToken = as::default_completion_token_t< 41 | typename as::ssl::stream::executor_type 42 | > 43 | > 44 | auto 45 | async_underlying_handshake( 46 | as::ssl::stream& layer, 47 | std::string_view host, 48 | std::string_view port, 49 | CompletionToken&& token = as::default_completion_token_t< 50 | typename as::ssl::stream::executor_type 51 | >{} 52 | ); 53 | 54 | } // namespace protocol 55 | 56 | } // namespace async_mqtt 57 | 58 | #endif // ASYNC_MQTT_ASIO_BIND_PREDEFINED_LAYER_MQTTS_HPP 59 | -------------------------------------------------------------------------------- /include/async_mqtt/asio_bind/predefined_layer/wss.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASIO_BIND_PREDEFINED_LAYER_WSS_HPP) 8 | #define ASYNC_MQTT_ASIO_BIND_PREDEFINED_LAYER_WSS_HPP 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | namespace async_mqtt { 17 | 18 | namespace as = boost::asio; 19 | namespace bs = boost::beast; 20 | 21 | namespace protocol { 22 | 23 | /** 24 | * @brief Type alias of boost::beast::websocket::stream of mqtts 25 | * async_underlying_handshake function can be called with wss. 26 | * You can call the following functions to handshake. 27 | * 28 | * async_underlying_handshake( 29 | * bs::websocket::stream& layer, 30 | * std::string_view host, 31 | * std::string_view port, 32 | * std::string_view path, 33 | * CompletionToken&& token 34 | * ) 35 | * 36 | * async_underlying_handshake( 37 | * bs::websocket::stream& layer, 38 | * std::string_view host, 39 | * std::string_view port, 40 | * CompletionToken&& token 41 | * ) 42 | * 43 | */ 44 | using wss = bs::websocket::stream; 45 | 46 | } // namespace protocol 47 | 48 | } // namespace async_mqtt 49 | 50 | #endif // ASYNC_MQTT_ASIO_BIND_PREDEFINED_LAYER_WSS_HPP 51 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/buffer_to_packet_variant.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_BUFFER_TO_PACKET_VARIANT_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_BUFFER_TO_PACKET_VARIANT_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace async_mqtt { 16 | 17 | /** 18 | * @brief create basic_packet_variant from the buffer 19 | * @param buf buffer contains packet bytes 20 | * @param ver protocol version to create packet 21 | * @param ec error_code for reporting error 22 | * @return if no error created basic_packet_variant, otherwise std::nullopt. 23 | */ 24 | template 25 | std::optional> 26 | buffer_to_basic_packet_variant(buffer buf, protocol_version ver, error_code& ec); 27 | 28 | /** 29 | * @brief create packet_variant from the buffer 30 | * @param buf buffer contains packet bytes 31 | * @param ver protocol version to create packet 32 | * @param ec error_code for reporting error 33 | * @return if no error created packet_variant, otherwise std::nullopt. 34 | */ 35 | std::optional 36 | buffer_to_packet_variant(buffer buf, protocol_version ver, error_code& ec); 37 | 38 | } // namespace async_mqtt 39 | 40 | #endif // ASYNC_MQTT_PROTOCOL_BUFFER_TO_PACKET_VARIANT_HPP 41 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/connection_fwd.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_CONNECTION_FWD_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_CONNECTION_FWD_HPP 9 | 10 | #include // for std::size_t 11 | 12 | #include 13 | 14 | namespace async_mqtt { 15 | 16 | /** 17 | * @brief MQTT connection. 18 | * 19 | * An I/O-independent MQTT protocol state machine. 20 | * @li Manages connection status. 21 | * @li Manages packet identifiers. 22 | * @li Manages Topic Aliases. 23 | * @li Manages packet resending on reconnection. 24 | * @li Manages PINGREQ/PINGRESP timers. 25 | * @li Manages automatic response packet sending. 26 | * 27 | * All requests and settings are implemented as synchronous functions. 28 | * When a caller action is required, the corresponding virtual function 29 | * is called **within the synchronous function before it returns**. 30 | * 31 | * #### Thread Safety 32 | * @li Distinct objects: Safe 33 | * @li Shared objects: Unsafe 34 | * 35 | * @tparam Role The role used for checking whether packets can be sent. 36 | * @tparam PacketIdBytes The number of bytes used for the packet identifier. 37 | * According to the MQTT specification, this is 2. 38 | * You can use @ref connection for this. 39 | */ 40 | template 41 | class basic_connection; 42 | 43 | /** 44 | * @brief Type alias for @ref basic_connection with PacketIdBytes set to 2. 45 | * This is for typical use cases (e.g., MQTT client). 46 | * 47 | * #### Thread Safety 48 | * @li Distinct objects: Safe 49 | * @li Shared objects: Unsafe 50 | * 51 | * @tparam Role The role used for checking whether packets can be sent. 52 | */ 53 | template 54 | using connection = basic_connection; 55 | 56 | } // namespace async_mqtt 57 | 58 | #endif // ASYNC_MQTT_PROTOCOL_CONNECTION_FWD_HPP 59 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/connection_status.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_CONNECTION_STATUS_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_CONNECTION_STATUS_HPP 9 | 10 | namespace async_mqtt { 11 | 12 | /** 13 | * @brief Connection status. 14 | */ 15 | enum class connection_status { 16 | connecting, ///< The status after sending or receiving a CONNECT packet, 17 | ///< but before receiving or sending a CONNACK packet. 18 | connected, ///< The status after sending or receiving a CONNACK packet. 19 | disconnected, ///< The status after sending or receiving a DISCONNECT packet, 20 | ///< detecting an error, or when the underlying layer is closed. 21 | }; 22 | 23 | } // namespace async_mqtt 24 | 25 | #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) 26 | #include 27 | #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) 28 | 29 | #endif // ASYNC_MQTT_PROTOCOL_CONNECTION_STATUS_HPP 30 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/detail/connection_impl_fwd.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_DETAIL_CONNECTION_IMPL_FWD_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_DETAIL_CONNECTION_IMPL_FWD_HPP 9 | 10 | #include // for std::size_t 11 | #include 12 | 13 | namespace async_mqtt::detail { 14 | 15 | template 16 | class basic_connection_impl; 17 | 18 | } // namespace async_mqtt::detail 19 | 20 | #endif // ASYNC_MQTT_PROTOCOL_DETAIL_CONNECTION_IMPL_FWD_HPP 21 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/event/close.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2024 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_EVENT_CLOSE_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_EVENT_CLOSE_HPP 9 | 10 | #include 11 | 12 | namespace async_mqtt::event { 13 | 14 | /** 15 | * @brief Close event. 16 | * 17 | * This corresponds to @ref basic_connection::on_close(). 18 | * 19 | * #### Thread Safety 20 | * @li Distinct objects: Safe 21 | * @li Shared objects: Unsafe 22 | */ 23 | class close { 24 | public: 25 | /** 26 | * @brief Constructor. 27 | */ 28 | constexpr close() = default; 29 | }; 30 | 31 | } // namespace async_mqtt::event 32 | 33 | #endif // ASYNC_MQTT_PROTOCOL_EVENT_CLOSE_HPP 34 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/event/packet_id_released.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2024 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_EVENT_PACKET_ID_RELEASED_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_EVENT_PACKET_ID_RELEASED_HPP 9 | 10 | #include 11 | 12 | #include 13 | 14 | namespace async_mqtt::event { 15 | 16 | /** 17 | * @brief Packet identifier released event. 18 | * 19 | * This corresponds to @ref basic_connection::on_packet_id_released(). 20 | * 21 | * #### Thread Safety 22 | * @li Distinct objects: Safe 23 | * @li Shared objects: Unsafe 24 | * 25 | * @tparam PacketIdBytes The number of bytes used for the packet identifier. 26 | * According to the MQTT specification, this is 2. 27 | * You can use @ref event::packet_id_released for this. 28 | */ 29 | template 30 | class basic_packet_id_released { 31 | public: 32 | /** 33 | * @brief Constructor. 34 | * 35 | * @param packet_id The released packet_id. 36 | */ 37 | explicit basic_packet_id_released(typename basic_packet_id_type::type packet_id) 38 | : packet_id_{packet_id} {} 39 | 40 | /** 41 | * @brief Get the released packet_id. 42 | * 43 | * @return The released packet_id. 44 | */ 45 | typename basic_packet_id_type::type get() const { 46 | return packet_id_; 47 | } 48 | 49 | private: 50 | typename basic_packet_id_type::type packet_id_; 51 | }; 52 | 53 | 54 | /** 55 | * @brief Type alias of @ref basic_packet_id_released (PacketIdBytes=2). 56 | * This is for typical usecase (e.g. MQTT client). 57 | * 58 | * #### Thread Safety 59 | * @li Distinct objects: Safe 60 | * @li Shared objects: Unsafe 61 | */ 62 | using packet_id_released = basic_packet_id_released<2>; 63 | 64 | } // namespace async_mqtt::event 65 | 66 | #endif // ASYNC_MQTT_PROTOCOL_EVENT_PACKET_ID_RELEASED_HPP 67 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/event/timer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2024 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_EVENT_TIMER_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_EVENT_TIMER_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | namespace async_mqtt::event { 17 | 18 | /** 19 | * @brief Timer event. 20 | * 21 | * This corresponds to @ref basic_connection::on_timer_op(). 22 | * 23 | * #### Thread Safety 24 | * @li Distinct objects: Safe 25 | * @li Shared objects: Unsafe 26 | */ 27 | class timer { 28 | public: 29 | /** 30 | * @brief Constructor. 31 | * 32 | * @param op The type of timer operation. 33 | * @param kind The type of timer. 34 | * @param ms The duration of the timer. 35 | * The minimum resolution is in milliseconds. 36 | * If `kind` is @ref timer_op::cancel, `ms` is ignored. 37 | */ 38 | explicit timer( 39 | timer_op op, 40 | timer_kind kind, 41 | std::optional ms = std::nullopt 42 | ) 43 | : op_{op}, kind_{kind}, ms_{ms} {} 44 | 45 | /** 46 | * @brief Get the timer operation. 47 | * 48 | * @return The timer operation. 49 | */ 50 | timer_op get_op() const { 51 | return op_; 52 | } 53 | 54 | /** 55 | * @brief Get the timer type. 56 | * 57 | * @return The timer type. 58 | */ 59 | timer_kind get_kind() const { 60 | return kind_; 61 | } 62 | 63 | /** 64 | * @brief Get the timer duration in milliseconds. 65 | * 66 | * @return The timer duration in milliseconds. 67 | */ 68 | std::optional get_ms() const { 69 | return ms_; 70 | } 71 | 72 | private: 73 | timer_op op_; 74 | timer_kind kind_; 75 | std::optional ms_; 76 | }; 77 | 78 | } // namespace async_mqtt::event 79 | 80 | #endif // ASYNC_MQTT_PROTOCOL_EVENT_TIMER_HPP 81 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/impl/connection_instantiate.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2024 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_IMPL_CONNECTION_INSTANTIATE_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_IMPL_CONNECTION_INSTANTIATE_HPP 9 | 10 | #if defined(ASYNC_MQTT_SEPARATE_COMPILATION) && defined(ASYNC_MQTT_INDIVIDUAL_INSTANTIATE) 11 | 12 | #include 13 | 14 | #endif // defined(ASYNC_MQTT_SEPARATE_COMPILATION) && defined(ASYNC_MQTT_INDIVIDUAL_INSTANTIATE) 15 | 16 | #endif // ASYNC_MQTT_PROTOCOL_IMPL_CONNECTION_INSTANTIATE_HPP 17 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/impl/connection_instantiate_direct.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2024 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_IMPL_CONNECTION_INSTANTIATE_DIRECT_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_IMPL_CONNECTION_INSTANTIATE_DIRECT_HPP 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | #define ASYNC_MQTT_INSTANTIATE_EACH(a_role, a_size) \ 16 | namespace async_mqtt { \ 17 | namespace detail { \ 18 | template \ 19 | class basic_connection_impl; \ 20 | } \ 21 | template \ 22 | class basic_connection; \ 23 | } // namespace async_mqtt 24 | 25 | #define ASYNC_MQTT_PP_GENERATE(r, product) \ 26 | BOOST_PP_EXPAND( \ 27 | ASYNC_MQTT_INSTANTIATE_EACH \ 28 | BOOST_PP_SEQ_TO_TUPLE( \ 29 | product \ 30 | ) \ 31 | ) 32 | 33 | BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_ROLE)(ASYNC_MQTT_PP_SIZE)) 34 | 35 | #undef ASYNC_MQTT_PP_GENERATE 36 | #undef ASYNC_MQTT_INSTANTIATE_EACH 37 | 38 | #endif // ASYNC_MQTT_PROTOCOL_IMPL_CONNECTION_INSTANTIATE_DIRECT_HPP 39 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/impl/connection_status_impl.ipp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2025 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_IMPL_CONNECTION_STATUS_IMPL_IPP) 8 | #define ASYNC_MQTT_PROTOCOL_IMPL_CONNECTION_STATUS_IMPL_IPP 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace async_mqtt { 16 | 17 | ASYNC_MQTT_HEADER_ONLY_INLINE 18 | constexpr 19 | char const* connection_status_to_string(connection_status v) { 20 | switch (v) { 21 | case connection_status::connecting: return "connecting"; 22 | case connection_status::connected: return "connected"; 23 | case connection_status::disconnected: return "disconnected"; 24 | default: return "unknown_connection_status"; 25 | } 26 | } 27 | 28 | inline 29 | std::ostream& operator<<(std::ostream& o, connection_status v) 30 | { 31 | o << connection_status_to_string(v); 32 | return o; 33 | } 34 | 35 | } // namespace async_mqtt 36 | 37 | #endif // ASYNC_MQTT_PROTOCOL_IMPL_CONNECTION_STATUS_IMPL_IPP 38 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/impl/rv_connection.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2024 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_IMPL_RV_CONNECTION_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_IMPL_RV_CONNECTION_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace async_mqtt { 14 | 15 | // public 16 | 17 | template 18 | template 19 | inline 20 | std::vector> 21 | basic_rv_connection:: 22 | send(Packet packet) { 23 | base_type::send(std::forward(packet)); 24 | return force_move(events_); 25 | } 26 | 27 | } // namespace async_mqtt 28 | 29 | #endif // ASYNC_MQTT_PROTOCOL_IMPL_RV_CONNECTION_HPP 30 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/impl/rv_connection_instantiate.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2024 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_IMPL_RV_CONNECTION_INSTANTIATE_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_IMPL_RV_CONNECTION_INSTANTIATE_HPP 9 | 10 | #if defined(ASYNC_MQTT_SEPARATE_COMPILATION) && defined(ASYNC_MQTT_INDIVIDUAL_INSTANTIATE) 11 | 12 | #include 13 | 14 | #endif // defined(ASYNC_MQTT_SEPARATE_COMPILATION) && defined(ASYNC_MQTT_INDIVIDUAL_INSTANTIATE) 15 | 16 | #endif // ASYNC_MQTT_PROTOCOL_IMPL_RV_CONNECTION_INSTANTIATE_HPP 17 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/impl/rv_connection_instantiate_direct.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2024 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_IMPL_RV_CONNECTION_INSTANTIATE_DIRECT_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_IMPL_RV_CONNECTION_INSTANTIATE_DIRECT_HPP 9 | 10 | #include 11 | 12 | #include 13 | 14 | #define ASYNC_MQTT_INSTANTIATE_EACH(a_role, a_size) \ 15 | namespace async_mqtt { \ 16 | template \ 17 | class basic_rv_connection; \ 18 | } // namespace async_mqtt 19 | 20 | #define ASYNC_MQTT_PP_GENERATE(r, product) \ 21 | BOOST_PP_EXPAND( \ 22 | ASYNC_MQTT_INSTANTIATE_EACH \ 23 | BOOST_PP_SEQ_TO_TUPLE( \ 24 | product \ 25 | ) \ 26 | ) 27 | 28 | BOOST_PP_SEQ_FOR_EACH_PRODUCT(ASYNC_MQTT_PP_GENERATE, (ASYNC_MQTT_PP_ROLE)(ASYNC_MQTT_PP_SIZE)) 29 | 30 | #undef ASYNC_MQTT_PP_GENERATE 31 | #undef ASYNC_MQTT_INSTANTIATE_EACH 32 | 33 | #endif // ASYNC_MQTT_PROTOCOL_IMPL_RV_CONNECTION_INSTANTIATE_DIRECT_HPP 34 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/impl/timer_impl.ipp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2024 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_IMPL_TIMER_IMPL_IPP) 8 | #define ASYNC_MQTT_PROTOCOL_IMPL_TIMER_IMPL_IPP 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace async_mqtt { 16 | 17 | ASYNC_MQTT_HEADER_ONLY_INLINE 18 | constexpr 19 | char const* timer_kind_to_string(timer_kind v) { 20 | switch (v) { 21 | case timer_kind::pingreq_send: return "pingreq_send"; 22 | case timer_kind::pingreq_recv: return "pingreq_recv"; 23 | case timer_kind::pingresp_recv: return "pingresp_recv"; 24 | default: return "unknown_timer_kind"; 25 | } 26 | } 27 | 28 | inline 29 | std::ostream& operator<<(std::ostream& o, timer_kind v) 30 | { 31 | o << timer_kind_to_string(v); 32 | return o; 33 | } 34 | 35 | constexpr 36 | char const* event_timer_op_to_string(timer_op const& v) { 37 | switch (v) { 38 | case timer_op::reset: return "reset"; 39 | case timer_op::cancel: return "cancel"; 40 | default: return "unknown_timer_op"; 41 | } 42 | } 43 | 44 | inline 45 | std::ostream& operator<<(std::ostream& o, timer_op v) 46 | { 47 | o << event_timer_op_to_string(v); 48 | return o; 49 | } 50 | 51 | } // namespace async_mqtt 52 | 53 | #endif // ASYNC_MQTT_PROTOCOL_IMPL_TIMER_IMPL_IPP 54 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/packet/detail/fixed_header.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_PACKET_DETAIL_FIXED_HEADER_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_PACKET_DETAIL_FIXED_HEADER_HPP 9 | 10 | #include 11 | 12 | namespace async_mqtt::detail { 13 | 14 | constexpr std::uint8_t make_fixed_header(control_packet_type type, std::uint8_t flags) { 15 | return static_cast(type) | (flags & 0x0f); 16 | } 17 | 18 | } // namespace async_mqtt::detail 19 | 20 | #endif // ASYNC_MQTT_PROTOCOL_PACKET_DETAIL_FIXED_HEADER_HPP 21 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/packet/detail/is_payload.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_PACKET_DETAIL_IS_PAYLOAD_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_PACKET_DETAIL_IS_PAYLOAD_HPP 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace async_mqtt::detail { 16 | 17 | template 18 | struct has_begin_end : std::false_type 19 | {}; 20 | 21 | template 22 | struct has_begin_end< 23 | T, 24 | std::enable_if_t< 25 | std::is_invocable_v), T const&> && 26 | std::is_invocable_v), T const&> 27 | > 28 | > 29 | : std::true_type 30 | {}; 31 | 32 | template 33 | constexpr bool is_payload() { 34 | return 35 | std::disjunction< 36 | std::is_convertible, 37 | has_begin_end> 38 | >::value; 39 | } 40 | 41 | } // namespace async_mqtt::detail 42 | 43 | #endif // ASYNC_MQTT_PROTOCOL_PACKET_DETAIL_IS_PAYLOAD_HPP 44 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/packet/impl/connect_flags.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2015 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_CONNECT_FLAGS_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_CONNECT_FLAGS_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace async_mqtt { 14 | 15 | namespace connect_flags { 16 | 17 | constexpr char const mask_clean_session = 0b00000010; 18 | constexpr char const mask_clean_start = 0b00000010; 19 | constexpr char const mask_will_flag = 0b00000100; 20 | constexpr char const mask_will_retain = 0b00100000; 21 | constexpr char const mask_password_flag = 0b01000000; 22 | constexpr char const mask_user_name_flag = static_cast(0b10000000u); 23 | 24 | constexpr bool has_clean_session(char v) { 25 | return (v & mask_clean_session) != 0; 26 | } 27 | 28 | constexpr bool has_clean_start(char v) { 29 | return (v & mask_clean_start) != 0; 30 | } 31 | 32 | constexpr bool has_will_flag(char v) { 33 | return (v & mask_will_flag) != 0; 34 | } 35 | 36 | constexpr pub::retain will_retain(char v) { 37 | return 38 | [&] { 39 | if (v & mask_will_retain) return pub::retain::yes; 40 | return pub::retain::no; 41 | }(); 42 | } 43 | 44 | constexpr bool has_password_flag(char v) { 45 | return (v & mask_password_flag) != 0; 46 | } 47 | 48 | constexpr bool has_user_name_flag(char v) { 49 | return (v & mask_user_name_flag) != 0; 50 | } 51 | 52 | constexpr void set_will_qos(char& v, qos qos_value) { 53 | v |= static_cast(static_cast(qos_value) << 3); 54 | } 55 | 56 | constexpr qos will_qos(char v) { 57 | return static_cast((v & 0b00011000) >> 3); 58 | } 59 | 60 | } // namespace connect_flags 61 | 62 | } // namespace async_mqtt 63 | 64 | #endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_CONNECT_FLAGS_HPP 65 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/packet/impl/copy_to_static_vector.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_COPY_TO_STATIC_VECTOR_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_COPY_TO_STATIC_VECTOR_HPP 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace async_mqtt { 18 | 19 | template 20 | bool copy_advance(buffer& buf, static_vector& sv) { 21 | if (buf.size() < sv.capacity()) return false; 22 | std::copy( 23 | buf.begin(), 24 | std::next(buf.begin(), typename static_vector::difference_type(sv.capacity())), 25 | sv.begin() 26 | ); 27 | buf.remove_prefix(sv.capacity()); 28 | return true; 29 | } 30 | 31 | template 32 | bool insert_advance(buffer& buf, static_vector& sv) { 33 | if (buf.size() < sv.capacity()) return false; 34 | std::copy( 35 | buf.begin(), 36 | std::next(buf.begin(), typename static_vector::difference_type(sv.capacity())), 37 | std::back_inserter(sv) 38 | ); 39 | buf.remove_prefix(sv.capacity()); 40 | return true; 41 | } 42 | 43 | inline 44 | std::optional insert_advance_variable_length(buffer& buf, static_vector& sv) { 45 | if (buf.empty()) return std::nullopt; 46 | std::uint32_t variable_length = 0; 47 | auto it = buf.begin(); 48 | // it is updated as consmed position 49 | if (auto len_opt = variable_bytes_to_val(it, buf.end())) { 50 | variable_length = *len_opt; 51 | } 52 | else { 53 | return std::nullopt; 54 | } 55 | std::copy( 56 | buf.begin(), 57 | it, 58 | std::back_inserter(sv)); 59 | buf.remove_prefix(std::size_t(std::distance(buf.begin(), it))); 60 | return variable_length; 61 | } 62 | 63 | } // namespace async_mqtt 64 | 65 | #endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_COPY_TO_STATIC_VECTOR_HPP 66 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/packet/impl/get_protocol_version.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_GET_PROTOCOL_VERSION_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_GET_PROTOCOL_VERSION_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace async_mqtt { 14 | 15 | inline 16 | protocol_version get_protocol_version(buffer buf) { 17 | static_vector sv; 18 | // fixed_header 19 | buf.remove_prefix(1); 20 | if (auto vl_opt = insert_advance_variable_length(buf, sv)) { 21 | if (buf.size() >= 6) { 22 | return static_cast(buf[6]); 23 | } 24 | } 25 | return protocol_version::undetermined; 26 | } 27 | 28 | } // async_mqtt 29 | 30 | #endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_GET_PROTOCOL_VERSION_HPP 31 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/packet/impl/session_present.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2015 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_PACKET_IMPL_SESSION_PRESENT_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_PACKET_IMPL_SESSION_PRESENT_HPP 9 | 10 | 11 | namespace async_mqtt { 12 | 13 | constexpr bool is_session_present(char v) { 14 | return v & 0b00000001; 15 | } 16 | 17 | } // namespace async_mqtt 18 | 19 | #endif // ASYNC_MQTT_PROTOCOL_PACKET_IMPL_SESSION_PRESENT_HPP 20 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/packet/packet_helper.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2023 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_PACKET_PACKET_HELPER_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_PACKET_PACKET_HELPER_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | namespace async_mqtt { 16 | 17 | template 18 | struct hex_dump_t { 19 | hex_dump_t(Packet const& p):p{p} {} 20 | 21 | Packet const& p; 22 | }; 23 | 24 | template 25 | std::ostream& operator<< (std::ostream& o, hex_dump_t const& v); 26 | 27 | /** 28 | * @brief hexdump the packet. 29 | * Usage. std::cout << hex_dump(p) << std::endl; 30 | * @param p packet to dump. p must be valid packet. packet_variant system_error cannot be accepted. 31 | * @return id 32 | * 33 | */ 34 | template 35 | hex_dump_t hex_dump(Packet const& p) { 36 | return hex_dump_t{p}; 37 | } 38 | 39 | } // namespace async_mqtt 40 | 41 | #include 42 | 43 | #endif // ASYNC_MQTT_PROTOCOL_PACKET_PACKET_HELPER_HPP 44 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/packet/packet_id_type.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_PACKET_PACKET_ID_TYPE_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_PACKET_PACKET_ID_TYPE_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace async_mqtt { 14 | 15 | /** 16 | * @brief packet idenfitifer type class template 17 | * 18 | * #### Actual Types 19 | * @li `std::uint16_t` if PacketIdBytes is 2. For MQTT specification. 20 | * @li `std::uint32_t` if PacketIdBytes is 4. For expanded specification for inter broker communication. 21 | * 22 | */ 23 | template 24 | struct basic_packet_id_type; 25 | 26 | template <> 27 | struct basic_packet_id_type<2> { 28 | using type = std::uint16_t; 29 | }; 30 | 31 | template <> 32 | struct basic_packet_id_type<4> { 33 | using type = std::uint32_t; 34 | }; 35 | 36 | /** 37 | * @brief packet idenfitifer type 38 | * 39 | */ 40 | using packet_id_type = typename basic_packet_id_type<2>::type; 41 | 42 | } // namespace async_mqtt 43 | 44 | #endif // ASYNC_MQTT_PROTOCOL_PACKET_PACKET_ID_TYPE_HPP 45 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/packet/packet_iterator.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_PACKET_PACKET_ITERATOR_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_PACKET_PACKET_ITERATOR_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | namespace async_mqtt { 20 | 21 | namespace as = boost::asio; 22 | 23 | /** 24 | * @brief A type alias of Boost.Asio buffers_iterator. 25 | * @tparam The type of buffer sequence. 26 | * 27 | */ 28 | template 29 | using packet_iterator = as::buffers_iterator; 30 | 31 | /** 32 | * @brief Create a pair of the const buffer sequence that points begin and end. 33 | * @param cbs The sequence of const buffer. 34 | * @return The pair of the iterator. 35 | * @tparam The type of const buffer sequence. 36 | * 37 | */ 38 | template 39 | std::pair, packet_iterator> 40 | make_packet_range(ConstBufferSequence const& cbs) { 41 | return { 42 | packet_iterator::begin(cbs), 43 | packet_iterator::end(cbs) 44 | }; 45 | } 46 | 47 | /** 48 | * @brief Convert const buffer sequence to the string. 49 | * @param cbs The sequence of const buffer. 50 | * @return The string that all buffers are concatenated. 51 | * @tparam The type of const buffer sequence. 52 | * 53 | */ 54 | template 55 | std::string 56 | to_string(ConstBufferSequence const& cbs) { 57 | auto [b, e] = make_packet_range(cbs); 58 | return std::string(b, e); 59 | } 60 | 61 | } // namespace async_mqtt 62 | 63 | #endif // ASYNC_MQTT_PROTOCOL_PACKET_PACKET_ITERATOR_HPP 64 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/packet/qos.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_PACKET_QOS_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_PACKET_QOS_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace async_mqtt { 14 | 15 | /** 16 | * @brief MQTT QoS 17 | * 18 | * \n See 19 | * 20 | */ 21 | enum class qos : std::uint8_t 22 | { 23 | at_most_once = 0b00000000, ///< At most once delivery. 24 | at_least_once = 0b00000001, ///< At least once delivery. 25 | exactly_once = 0b00000010, ///< Exactly once delivery. 26 | }; 27 | 28 | /** 29 | * @brief stringize qos 30 | * @param v target 31 | * @return QoS string 32 | * 33 | */ 34 | constexpr char const* qos_to_str(qos v) { 35 | switch(v) { 36 | case qos::at_most_once: return "at_most_once"; 37 | case qos::at_least_once: return "at_least_once"; 38 | case qos::exactly_once: return "exactly_once"; 39 | default: return "invalid_qos"; 40 | } 41 | } 42 | 43 | /** 44 | * @brief output to the stream 45 | * @param o output stream 46 | * @param v target 47 | * @return output stream 48 | * 49 | */ 50 | inline 51 | std::ostream& operator<<(std::ostream& o, qos v) 52 | { 53 | o << qos_to_str(v); 54 | return o; 55 | } 56 | 57 | } // namespace async_mqtt 58 | 59 | #endif // ASYNC_MQTT_PROTOCOL_PACKET_QOS_HPP 60 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/packet/qos_util.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_PACKET_QOS_UTIL_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_PACKET_QOS_UTIL_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace async_mqtt { 14 | 15 | /** 16 | * @brief create suback_return_code corresponding to the QoS 17 | * @param q QoS 18 | * @return suback_retun_code 19 | * 20 | */ 21 | constexpr suback_return_code qos_to_suback_return_code(qos q) { 22 | return static_cast(q); 23 | } 24 | 25 | /** 26 | * @brief create suback_reason_code corresponding to the QoS 27 | * @param q QoS 28 | * @return suback_reason_code 29 | * 30 | */ 31 | constexpr suback_reason_code qos_to_suback_reason_code(qos q) { 32 | return static_cast(q); 33 | } 34 | 35 | } // namespace async_mqtt 36 | 37 | #endif // ASYNC_MQTT_PROTOCOL_PACKET_QOS_UTIL_HPP 38 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/packet/store_packet_variant_fwd.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_PACKET_STORE_PACKET_VARIANT_FWD_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_PACKET_STORE_PACKET_VARIANT_FWD_HPP 9 | 10 | #include 11 | 12 | namespace async_mqtt { 13 | 14 | /** 15 | * @brief MQTT packet variant for store 16 | * @tparam PacketIdBytes MQTT spec is 2. You can use `store_packet_variant` for that. 17 | * 18 | * #### variants 19 | * @li @ref v3_1_1::basic_publish_packet 20 | * @li @ref v3_1_1::basic_pubrel_packet 21 | * @li @ref v5::basic_publish_packet 22 | * @li @ref v5::basic_pubrel_packet 23 | * 24 | */ 25 | template 26 | class basic_store_packet_variant; 27 | 28 | /** 29 | * @brief Type alias of basic_store_packet_variant (PacketIdBytes=2). 30 | * 31 | */ 32 | using store_packet_variant = basic_store_packet_variant<2>; 33 | 34 | } // namespace async_mqtt 35 | 36 | #endif // ASYNC_MQTT_PROTOCOL_PACKET_STORE_PACKET_VARIANT_FWD_HPP 37 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/protocol_version.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_PROTOCOL_VERSION_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_PROTOCOL_VERSION_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace async_mqtt { 14 | 15 | /** 16 | * @brief MQTT protocol version 17 | * 18 | */ 19 | enum class protocol_version { 20 | undetermined = 0, ///< both v3.1.1 and v5.0 are accepted for broker (server) 21 | v3_1_1 = 4, ///< version 3.1.1 22 | v5 = 5, ///< version 5.0 23 | }; 24 | 25 | /** 26 | * @brief stringize protocol_version 27 | * @param v target 28 | * @return version string 29 | * 30 | */ 31 | constexpr char const* protocol_version_to_str(protocol_version v) { 32 | switch(v) { 33 | case protocol_version::undetermined: return "undetermined"; 34 | case protocol_version::v3_1_1: return "v3_1_1"; 35 | case protocol_version::v5: return "v5"; 36 | default: return "unknown_protocol_version"; 37 | } 38 | } 39 | 40 | /** 41 | * @brief output to the stream protocol_version 42 | * @param os output stream 43 | * @param val target 44 | * @return output stream 45 | * 46 | */ 47 | inline 48 | std::ostream& operator<<(std::ostream& os, protocol_version val) 49 | { 50 | os << protocol_version_to_str(val); 51 | return os; 52 | } 53 | 54 | } // namespace async_mqtt 55 | 56 | #endif // ASYNC_MQTT_PROTOCOL_PROTOCOL_VERSION_HPP 57 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/role.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_ASYNC_MQTT_ROLE_HPP) 8 | #define ASYNC_MQTT_ASYNC_MQTT_ROLE_HPP 9 | 10 | namespace async_mqtt { 11 | 12 | /** 13 | * @brief MQTT endpoint connection role 14 | * 15 | */ 16 | enum class role { 17 | client = 0b01, ///< as client. Can't send CONNACK, SUBACK, UNSUBACK, PINGRESP. Can send Other packets. 18 | server = 0b10, ///< as server. Can't send CONNECT, SUBSCRIBE, UNSUBSCRIBE, PINGREQ, DISCONNECT(only on v3.1.1). 19 | /// Can send Other packets. 20 | any = 0b11, ///< can send all packets. (no check) 21 | }; 22 | 23 | } // namespace async_mqtt 24 | 25 | #endif // ASYNC_MQTT_ASYNC_MQTT_ROLE_HPP 26 | -------------------------------------------------------------------------------- /include/async_mqtt/protocol/timer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2024 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_PROTOCOL_TIMER_HPP) 8 | #define ASYNC_MQTT_PROTOCOL_TIMER_HPP 9 | 10 | #include 11 | 12 | namespace async_mqtt { 13 | 14 | /** 15 | * @brief Types of timers. 16 | */ 17 | enum class timer_kind { 18 | pingreq_send, ///< Timer for sending PINGREQ. Set by the client. 19 | pingreq_recv, ///< Timer for receiving PINGREQ. Set by the server (broker). 20 | pingresp_recv, ///< Timer for receiving PINGRESP. Set by the client. 21 | }; 22 | 23 | /** 24 | * @brief Types of timer operations. 25 | */ 26 | enum class timer_op { 27 | reset, ///< Reset the timer. If a timer is set, it is canceled and then reset; otherwise, a new timer is set. 28 | cancel ///< Cancel the timer. 29 | }; 30 | 31 | /** 32 | * @brief Convert a timer_kind value to a string. 33 | * 34 | * @param v The timer kind. 35 | * @return The string representation of the given timer kind. 36 | */ 37 | constexpr 38 | char const* timer_kind_to_string(timer_kind v); 39 | 40 | /** 41 | * @brief Output a timer_kind value as a string to the stream. 42 | * 43 | * @param o The output stream. 44 | * @param v The timer kind. 45 | * @return The output stream. 46 | */ 47 | std::ostream& operator<<(std::ostream& o, timer_kind v); 48 | 49 | /** 50 | * @brief Convert a timer_op value to a string. 51 | * 52 | * @param v The timer operation. 53 | * @return The string representation of the given timer operation. 54 | */ 55 | constexpr 56 | char const* timer_op_to_string(timer_op v); 57 | 58 | /** 59 | * @brief Output a timer_op value as a string to the stream. 60 | * 61 | * @param o The output stream. 62 | * @param v The timer operation. 63 | * @return The output stream. 64 | */ 65 | std::ostream& operator<<(std::ostream& o, timer_op v); 66 | 67 | } // namespace async_mqtt 68 | 69 | #if !defined(ASYNC_MQTT_SEPARATE_COMPILATION) 70 | #include 71 | #endif // !defined(ASYNC_MQTT_SEPARATE_COMPILATION) 72 | 73 | #endif // ASYNC_MQTT_PROTOCOL_TIMER_HPP 74 | -------------------------------------------------------------------------------- /include/async_mqtt/separate/src.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2025 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_SRC_HPP) 8 | #define ASYNC_MQTT_SRC_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #endif // ASYNC_MQTT_SRC_HPP 16 | -------------------------------------------------------------------------------- /include/async_mqtt/separate/src_client.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2025 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_SEPARATE_SRC_CLIENT_HPP) 8 | #define ASYNC_MQTT_SEPARATE_SRC_CLIENT_HPP 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | #endif // ASYNC_MQTT_SEPARATE_SRC_CLIENT_HPP 30 | -------------------------------------------------------------------------------- /include/async_mqtt/separate/src_endpoint.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2025 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_SEPARATE_SRC_ENDPOINT_HPP) 8 | #define ASYNC_MQTT_SEPARATE_SRC_ENDPOINT_HPP 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | #endif // ASYNC_MQTT_SEPARATE_SRC_ENDPOINT_HPP 27 | -------------------------------------------------------------------------------- /include/async_mqtt/separate/src_rv_connection.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2025 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_SEPARATE_SRC_RV_CONNECTION_HPP) 8 | #define ASYNC_MQTT_SEPARATE_SRC_RV_CONNECTION_HPP 9 | 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | 16 | #endif // ASYNC_MQTT_SEPARATE_SRC_RV_CONNECTION_HPP 17 | -------------------------------------------------------------------------------- /include/async_mqtt/util/detail/is_iterator.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_UTIL_DETAIL_IS_ITERATOR_HPP) 8 | #define ASYNC_MQTT_UTIL_DETAIL_IS_ITERATOR_HPP 9 | 10 | #include 11 | 12 | namespace async_mqtt::detail { 13 | 14 | template 15 | using void_t = void; 16 | 17 | template 18 | struct is_input_iterator : std::false_type { 19 | }; 20 | 21 | template 22 | struct is_input_iterator< 23 | T, 24 | void_t< 25 | decltype(++std::declval()), // incrementable, 26 | decltype(*std::declval()), // dereferencable, 27 | decltype(std::declval() == std::declval()) // comparable 28 | > 29 | >: std::true_type{}; 30 | 31 | } // namespace async_mqtt::detail 32 | 33 | #endif // ASYNC_MQTT_UTIL_DETAIL_IS_ITERATOR_HPP 34 | -------------------------------------------------------------------------------- /include/async_mqtt/util/endian_convert.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_UTIL_ENDIAN_CONVERT_HPP) 8 | #define ASYNC_MQTT_UTIL_ENDIAN_CONVERT_HPP 9 | 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | 16 | namespace async_mqtt { 17 | 18 | template 19 | T endian_load(char const* buf) { 20 | static_vector usbuf(sizeof(T)); 21 | std::copy(buf, buf + sizeof(T), usbuf.data()); 22 | return boost::endian::endian_load(usbuf.data()); 23 | } 24 | 25 | template 26 | void endian_store(T val, char* buf) { 27 | static_vector usbuf(sizeof(T)); 28 | boost::endian::endian_store(usbuf.data(), val); 29 | std::copy(usbuf.begin(), usbuf.end(), buf); 30 | } 31 | 32 | template 33 | static_vector endian_static_vector(T val) { 34 | static_vector usbuf(sizeof(T)); 35 | boost::endian::endian_store(usbuf.data(), val); 36 | static_vector cbuf(sizeof(T)); 37 | std::copy(usbuf.begin(), usbuf.end(), cbuf.begin()); 38 | return cbuf; 39 | } 40 | 41 | } // namespace async_mqtt 42 | 43 | #endif // ASYNC_MQTT_UTIL_ENDIAN_CONVERT_HPP 44 | -------------------------------------------------------------------------------- /include/async_mqtt/util/inline.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2024 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_UTIL_INLINE_HPP) 8 | #define ASYNC_MQTT_UTIL_INLINE_HPP 9 | 10 | #if defined(ASYNC_MQTT_SEPARATE_COMPILATION) 11 | #define ASYNC_MQTT_HEADER_ONLY_INLINE 12 | #else // defined(ASYNC_MQTT_SEPARATE_COMPILATION) 13 | #define ASYNC_MQTT_HEADER_ONLY_INLINE inline 14 | #endif // defined(ASYNC_MQTT_SEPARATE_COMPILATION) 15 | 16 | #endif // ASYNC_MQTT_UTIL_INLINE_HPP 17 | -------------------------------------------------------------------------------- /include/async_mqtt/util/ioc_queue.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2023 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_UTIL_IOC_QUEUE_HPP) 8 | #define ASYNC_MQTT_UTIL_IOC_QUEUE_HPP 9 | 10 | #include 11 | 12 | #include 13 | 14 | namespace async_mqtt { 15 | 16 | namespace as = boost::asio; 17 | 18 | class ioc_queue { 19 | public: 20 | explicit ioc_queue() { 21 | queue_.stop(); 22 | } 23 | 24 | void start_work() { 25 | working_ = true; 26 | guard_.emplace(queue_.get_executor()); 27 | } 28 | 29 | void stop_work() { 30 | guard_.reset(); 31 | } 32 | 33 | bool immediate_executable() const { 34 | return !working_ && queue_.stopped(); 35 | } 36 | 37 | template 38 | void post(CompletionToken&& token) { 39 | as::post( 40 | queue_, 41 | std::forward(token) 42 | ); 43 | } 44 | 45 | void try_execute() { 46 | if (immediate_executable()) { 47 | queue_.restart(); 48 | queue_.poll_one(); 49 | } 50 | } 51 | 52 | bool stopped() const { 53 | return queue_.stopped(); 54 | } 55 | 56 | std::size_t poll_one() { 57 | working_ = false; 58 | if (queue_.stopped()) queue_.restart(); 59 | return queue_.poll_one(); 60 | } 61 | 62 | std::size_t poll() { 63 | working_ = false; 64 | if (queue_.stopped()) queue_.restart(); 65 | return queue_.poll(); 66 | } 67 | 68 | private: 69 | as::io_context queue_{BOOST_ASIO_CONCURRENCY_HINT_UNSAFE}; 70 | bool working_ = false; 71 | std::optional> guard_; 72 | }; 73 | 74 | } // namespace async_mqtt 75 | 76 | #endif // ASYNC_MQTT_UTIL_IOC_QUEUE_HPP 77 | -------------------------------------------------------------------------------- /include/async_mqtt/util/log_severity.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2020 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_UTIL_LOG_SEVERITY_HPP) 8 | #define ASYNC_MQTT_UTIL_LOG_SEVERITY_HPP 9 | 10 | #include 11 | 12 | namespace async_mqtt { 13 | 14 | /** 15 | * log severity level 16 | * warning is recommended for actual operation because there is no output except something important. 17 | * 18 | */ 19 | enum class severity_level { 20 | trace, ///< trace level for detaied behavior and reporting issue 21 | debug, ///< debug level not used in async_mqtt, so far 22 | info, ///< info level api call is output 23 | warning, ///< warning level such as timeout 24 | error, ///< error level error report such as connection is failed 25 | fatal ///< fatal level it is logic error of async_mqtt 26 | }; 27 | 28 | inline std::ostream& operator<<(std::ostream& o, severity_level sev) { 29 | constexpr char const* const str[] { 30 | "trace", 31 | "debug", 32 | "info", 33 | "warning", 34 | "error", 35 | "fatal" 36 | }; 37 | o << str[static_cast(sev)]; 38 | return o; 39 | } 40 | 41 | } // namespace async_mqtt 42 | 43 | #endif // ASYNC_MQTT_UTIL_LOG_SEVERITY_HPP 44 | -------------------------------------------------------------------------------- /include/async_mqtt/util/move.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_UTIL_MOVE_HPP) 8 | #define ASYNC_MQTT_UTIL_MOVE_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace async_mqtt { 14 | 15 | template 16 | constexpr 17 | typename std::remove_reference_t&& 18 | force_move(T&& t) { 19 | static_assert(!std::is_const>::value, "T is const. Fallback to copy."); 20 | return std::move(t); 21 | } 22 | 23 | } // namespace async_mqtt 24 | 25 | #endif // ASYNC_MQTT_UTIL_MOVE_HPP 26 | -------------------------------------------------------------------------------- /include/async_mqtt/util/overload.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_UTIL_OVERLOAD_HPP) 8 | #define ASYNC_MQTT_UTIL_OVERLOAD_HPP 9 | 10 | namespace async_mqtt { 11 | 12 | // overload for std::visit lambda expressions 13 | template struct overload : Ts... { using Ts::operator()...; }; 14 | template overload(Ts...) -> overload; 15 | 16 | } // namespace async_mqtt 17 | 18 | #endif // ASYNC_MQTT_UTIL_OVERLOAD_HPP 19 | -------------------------------------------------------------------------------- /include/async_mqtt/util/scope_guard.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_UTIL_SCOPE_GUARD_HPP) 8 | #define ASYNC_MQTT_UTIL_SCOPE_GUARD_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace async_mqtt { 14 | 15 | namespace detail { 16 | template 17 | class unique_sg { 18 | public: 19 | explicit unique_sg(Proc proc) 20 | :proc_{std::move(proc)} 21 | {} 22 | unique_sg(unique_sg const&) = delete; 23 | unique_sg(unique_sg&& other) 24 | :proc_{other.proc_} { 25 | other.moved_ = true; 26 | } 27 | ~unique_sg() { 28 | if (!moved_) std::move(proc_)(); 29 | } 30 | 31 | private: 32 | Proc proc_; 33 | bool moved_ = false; 34 | }; 35 | 36 | } // namespace detail 37 | 38 | template 39 | inline detail::unique_sg unique_scope_guard(Proc&& proc) { 40 | return detail::unique_sg{std::forward(proc)}; 41 | } 42 | 43 | template 44 | inline auto shared_scope_guard(Proc&& proc) { 45 | auto deleter = [proc = std::forward(proc)](void*) mutable { std::move(proc)(); }; 46 | return std::shared_ptr(nullptr, std::move(deleter)); 47 | } 48 | 49 | } // namespace async_mqtt 50 | 51 | #endif // ASYNC_MQTT_UTIL_SCOPE_GUARD_HPP 52 | -------------------------------------------------------------------------------- /include/async_mqtt/util/shared_ptr_array.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_UTIL_SHARED_PTR_ARRAY_HPP) 8 | #define ASYNC_MQTT_UTIL_SHARED_PTR_ARRAY_HPP 9 | 10 | #include 11 | 12 | namespace async_mqtt { 13 | 14 | /** 15 | * @brief shared_ptr creating function. 16 | * You can choose the target type. 17 | * - if your compiler setting is C++20 or later, then `std::make_shared(size)` is used. 18 | * - It can allocate an array of characters and the control block in a single allocation. 19 | * - otherwise `std::shared_ptr(new char[size])` is used. 20 | * - It requires two times allocations. 21 | * @param size of char array 22 | * @return shared_ptr of array 23 | */ 24 | inline std::shared_ptr make_shared_ptr_char_array(std::size_t size) { 25 | #if __cpp_lib_shared_ptr_arrays >= 201707L 26 | return std::make_shared(size); 27 | #else // __cpp_lib_shared_ptr_arrays >= 201707L 28 | return std::shared_ptr(new char[size]); 29 | #endif // __cpp_lib_shared_ptr_arrays >= 201707Lhai 30 | } 31 | 32 | } // namespace async_mqtt 33 | 34 | #endif // ASYNC_MQTT_UTIL_SHARED_PTR_ARRAY_HPP 35 | -------------------------------------------------------------------------------- /include/async_mqtt/util/static_vector.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_UTIL_STATIC_VECTOR_HPP) 8 | #define ASYNC_MQTT_UTIL_STATIC_VECTOR_HPP 9 | 10 | #include 11 | 12 | namespace async_mqtt { 13 | 14 | template 15 | using static_vector = boost::container::static_vector; 16 | 17 | } // namespace async_mqtt 18 | 19 | #endif // ASYNC_MQTT_UTIL_STATIC_VECTOR_HPP 20 | -------------------------------------------------------------------------------- /include/async_mqtt/util/string_view_helper.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2016 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_UTIL_STRING_VIEW_HELPER_HPP) 8 | #define ASYNC_MQTT_UTIL_STRING_VIEW_HELPER_HPP 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace async_mqtt { 15 | 16 | namespace detail { 17 | 18 | template 19 | T* to_address(T* p) noexcept 20 | { 21 | return p; 22 | } 23 | 24 | template 25 | auto to_address(const T& p) noexcept 26 | { 27 | return detail::to_address(p.operator->()); 28 | } 29 | 30 | } // namespace detail 31 | 32 | // Make a string_view from a pair of iterators. 33 | template 34 | std::string_view make_string_view(Begin begin, End end) { 35 | static_assert( 36 | std::is_same_v< 37 | typename std::iterator_traits::iterator_category, 38 | std::random_access_iterator_tag 39 | > 40 | ); 41 | return std::string_view( 42 | detail::to_address(begin), 43 | static_cast(std::distance(begin, end)) 44 | ); 45 | } 46 | 47 | } // namespace async_mqtt 48 | 49 | #endif // ASYNC_MQTT_UTIL_STRING_VIEW_HELPER_HPP 50 | -------------------------------------------------------------------------------- /include/async_mqtt/util/variable_bytes.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_UTIL_VARIABLE_BYTES_HPP) 8 | #define ASYNC_MQTT_UTIL_VARIABLE_BYTES_HPP 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | namespace async_mqtt { 17 | 18 | inline static_vector 19 | val_to_variable_bytes(std::uint32_t val) { 20 | static_vector bytes; 21 | if (val > 0xfffffff) return bytes; 22 | while (val > 127) { 23 | bytes.push_back(static_cast((val & 0b01111111) | 0b10000000)); 24 | val >>= 7; 25 | } 26 | bytes.push_back(val & 0b01111111); 27 | return bytes; 28 | } 29 | 30 | 31 | template 32 | constexpr 33 | std::enable_if_t< 34 | detail::is_input_iterator::value && 35 | detail::is_input_iterator::value, 36 | std::optional 37 | > 38 | variable_bytes_to_val(It& it, End e) { 39 | std::size_t val = 0; 40 | std::size_t mul = 1; 41 | for (; it != e; ++it) { 42 | if (mul == 128 * 128 * 128 * 128) { 43 | ++it; 44 | return std::nullopt; 45 | } 46 | val += (*it & 0b01111111) * mul; 47 | mul *= 128; 48 | if (!(*it & 0b10000000)) { 49 | ++it; 50 | return std::uint32_t(val); 51 | } 52 | } 53 | return std::nullopt; 54 | } 55 | 56 | } // namespace async_mqtt 57 | 58 | #endif // ASYNC_MQTT_UTIL_VARIABLE_BYTES_HPP 59 | -------------------------------------------------------------------------------- /lib/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Separate compilation library 2 | 3 | file(GLOB_RECURSE ASIO_BIND_IPP ${CMAKE_CURRENT_SOURCE_DIR} "../include/async_mqtt/asio_bind/impl/*.ipp") 4 | set_source_files_properties(${ASIO_BIND_IPP} PROPERTIES LANGUAGE CXX) 5 | add_library(async_mqtt_asio_bind ${ASIO_BIND_IPP}) 6 | target_compile_definitions(async_mqtt_asio_bind PRIVATE ASYNC_MQTT_SEPARATE_COMPILATION ASYNC_MQTT_INDIVIDUAL_INSTANTIATE) 7 | if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") 8 | target_compile_options(async_mqtt_asio_bind PRIVATE -x c++) 9 | endif() 10 | 11 | file(GLOB_RECURSE PROTOCOL_IPP ${CMAKE_CURRENT_SOURCE_DIR} "../include/async_mqtt/protocol/*.ipp") 12 | set_source_files_properties(${PROTOCOL_IPP} PROPERTIES LANGUAGE CXX) 13 | add_library(async_mqtt_protocol ${PROTOCOL_IPP}) 14 | target_compile_definitions(async_mqtt_protocol PRIVATE ASYNC_MQTT_SEPARATE_COMPILATION ASYNC_MQTT_INDIVIDUAL_INSTANTIATE) 15 | if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") 16 | target_compile_options(async_mqtt_protocol PRIVATE -x c++) 17 | endif() 18 | 19 | if(ASYNC_MQTT_USE_LOG) 20 | target_compile_definitions( 21 | async_mqtt_asio_bind 22 | PRIVATE 23 | $,,BOOST_LOG_DYN_LINK> 24 | ) 25 | target_compile_definitions( 26 | async_mqtt_protocol 27 | PRIVATE 28 | $,,BOOST_LOG_DYN_LINK> 29 | ) 30 | endif() 31 | 32 | macro(fix_msvc_build) 33 | message(STATUS "MSVC build fix applied") 34 | target_compile_options(async_mqtt_asio_bind PRIVATE "/Zc:preprocessor" "/bigobj") 35 | target_compile_options(async_mqtt_protocol PRIVATE "/Zc:preprocessor" "/bigobj") 36 | endmacro() 37 | 38 | if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") 39 | fix_msvc_build() 40 | endif() 41 | 42 | target_link_libraries(async_mqtt_asio_bind async_mqtt_iface) 43 | target_link_libraries(async_mqtt_protocol async_mqtt_iface) 44 | -------------------------------------------------------------------------------- /llvm-gcov.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | exec llvm-cov gcov "$@" 3 | -------------------------------------------------------------------------------- /makedoc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | rm -rf .tmp_doc 3 | mkdir .tmp_doc 4 | cd .tmp_doc 5 | git clone --branch doc https://github.com/redboltz/async_mqtt.git 6 | cp ../CHANGELOG.adoc async_mqtt 7 | bundle exec asciidoxy --base-dir async_mqtt async_mqtt/index.adoc --destination-dir ../doc --multipage -r asciidoctor-diagram --image-dir async_mqtt/img 8 | 9 | rm -rf ../doc/api 10 | cmake -DASYNC_MQTT_USE_TLS=ON -DASYNC_MQTT_USE_WS=ON .. 11 | make doxygen 12 | mv doc/html ../doc/api 13 | cd .. 14 | rm -rf .tmp_doc 15 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright Takatoshi Kondo 2022 2 | # 3 | # Distributed under the Boost Software License, Version 1.0. 4 | # (See accompanying file LICENSE_1_0.txt or copy at 5 | # http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | if(ASYNC_MQTT_BUILD_UNIT_TESTS) 8 | add_subdirectory(unit) 9 | message(STATUS "Unit tests enabled") 10 | else() 11 | message(STATUS "Unit tests disabled") 12 | endif() 13 | 14 | if(ASYNC_MQTT_BUILD_SYSTEM_TESTS) 15 | add_subdirectory (system) 16 | message(STATUS "System tests enabled") 17 | else() 18 | message(STATUS "System tests disabled") 19 | endif() 20 | -------------------------------------------------------------------------------- /test/args_provider.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | echo $1 $(echo ${CTEST_ARGS}) 4 | $1 $(echo ${CTEST_ARGS}) 5 | -------------------------------------------------------------------------------- /test/certs/cacert.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDAzCCAeugAwIBAgIUU03m5DevP1EHB/mDSdiWnesMIDwwDQYJKoZIhvcNAQEL 3 | BQAwETEPMA0GA1UEAwwGcm9vdGNhMB4XDTIwMDkyOTAyMTcxNFoXDTQ4MDIxNTAy 4 | MTcxNFowETEPMA0GA1UEAwwGcm9vdGNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A 5 | MIIBCgKCAQEA2Avsj2Y0lzsLmM5jrND1/EmpKTNhYlNITsvsk0Pq43zVLJkLs3JH 6 | DfEmmOnICdibniqpvbzX4i5aKM3V83iBsKIXBXVEf5+0lPwYbhgNZK5VfskP2jw0 7 | epH6hlj03S/DlszZtS9MsGabWCkWN0wpEKAk39wW90Flr6AKpg4bXnEcBDG+k04y 8 | PfhUjNvamhThjrsGYrMBg/EUmvqxhirUxq862zjD3rgOGOepm0NCEDmNwvlKXDA8 9 | SN7aZMO8ZO+/R8JiJBOb2Q3XUYVXJt7erxrHt0AZ5JpkYZscPZeEYHEKf0xnxq0e 10 | C2W9h0OWeKr6/7gTY0Vvc1gy5ff8JDgFbwIDAQABo1MwUTAdBgNVHQ4EFgQUhZUL 11 | PUzCqzmAXn+NjfAIB4grCo0wHwYDVR0jBBgwFoAUhZULPUzCqzmAXn+NjfAIB4gr 12 | Co0wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAQd6INt2vReUr 13 | 8NKde+W36JLbRxMR6rmbljS6MpqUTIcqw9htNQpv+/zi+FUcyFjaS8gF4e3eHDs2 14 | lssGL9tnP3OPUzsHpqaqjHbcghg+9l9WmLjV5x3zsYiW9qkdnd7UH+2s559J8xP9 15 | HsNALP2mtdre0p4nzW9Wa5srvLTYIwfZP2IJbp1JlYfBzBZ2DIddI9D+RIQY4Ban 16 | /Zts58FYjivtn9z5jN+RQ/z5BUiQdkuxqZG0R6syfrvorqgTlzEIzrwlWIlsqNFl 17 | 3IrtRIAjd1U9D8P4xzHj/3kQyRcUXmNlq6npod+bZdx1/xF33LR343KZfv0c01C6 18 | K4ngI65jVQ== 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /test/certs/client.crt.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDcTCCAlmgAwIBAgIUQ1J1bxX3IoBolCv6kfpckYag7WYwDQYJKoZIhvcNAQEL 3 | BQAwETEPMA0GA1UEAwwGcm9vdGNhMB4XDTIxMDUyMTEwMTAzNFoXDTQ4MTAwNjEw 4 | MTAzNFowDzENMAsGA1UEAwwEY2lkMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC 5 | AQoCggEBAKkTZadltzY+ylAIap6AoFtEE137ZxU1rItTcAhOMeEpCL1w1Wdxm6oo 6 | setmjnnX+0asS8V6niRfFGr08CMbRWPwEoNcfb8YSidgmSOF2OW+aay9A7R99H/i 7 | c+OAa1KO0laEoBl4cYKl976gwrooFu4wznYCXAPzUrOLQxAWY+vbUnYJHfLBiXdp 8 | 4/b/6bdNV5Ot3/ZpzaKayEozvXjL1DJrQq+vL9+avOHKG+h+Smh1d4SogcNENvsn 9 | /73Cw7PGnXb8niguxd6vjjFfe4F1SbRBxU9WBtcQxBHbJPxRU2JEA2QtxmU9th/T 10 | 3RCUsPoxbwPL0k5DaajURrtXpotDk7MCAwEAAaOBwjCBvzBMBgNVHSMERTBDgBSF 11 | lQs9TMKrOYBef42N8AgHiCsKjaEVpBMwETEPMA0GA1UEAwwGcm9vdGNhghRTTebk 12 | N68/UQcH+YNJ2Jad6wwgPDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIFoDATBgNVHSUE 13 | DDAKBggrBgEFBQcDAjAxBglghkgBhvhCAQ0EJBYiT3BlblNTTCBDZXJ0aWZpY2F0 14 | ZSBmb3IgU1NMIENsaWVudDAPBgNVHREECDAGggRjaWQxMA0GCSqGSIb3DQEBCwUA 15 | A4IBAQAX9VAlG6wfBJpKUY1lxui2nTfk0JsYY+6enc+/G8WNNL1fobeJUwCKzdTQ 16 | SQPzg4qYpxbqV1qn4X3cQfHXvdgvVfWUNYH9eGnKLe6PH/e1F/qC5T7G2SFe4uQ9 17 | VOOHt4R9zOX6BuYCfwTKwt0+dbLuR7RONzM8MIzfCdbbfOvmcvq6+9vS5WrHgxGE 18 | dzCM8B7hp0DTtpTEAFnXDCPTViN1QCTmfTGvEDIgMRI8xXB20oCN/SEUtxJ4vleu 19 | dpjLJIXPrbzXKB8czmLFCJg3tOgRqRi9BtT4+IR8THqq/SFWRCp3C9JsZipgnwu5 20 | HqX8HmgF0F09RZMKRACwhZXF9ELA 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /test/certs/client.key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEowIBAAKCAQEAqRNlp2W3Nj7KUAhqnoCgW0QTXftnFTWsi1NwCE4x4SkIvXDV 3 | Z3Gbqiix62aOedf7RqxLxXqeJF8UavTwIxtFY/ASg1x9vxhKJ2CZI4XY5b5prL0D 4 | tH30f+Jz44BrUo7SVoSgGXhxgqX3vqDCuigW7jDOdgJcA/NSs4tDEBZj69tSdgkd 5 | 8sGJd2nj9v/pt01Xk63f9mnNoprISjO9eMvUMmtCr68v35q84cob6H5KaHV3hKiB 6 | w0Q2+yf/vcLDs8addvyeKC7F3q+OMV97gXVJtEHFT1YG1xDEEdsk/FFTYkQDZC3G 7 | ZT22H9PdEJSw+jFvA8vSTkNpqNRGu1emi0OTswIDAQABAoIBAEbgU7/NuvTpc4QD 8 | UzaosxAvRHMkXX0dp/wr+Q3yQaSiwAAyGbOog1ncf2Ev99AKA1MIDSd2lG6o0PVZ 9 | QoVk/Dy9ufUJQ8lk1EkXjHrAtEDzBnecML5sAp/NfUlEXzkXmAMey8KBpAvhqS5n 10 | U9oXzi0BlrsPmCUrzmJnobBPwolvE83OR0zTQKbRBzH26PStYgFnDolJmexFHAAh 11 | q1if+JgwosTYliXtzB4SOF1+psMjGDX8SLYHaInIfvAVrJTx9Y/1ykk1102Oak5h 12 | v3qAV5QW3qG8709EU5iFWfmwwaOJcttN7FlZ9GptyssPLkOFF6pmgqDdSvz+FG86 13 | Qj1pw7kCgYEA2h5bQFp2IcxZKeeM5ouwlwt1AhOMBdkAy9QAXmg7exro0fQbI6px 14 | g6JbB7aTDqCRfq1tjlix2wkFjEu+vsGifg/JifRpBa9FO5qiunuXjIn73Vu5zoEU 15 | cCv/0y/abCFjuAeJ5VQdeIs6SKC5WZN6UTtmgA+eVkPIFphvqoB7RDUCgYEAxnCT 16 | pKGsQRlxYB7qpAQvBgBogI0vD7weIosKEYZfFJeKPXf2O+mI4l2hlGXi9N75Hwax 17 | Wen8+4TXMw9sSyTKPlcmdbCNRKGHc+TjjnNURofVVcLqyn/6Ht6DsgvgqYuZKiKl 18 | PiwUrcS8ay1aTwlHKk+tJV+3S1a5jykwhc5YJUcCgYEAr1yMnNad91plrU0eeRSB 19 | 604oynyQrPrkqvtNOJmwiK7/1Bzf3PLhxKU5bqAY5z+s+h3Q4QrqI2HDdiJHvvHL 20 | BHMI48L+1LUvglY20psfIrylJDjkz+PzXKPjUBU/FIRbuc9FzHyuHQZC27Vsj1oE 21 | k16gcAEemdhw+8merYQSlqkCgYB5Jwo9HSfZpvr9QGLpOFStSVqEAa6V4LhVRqYj 22 | BPLP06Vm2fLPqUkVSyz3OS1Taz6VnrRwvNbjiLsKRYRMbG29md+1QtE88ZGNRFVa 23 | BzeQyCWLcrF+aJwAdMHa1j2Xxc8BVp2kU61cWhzfIpVcY8G7J2ICy2lQ6eXobbFe 24 | QBi4yQKBgH0yOAUk3vC5FVaFvFzohJ8yFM9OjwrSuoaAKHFtRroAUgBtX1dTRSKg 25 | /GzeJdsA0vH4bfZKKxaFgRo+RfAi9s6ZmxBQWf6MgB1PlU1IWNVYqBceZZ97j7Ln 26 | wscsOgt0Sa7CPpE3Ww8P6dX3leH1/uRYgAC97p61h+rXVPHTIgl0 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /test/certs/mosquitto.org.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIC8DCCAlmgAwIBAgIJAOD63PlXjJi8MA0GCSqGSIb3DQEBBQUAMIGQMQswCQYD 3 | VQQGEwJHQjEXMBUGA1UECAwOVW5pdGVkIEtpbmdkb20xDjAMBgNVBAcMBURlcmJ5 4 | MRIwEAYDVQQKDAlNb3NxdWl0dG8xCzAJBgNVBAsMAkNBMRYwFAYDVQQDDA1tb3Nx 5 | dWl0dG8ub3JnMR8wHQYJKoZIhvcNAQkBFhByb2dlckBhdGNob28ub3JnMB4XDTEy 6 | MDYyOTIyMTE1OVoXDTIyMDYyNzIyMTE1OVowgZAxCzAJBgNVBAYTAkdCMRcwFQYD 7 | VQQIDA5Vbml0ZWQgS2luZ2RvbTEOMAwGA1UEBwwFRGVyYnkxEjAQBgNVBAoMCU1v 8 | c3F1aXR0bzELMAkGA1UECwwCQ0ExFjAUBgNVBAMMDW1vc3F1aXR0by5vcmcxHzAd 9 | BgkqhkiG9w0BCQEWEHJvZ2VyQGF0Y2hvby5vcmcwgZ8wDQYJKoZIhvcNAQEBBQAD 10 | gY0AMIGJAoGBAMYkLmX7SqOT/jJCZoQ1NWdCrr/pq47m3xxyXcI+FLEmwbE3R9vM 11 | rE6sRbP2S89pfrCt7iuITXPKycpUcIU0mtcT1OqxGBV2lb6RaOT2gC5pxyGaFJ+h 12 | A+GIbdYKO3JprPxSBoRponZJvDGEZuM3N7p3S/lRoi7G5wG5mvUmaE5RAgMBAAGj 13 | UDBOMB0GA1UdDgQWBBTad2QneVztIPQzRRGj6ZHKqJTv5jAfBgNVHSMEGDAWgBTa 14 | d2QneVztIPQzRRGj6ZHKqJTv5jAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUA 15 | A4GBAAqw1rK4NlRUCUBLhEFUQasjP7xfFqlVbE2cRy0Rs4o3KS0JwzQVBwG85xge 16 | REyPOFdGdhBY2P1FNRy0MDr6xr+D2ZOwxs63dG1nnAnWZg7qwoLgpZ4fESPD3PkA 17 | 1ZgKJc2zbSQ9fCPxt2W3mdVav66c6fsb7els2W2Iz7gERJSX 18 | -----END CERTIFICATE----- 19 | -------------------------------------------------------------------------------- /test/certs/server.crt.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDUjCCAjqgAwIBAgIUQ1J1bxX3IoBolCv6kfpckYag7WUwDQYJKoZIhvcNAQEL 3 | BQAwETEPMA0GA1UEAwwGcm9vdGNhMB4XDTIxMDUyMTEwMTAxOVoXDTQ4MTAwNjEw 4 | MTAxOVowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOC 5 | AQ8AMIIBCgKCAQEArhWwTP0YY40Dc9xgLHvy4rm0NLM2JJvqQJcVryfQb3SIisYx 6 | KQx41biCzOyFE+5/ZO0VLSKUD7QdOAZIaARVzWSgNuOSj5ed0IAsBKkEOF/1oozn 7 | ww0efPNM51ahy1heG0pLeRBPeyHPRyvAOsVYgmkdkxnOFAFPl/rPYgmYAW7SWfvx 8 | V6kI7DLfo50MpohqGFiPnvwpXtLTMH9Wl/ChA0XGDSFyqZC1PI9EtWCkw6nwiauV 9 | F/8/p8HNJ9+Mq5MmdKmHaLsrddy07nIvg3lShYWXevRVi1vK1fLIHYrU6jYNpY3I 10 | 3X0C97Y2sa61MceIRy3Eum7PVH06gtwUjIreGQIDAQABo4GeMIGbMEwGA1UdIwRF 11 | MEOAFIWVCz1Mwqs5gF5/jY3wCAeIKwqNoRWkEzARMQ8wDQYDVQQDDAZyb290Y2GC 12 | FFNN5uQ3rz9RBwf5g0nYlp3rDCA8MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgQwMB0G 13 | A1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAUBgNVHREEDTALgglsb2NhbGhv 14 | c3QwDQYJKoZIhvcNAQELBQADggEBAEKKkTIxtVUrRyT+9RspolZdheK9dWqPGQCP 15 | mDKnHON8nhK2VGUgqEBwQOU9tHsluimQY3XhQowEsOFLV1dgIt4fdUuHDheCD1RI 16 | wkDdO/d/dZDk83ViuRFiPyZsRmVXIR49QkXQsvh8/q6EG9peVCiPlxLJE5n3ITa9 17 | P9019WJ16BMrVaJqQHI5kYLGIFrb2HD0SUdQj0ORr0mwsGdZCk3Y08d92Wgicgg+ 18 | 74Qqdl8jiZnluShUAZeUa5KvOz5SAFHePOkE8fj6klIFUcUamAKrwxaaGNUs0NXo 19 | JgUwwL3L9QVgt4dmmsNB4NEM5Kref8A+Py1WfLVetIW8t9wNWb8= 20 | -----END CERTIFICATE----- 21 | -------------------------------------------------------------------------------- /test/certs/server.key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpAIBAAKCAQEArhWwTP0YY40Dc9xgLHvy4rm0NLM2JJvqQJcVryfQb3SIisYx 3 | KQx41biCzOyFE+5/ZO0VLSKUD7QdOAZIaARVzWSgNuOSj5ed0IAsBKkEOF/1oozn 4 | ww0efPNM51ahy1heG0pLeRBPeyHPRyvAOsVYgmkdkxnOFAFPl/rPYgmYAW7SWfvx 5 | V6kI7DLfo50MpohqGFiPnvwpXtLTMH9Wl/ChA0XGDSFyqZC1PI9EtWCkw6nwiauV 6 | F/8/p8HNJ9+Mq5MmdKmHaLsrddy07nIvg3lShYWXevRVi1vK1fLIHYrU6jYNpY3I 7 | 3X0C97Y2sa61MceIRy3Eum7PVH06gtwUjIreGQIDAQABAoIBAFvo9YjgQ4UjyUPd 8 | gSVbV5Qeqab9S0Ou0dHCMt+kLKb7pq9mDkR24kEsRlq9MVGhpL77cSfATt2voZGX 9 | t5i7WTW0v+Xa5uFLEjYnxZW8So8dEsn8jMxtW8BqkBq/oXKDuEO+SPSlCOGgqxgP 10 | YFFnKeDIcKXehPAI9SXvdJh1Kjzuj9K81QfYDDbc30424p5qotW8F1ldJN6T709R 11 | DqKttvLPO1lsr43kjMLwT5pbpdvFS4H2TweeC4y/woM6LUKehlMPVO39aop0MOfF 12 | aGQj0OGjAfhfmjVvG1DGT++sdO5+CaRAUj7XDAX7y7fELCbovrQqKnxBeCg4Z6yF 13 | zkicDwUCgYEA1LYJ8EeR83I1uuo18eZvebQYTIukoFVdHYBqTO+SiP4cot0p8UrX 14 | rkGPDrM5Hhl20n6tWR20CImEDbkKuEHX9IwwxJJwAqg5M1UbHtW0re3eLQeBn5GW 15 | JP2mfjK6ffTWuOcqXzt6VhRnIqLk1TacQSKxXD3FmSn17/tZ53jRptMCgYEA0YNE 16 | pCNxxLqBFuF46gr/z7lSLk3iNqe/Xw4uwXa8JeGdyHfI+bvqRm1xOnrJhlvAONL2 17 | 8lq/y1Ye6m8SBxDHco92GuSov4WQL45MjO1lEx3/xe6lVdo27huzyG0wiD27MQGV 18 | PR011JqB+cnZVM4Nj3rG87JLQr8AAgnAHIfXq+MCgYBJwFBT2kzVjtzoUPqhQ9eU 19 | 6Aegyq4q1U4yw2qYAFzbWNgO9AXt3phHl/2FCEkekY+sTjXGd1ELwLpjk6wO1O2O 20 | oejqzyc9FJy4mqKLn2dFAvuMu1SLQgxACR5oFSiqMXEdrTD40gOJwws7bCVRc9zb 21 | jK7YH6bagzz9lzXF1xNB9wKBgQCRTpZztHV6ONPBF72xrNFAs0ow/SlQOMV8WqzI 22 | 1t2k9DZnS9Sih9by44KtSW2tdsL5Zi+JZLEyiFdGxqPdLKD3blI+UqpKsoqOwQWM 23 | lDUOrjavg1U+FusT9ziYYEpRo2bJlUx5J2InQsW0hW7q50H2afPEHrsd3rRVtYd9 24 | AiXtewKBgQC3z+7k6av30wvnStXWKTb4utPmvhAU+T8iXOM/3nq83S+OMArcAX9b 25 | 5xcccDK9iy1s7MnLrA2NIJwmKCOk0OMcxWLHLyyC5X2tOc0uVGZau4aF4HsI63O6 26 | eVP9RpwPSu8vMOZf4SWNlcv5iq/zH1KFW5wR/JNTAwYf0xgyb+rgYA== 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /test/common/global_fixture.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_GLOBAL_FIXTURE_HPP) 8 | #define ASYNC_MQTT_GLOBAL_FIXTURE_HPP 9 | 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | 16 | struct global_fixture { 17 | void setup() { 18 | auto sev = 19 | [&] { 20 | auto argc = boost::unit_test::framework::master_test_suite().argc; 21 | if (argc >= 2) { 22 | auto argv = boost::unit_test::framework::master_test_suite().argv; 23 | auto sevstr = std::string_view(argv[1]); 24 | if (sevstr == "fatal") { 25 | return async_mqtt::severity_level::fatal; 26 | } 27 | else if (sevstr == "error") { 28 | return async_mqtt::severity_level::error; 29 | } 30 | else if (sevstr == "warning") { 31 | return async_mqtt::severity_level::warning; 32 | } 33 | else if (sevstr == "info") { 34 | return async_mqtt::severity_level::info; 35 | } 36 | else if (sevstr == "debug") { 37 | return async_mqtt::severity_level::debug; 38 | } 39 | else if (sevstr == "trace") { 40 | return async_mqtt::severity_level::trace; 41 | } 42 | } 43 | return async_mqtt::severity_level::warning; 44 | } (); 45 | async_mqtt::setup_log(sev); 46 | } 47 | void teardown() { 48 | } 49 | }; 50 | 51 | BOOST_TEST_GLOBAL_FIXTURE(global_fixture); 52 | 53 | #endif // ASYNC_MQTT_GLOBAL_FIXTURE_HPP 54 | -------------------------------------------------------------------------------- /test/common/test_main.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_TEST_MAIN_HPP) 8 | #define ASYNC_MQTT_TEST_MAIN_HPP 9 | 10 | #define BOOST_TEST_MODULE async_mqtt_test 11 | #include 12 | 13 | #endif // ASYNC_MQTT_TEST_MAIN_HPP 14 | -------------------------------------------------------------------------------- /test/system/coro_base.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2023 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_TEST_SYSTEM_CORO_BASE_HPP) 8 | #define ASYNC_MQTT_TEST_SYSTEM_CORO_BASE_HPP 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | #include 16 | 17 | namespace as = boost::asio; 18 | namespace am = async_mqtt; 19 | 20 | template 21 | struct coro_base : as::coroutine { 22 | coro_base(Ep& ep) 23 | :eps_{ep} 24 | {} 25 | coro_base(std::vector> eps) 26 | :eps_(am::force_move(eps)) 27 | {} 28 | 29 | virtual ~coro_base() = default; 30 | 31 | void operator()(am::error_code const& ec = am::error_code{}) { 32 | proc(ec, std::nullopt, 0); 33 | } 34 | void operator()(am::error_code const& ec, std::optional> pv_opt) { 35 | proc(ec, am::force_move(pv_opt), 0); 36 | } 37 | void operator()(am::error_code const& ec, typename am::basic_packet_id_type::type pid) { 38 | proc(ec, std::nullopt, pid); 39 | } 40 | bool finish() const { 41 | return *finish_; 42 | } 43 | protected: 44 | Ep& ep(std::size_t idx = 0) { return eps_.at(idx).get(); } 45 | Ep const& ep(std::size_t idx = 0) const { return eps_.at(idx).get(); } 46 | void set_finish() { 47 | *finish_ = true; 48 | } 49 | private: 50 | virtual void proc( 51 | am::error_code ec, 52 | std::optional> pv_opt, 53 | typename am::basic_packet_id_type::type pid 54 | ) = 0; 55 | std::vector> eps_; 56 | std::shared_ptr finish_ = std::make_shared(false); 57 | }; 58 | 59 | #endif // ASYNC_MQTT_TEST_SYSTEM_CORO_BASE_HPP 60 | -------------------------------------------------------------------------------- /test/system/st_auth.json: -------------------------------------------------------------------------------- 1 | { 2 | // Grant users to connect the broker 3 | "authentication": [ 4 | { 5 | "name": "u1", 6 | "method": "plain_password", 7 | "password": "passforu1" 8 | } 9 | , 10 | { 11 | // Authenticates user by client certificate 12 | "name": "cid1", 13 | "method": "client_cert" 14 | } 15 | , 16 | { 17 | "name": "u3", 18 | "method": "sha256", 19 | "salt": "mysalt", 20 | /* 21 | mysaltpassforu3 22 | you can get it `echo -n mysaltpassforu3 | sha256sum` 23 | don't forget -n 24 | */ 25 | "digest": "9ed77f119f694e5e543201a97cc8db226cf36c814c4406fe2eac5b9b1f084ba9" 26 | } 27 | ] 28 | , 29 | // Grant users an groups to access topics 30 | "authorization": [ 31 | { 32 | // Specified users and groups are denied to subscribe and publish on this topic 33 | "topic": "#", 34 | "allow": { 35 | "sub": ["u1"], 36 | "pub": ["u1"] 37 | } 38 | } 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /test/system/st_broker.conf: -------------------------------------------------------------------------------- 1 | # Default configuration for async_mqtt Broker 2 | # print program options 3 | silent=true 4 | # log severity 0:fatal, 1:error, 2:warning, 3:info, 4:debug, 5:trace 5 | verbose=2 6 | # for TLS 7 | certificate=server.crt.pem 8 | private_key=server.key.pem 9 | # for Client Certificate Verification 10 | verify_file=cacert.pem 11 | 12 | # for MQTT auth 13 | auth_file=st_auth.json 14 | 15 | # 0 means automatic 16 | # Num of vCPU 17 | iocs=1 18 | 19 | # 0 means automatic 20 | # min(4 or Num of vCPU) 21 | threads_per_ioc=1 22 | 23 | # Configuration for TCP 24 | [tcp] 25 | port=1883 26 | 27 | # Configuration for TLS 28 | [tls] 29 | port=8883 30 | 31 | # Configuration for Websocket 32 | [ws] 33 | port=10080 34 | 35 | # Configuration for Websocket with TLS 36 | [wss] 37 | port=10443 38 | -------------------------------------------------------------------------------- /test/unit/test_allocate_buffer.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_TEST_UNI_ALLOCATE_BUFFER_HPP) 8 | #define ASYNC_MQTT_TEST_UNI_ALLOCATE_BUFFER_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace async_mqtt { 14 | 15 | template 16 | inline buffer allocate_buffer(Iterator b, Iterator e) { 17 | auto size = static_cast(std::distance(b, e)); 18 | if (size == 0) return buffer(&*b, size); 19 | auto spca = make_shared_ptr_char_array(size); 20 | std::copy(b, e, spca.get()); 21 | auto p = spca.get(); 22 | return buffer(p, size, force_move(spca)); 23 | } 24 | 25 | inline buffer allocate_buffer(std::string_view sv) { 26 | return allocate_buffer(sv.begin(), sv.end()); 27 | } 28 | 29 | } // namespace async_mqtt 30 | 31 | #endif // ASYNC_MQTT_TEST_UNI_ALLOCATE_BUFFER_HPP 32 | -------------------------------------------------------------------------------- /test/unit/ut_connection_status.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2025 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include "../common/test_main.hpp" 8 | #include "../common/global_fixture.hpp" 9 | 10 | #include 11 | 12 | BOOST_AUTO_TEST_SUITE(ut_connection_status) 13 | 14 | namespace am = async_mqtt; 15 | 16 | 17 | BOOST_AUTO_TEST_CASE(status) { 18 | { 19 | std::stringstream ss; 20 | ss << am::connection_status::connected; 21 | BOOST_TEST(ss.str() == "connected"); 22 | } 23 | { 24 | std::stringstream ss; 25 | ss << am::connection_status::connecting; 26 | BOOST_TEST(ss.str() == "connecting"); 27 | } 28 | { 29 | std::stringstream ss; 30 | ss << am::connection_status::disconnected; 31 | BOOST_TEST(ss.str() == "disconnected"); 32 | } 33 | { 34 | std::stringstream ss; 35 | ss << static_cast(3); 36 | BOOST_TEST(ss.str() == "unknown_connection_status"); 37 | } 38 | } 39 | 40 | BOOST_AUTO_TEST_SUITE_END() 41 | -------------------------------------------------------------------------------- /test/unit/ut_multi_file1.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2023 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | -------------------------------------------------------------------------------- /test/unit/ut_multi_file2.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2023 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include 8 | 9 | int main() { 10 | } 11 | -------------------------------------------------------------------------------- /test/unit/ut_null_strand.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2024 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include "../common/test_main.hpp" 8 | #include "../common/global_fixture.hpp" 9 | 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | #include "stub_socket.hpp" 18 | 19 | BOOST_AUTO_TEST_SUITE(ut_null_strand) 20 | 21 | namespace am = async_mqtt; 22 | namespace as = boost::asio; 23 | 24 | // v3_1_1 25 | 26 | BOOST_AUTO_TEST_CASE(epst) { 27 | auto version = am::protocol_version::v3_1_1; 28 | as::io_context ioc; 29 | auto guard = as::make_work_guard(ioc.get_executor()); 30 | std::thread th { 31 | [&] { 32 | ioc.run(); 33 | } 34 | }; 35 | 36 | auto ep = am::endpoint_st{ 37 | version, 38 | // for stub_socket args 39 | version, 40 | ioc.get_executor() 41 | }; 42 | auto fut1 = ep->async_acquire_unique_packet_id_wait_until(as::use_future); 43 | auto pid1 = fut1.get(); 44 | BOOST_TEST(pid1 == 1); 45 | 46 | guard.reset(); 47 | th.join(); 48 | } 49 | 50 | BOOST_AUTO_TEST_CASE(bep) { 51 | auto version = am::protocol_version::v3_1_1; 52 | as::io_context ioc; 53 | auto guard = as::make_work_guard(ioc.get_executor()); 54 | std::thread th { 55 | [&] { 56 | ioc.run(); 57 | } 58 | }; 59 | 60 | auto ep = am::basic_endpoint{ 61 | version, 62 | // for stub_socket args 63 | version, 64 | ioc.get_executor() 65 | }; 66 | auto fut1 = ep->async_acquire_unique_packet_id_wait_until(as::use_future); 67 | auto pid1 = fut1.get(); 68 | BOOST_TEST(pid1 == 1); 69 | 70 | guard.reset(); 71 | th.join(); 72 | } 73 | 74 | BOOST_AUTO_TEST_SUITE_END() 75 | -------------------------------------------------------------------------------- /test/unit/ut_packet_variant.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2024 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include "../common/test_main.hpp" 8 | #include "../common/global_fixture.hpp" 9 | 10 | 11 | #include 12 | 13 | #include 14 | 15 | BOOST_AUTO_TEST_SUITE(ut_packet_variant) 16 | 17 | namespace am = async_mqtt; 18 | 19 | BOOST_AUTO_TEST_CASE( stringize ) { 20 | am::packet_variant v{am::v3_1_1::pingreq_packet{}}; 21 | BOOST_TEST(boost::lexical_cast(v) == "v3_1_1::pingreq{}"); 22 | } 23 | 24 | BOOST_AUTO_TEST_SUITE_END() 25 | -------------------------------------------------------------------------------- /test/unit/ut_static_assert_fail_client.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2023 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include "../common/test_main.hpp" 8 | #include "../common/global_fixture.hpp" 9 | 10 | #include 11 | 12 | #include 13 | #include "stub_socket.hpp" 14 | 15 | namespace am = async_mqtt; 16 | namespace as = boost::asio; 17 | 18 | BOOST_AUTO_TEST_CASE(tc) { 19 | auto version = am::protocol_version::v3_1_1; 20 | as::io_context ioc; 21 | auto ep = am::endpoint{ 22 | version, 23 | // for stub_socket args 24 | version, 25 | ioc 26 | }; 27 | auto p = am::v3_1_1::connack_packet{ 28 | true, // session_present 29 | am::connect_return_code::not_authorized 30 | }; 31 | // static_assert fail as expected 32 | auto ec = ep.async_send(p, as::use_future).get(); 33 | BOOST_TEST(!ec); 34 | } 35 | -------------------------------------------------------------------------------- /test/unit/ut_static_assert_fail_server.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2023 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include "../common/test_main.hpp" 8 | #include "../common/global_fixture.hpp" 9 | 10 | #include 11 | 12 | #include 13 | #include "stub_socket.hpp" 14 | 15 | namespace am = async_mqtt; 16 | namespace as = boost::asio; 17 | 18 | BOOST_AUTO_TEST_CASE(tc) { 19 | auto version = am::protocol_version::v3_1_1; 20 | as::io_context ioc; 21 | auto ep = am::endpoint{ 22 | version, 23 | // for stub_socket args 24 | version, 25 | ioc 26 | }; 27 | auto p = am::v3_1_1::connect_packet{ 28 | true, // clean_session 29 | 0x0, // keep_alive 30 | "cid1", 31 | std::nullopt, 32 | "user1", 33 | "pass1" 34 | }; 35 | // static_assert fail as expected 36 | auto ec = ep.async_send(p, as::use_future).get(); 37 | BOOST_TEST(!ec); 38 | } 39 | -------------------------------------------------------------------------------- /test/unit/ut_strm.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include "../common/test_main.hpp" 8 | #include "../common/global_fixture.hpp" 9 | 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include "stub_socket.hpp" 19 | 20 | BOOST_AUTO_TEST_SUITE(ut_strm) 21 | 22 | namespace am = async_mqtt; 23 | namespace as = boost::asio; 24 | 25 | // packet_id is hard coded in this test case for just testing. 26 | // but users need to get packet_id via ep->acquire_unique_packet_id(...) 27 | // see other test cases. 28 | 29 | // v3_1_1 30 | 31 | BOOST_AUTO_TEST_CASE(write_cont) { 32 | auto version = am::protocol_version::v3_1_1; 33 | as::io_context ioc; 34 | auto guard{as::make_work_guard(ioc.get_executor())}; 35 | 36 | using strm_t = am::stream; 37 | { 38 | strm_t s{ 39 | // for stub_socket args 40 | version, 41 | ioc.get_executor() 42 | }; 43 | auto sg = 44 | am::shared_scope_guard( 45 | [&] { 46 | guard.reset(); 47 | } 48 | ); 49 | 50 | auto p = am::v3_1_1::pingreq_packet(); 51 | s.async_write_packet(p, [sg](am::error_code const&, std::size_t){}); 52 | s.async_write_packet(p, [sg](am::error_code const&, std::size_t){}); 53 | s.async_write_packet(p, [sg](am::error_code const&, std::size_t){}); 54 | s.async_write_packet(p, [sg](am::error_code const&, std::size_t){}); 55 | s.async_write_packet(p, [sg](am::error_code const&, std::size_t){}); 56 | s.async_write_packet(p, [sg](am::error_code const&, std::size_t){}); 57 | s.async_write_packet(p, [sg](am::error_code const&, std::size_t){}); 58 | s.async_write_packet(p, [sg](am::error_code const&, std::size_t){}); 59 | } 60 | ioc.run(); 61 | } 62 | 63 | BOOST_AUTO_TEST_SUITE_END() 64 | -------------------------------------------------------------------------------- /test/unit/ut_timer.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2025 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include "../common/test_main.hpp" 8 | #include "../common/global_fixture.hpp" 9 | 10 | #include 11 | 12 | BOOST_AUTO_TEST_SUITE(ut_timer) 13 | 14 | namespace am = async_mqtt; 15 | 16 | 17 | BOOST_AUTO_TEST_CASE(kind) { 18 | { 19 | std::stringstream ss; 20 | ss << am::timer_kind::pingreq_send; 21 | BOOST_TEST(ss.str() == "pingreq_send"); 22 | } 23 | { 24 | std::stringstream ss; 25 | ss << am::timer_kind::pingreq_recv; 26 | BOOST_TEST(ss.str() == "pingreq_recv"); 27 | } 28 | { 29 | std::stringstream ss; 30 | ss << am::timer_kind::pingresp_recv; 31 | BOOST_TEST(ss.str() == "pingresp_recv"); 32 | } 33 | { 34 | std::stringstream ss; 35 | ss << static_cast(3); 36 | BOOST_TEST(ss.str() == "unknown_timer_kind"); 37 | } 38 | } 39 | 40 | BOOST_AUTO_TEST_CASE(op) { 41 | { 42 | std::stringstream ss; 43 | ss << am::timer_op::reset; 44 | BOOST_TEST(ss.str() == "reset"); 45 | } 46 | { 47 | std::stringstream ss; 48 | ss << am::timer_op::cancel; 49 | BOOST_TEST(ss.str() == "cancel"); 50 | } 51 | { 52 | std::stringstream ss; 53 | ss << static_cast(3); 54 | BOOST_TEST(ss.str() == "unknown_timer_op"); 55 | } 56 | } 57 | 58 | BOOST_AUTO_TEST_SUITE_END() 59 | -------------------------------------------------------------------------------- /test/unit/ut_topic_sharename.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2020 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include "../common/test_main.hpp" 8 | #include "../common/global_fixture.hpp" 9 | 10 | #include 11 | 12 | BOOST_AUTO_TEST_SUITE(ut_topic_sharename) 13 | 14 | namespace am = async_mqtt; 15 | 16 | // success 17 | BOOST_AUTO_TEST_CASE( parse_success1 ) { 18 | am::topic_sharename ts{"$share/share_name/topic_filter"}; 19 | BOOST_CHECK(ts); 20 | BOOST_TEST(ts.sharename() == "share_name"); 21 | BOOST_TEST(ts.topic() == "topic_filter"); 22 | } 23 | 24 | BOOST_AUTO_TEST_CASE( parse_success2 ) { 25 | am::topic_sharename ts{"topic_filter"}; 26 | BOOST_CHECK(ts); 27 | BOOST_TEST(ts.sharename() == ""); 28 | BOOST_TEST(ts.topic() == "topic_filter"); 29 | } 30 | 31 | 32 | BOOST_AUTO_TEST_CASE( parse_success3 ) { 33 | am::topic_sharename ts{"$share/share_name//"}; 34 | BOOST_CHECK(ts); 35 | BOOST_TEST(ts.sharename() == "share_name"); 36 | BOOST_TEST(ts.topic() == "/"); 37 | } 38 | 39 | // error 40 | 41 | BOOST_AUTO_TEST_CASE( parse_error1 ) { 42 | am::topic_sharename ts{"$share//topic_filter"}; 43 | BOOST_CHECK(!ts); 44 | } 45 | 46 | 47 | BOOST_AUTO_TEST_CASE( parse_error2 ) { 48 | am::topic_sharename ts{"$share/share_name"}; 49 | BOOST_CHECK(!ts); 50 | } 51 | 52 | BOOST_AUTO_TEST_CASE( parse_error3 ) { 53 | am::topic_sharename ts{"$share/share_name/"}; 54 | BOOST_CHECK(!ts); 55 | } 56 | 57 | BOOST_AUTO_TEST_SUITE_END() 58 | -------------------------------------------------------------------------------- /test/unit/ut_topic_subopts.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include "../common/test_main.hpp" 8 | #include "../common/global_fixture.hpp" 9 | 10 | #include 11 | 12 | BOOST_AUTO_TEST_SUITE(ut_topic_subopts) 13 | 14 | 15 | BOOST_AUTO_TEST_CASE( tc1 ) { 16 | 17 | } 18 | 19 | BOOST_AUTO_TEST_SUITE_END() 20 | -------------------------------------------------------------------------------- /test/unit/ut_unique_scope_guard.cpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2021 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #include "../common/test_main.hpp" 8 | #include "../common/global_fixture.hpp" 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | BOOST_AUTO_TEST_SUITE(ut_unique_scope_guard) 16 | 17 | namespace am = async_mqtt; 18 | 19 | BOOST_AUTO_TEST_CASE( simple ) { 20 | int i = 0; 21 | { 22 | auto g1 = am::unique_scope_guard( 23 | [&] { 24 | ++i; 25 | } 26 | ); 27 | } 28 | BOOST_TEST(i == 1); 29 | } 30 | 31 | BOOST_AUTO_TEST_CASE( move_c ) { 32 | int i = 0; 33 | { 34 | auto g1 = am::unique_scope_guard( 35 | [&] { 36 | ++i; 37 | } 38 | ); 39 | auto g2{std::move(g1)}; 40 | } 41 | BOOST_TEST(i == 1); 42 | } 43 | 44 | BOOST_AUTO_TEST_SUITE_END() 45 | -------------------------------------------------------------------------------- /tool/broker.conf: -------------------------------------------------------------------------------- 1 | # Default configuration for async_mqtt Broker 2 | # print program options 3 | silent=false 4 | # log severity 0:fatal, 1:error, 2:warning, 3:info, 4:debug, 5:trace 5 | verbose=1 6 | # Log is colored by level 7 | colored_log=true 8 | # for TLS 9 | certificate=server.crt.pem 10 | private_key=server.key.pem 11 | # for Client Certificate Verification 12 | verify_file=cacert.pem 13 | # for MQTT auth 14 | auth_file=auth.json 15 | 16 | # 0 means automatic 17 | # Num of vCPU 18 | iocs=0 19 | 20 | # 0 means automatic 21 | # min(4 or Num of vCPU) 22 | threads_per_ioc=0 23 | 24 | # Fixed CPU core mapping by ioc 25 | # When set true, ioc index is mapped to core 26 | # e.g. if thread0,1,2,3 mapped ioc0 then they are 27 | # mapped to core0 28 | # Normally, set false is recommended. 29 | # OS doing well. 30 | fixed_core_map=false 31 | 32 | # Socket config (underlying layer) 33 | # tcp_no_delay=true 34 | # send_buf_size=131072 35 | # recv_buf_size=16384 36 | 37 | # Library Internal behavior 38 | # bulk_write=false 39 | # read_buf_size=65536 40 | 41 | 42 | # allocator config 43 | # recycling_allocator=true 44 | 45 | # Configuration for TCP 46 | [tcp] 47 | port=1883 48 | 49 | # Configuration for TLS 50 | [tls] 51 | port=8883 52 | 53 | # Configuration for Websocket 54 | [ws] 55 | port=10080 56 | 57 | # Configuration for Websocket with TLS 58 | [wss] 59 | port=10443 60 | -------------------------------------------------------------------------------- /tool/cli.conf: -------------------------------------------------------------------------------- 1 | ## connection settings 2 | 3 | # hostname or IP address of the target broker 4 | host=localhost 5 | 6 | # MQTT typical port is 1883. MQTTS typical port is 8883 7 | port=1883 8 | 9 | # mqtt, mqtts, ws, or wss 10 | protocol=mqtt 11 | 12 | # v3.1.1 or v5 13 | mqtt_version=v5 14 | 15 | # MQTT username for all clients 16 | #usermane=user1 17 | 18 | # MQTT password for all clients 19 | #password=mypassword 20 | 21 | # MQTT Client Identifier. 22 | #client_id=cid1 23 | 24 | # MQTT CleanStart(v5) CleanSession(v3.1.1). true or false 25 | clean_start=true 26 | 27 | # CA certificate file. it is used only protocol mqtts and wss 28 | #verify_file=cacert.pem 29 | 30 | # Client Certificate (chain) file 31 | #certificate=client.crt.pem 32 | 33 | # Client Certificate key file 34 | #private_key=client.key.pem 35 | 36 | # Web-Scoket path. it is used only protocol ws and wss 37 | #ws_path=/ 38 | 39 | # MQTT v5 Session Expiry Interval (seconds) 40 | sei=0 41 | 42 | # log level. 0 to 5. fatal, error, warning, info, debug, and trace 43 | # 0 1 2 3 4 5 44 | verbose=2 45 | # Log is colored by level 46 | colored_log=true 47 | -------------------------------------------------------------------------------- /tool/include/broker/constant.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Wouter van Kleunen 2022 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_BROKER_CONSTANT_HPP) 8 | #define ASYNC_MQTT_BROKER_CONSTANT_HPP 9 | 10 | #include 11 | 12 | namespace async_mqtt { 13 | 14 | static constexpr std::size_t max_cn_size = 0xffff; 15 | 16 | } // namespace async_mqtt 17 | 18 | #endif // ASYNC_MQTT_BROKER_CONSTANT_HPP 19 | -------------------------------------------------------------------------------- /tool/include/broker/fixed_core_map.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2021 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_BROKER_FIXED_CORE_MAP_HPP) 8 | #define ASYNC_MQTT_BROKER_FIXED_CORE_MAP_HPP 9 | 10 | #include 11 | 12 | #if defined(_GNU_SOURCE) 13 | 14 | #include 15 | #include 16 | 17 | namespace async_mqtt { 18 | 19 | inline void map_core_to_this_thread(std::size_t core) { 20 | cpu_set_t mask; 21 | CPU_ZERO(&mask); 22 | CPU_SET(static_cast(core), &mask); 23 | int ret = sched_setaffinity(0, sizeof(mask), &mask); 24 | (void)ret; 25 | BOOST_ASSERT(ret == 0); 26 | } 27 | 28 | } // namespace async_mqtt 29 | 30 | #else // defined(_GNU_SOURCE) 31 | 32 | namespace async_mqtt { 33 | 34 | inline void map_core_to_this_thread(std::size_t /*core*/) { 35 | ASYNC_MQTT_LOG("mqtt_broker", warning) 36 | << "map_core_to_this_thread() is called but do nothing"; 37 | } 38 | 39 | } // namespace async_mqtt 40 | 41 | #endif // defined(_GNU_SOURCE) 42 | 43 | #endif // ASYNC_MQTT_BROKER_FIXED_CORE_MAP_HPP 44 | -------------------------------------------------------------------------------- /tool/include/broker/mutex.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2021 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_BROKER_MUTEX_HPP) 8 | #define ASYNC_MQTT_BROKER_MUTEX_HPP 9 | 10 | #include 11 | 12 | namespace async_mqtt { 13 | 14 | using mutex = std::shared_timed_mutex; 15 | 16 | } // namespace async_mqtt 17 | 18 | 19 | #endif // ASYNC_MQTT_BROKER_MUTEX_HPP 20 | -------------------------------------------------------------------------------- /tool/include/broker/retain_type.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2020 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_BROKER_RETAIN_TYPE_HPP) 8 | #define ASYNC_MQTT_BROKER_RETAIN_TYPE_HPP 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | namespace async_mqtt { 17 | 18 | // A collection of messages that have been retained in 19 | // case clients add a new subscription to the associated topics. 20 | struct retain_type { 21 | retain_type( 22 | std::string topic, 23 | std::vector payload, 24 | properties props, 25 | qos qos_value, 26 | std::shared_ptr tim_message_expiry = std::shared_ptr()) 27 | :topic(force_move(topic)), 28 | props(force_move(props)), 29 | qos_value(qos_value), 30 | tim_message_expiry(force_move(tim_message_expiry)) 31 | { 32 | auto it = std::cbegin(payload); 33 | auto end = std::cend(payload); 34 | for (; it != end; ++it) { 35 | this->payload.emplace_back(*it); 36 | } 37 | } 38 | 39 | std::string topic; 40 | std::vector payload; 41 | properties props; 42 | qos qos_value; 43 | std::shared_ptr tim_message_expiry; 44 | }; 45 | 46 | } // namespace async_mqtt 47 | 48 | #endif // ASYNC_MQTT_BROKER_RETAIN_TYPE_HPP 49 | -------------------------------------------------------------------------------- /tool/include/broker/retained_messages.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2020 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_BROKER_RETAINED_MESSAGES_HPP) 8 | #define ASYNC_MQTT_BROKER_RETAINED_MESSAGES_HPP 9 | 10 | #include // reference_wrapper 11 | 12 | #include 13 | #include 14 | 15 | namespace async_mqtt { 16 | 17 | using retained_messages = retained_topic_map; 18 | 19 | } // namespace async_mqtt 20 | 21 | #endif // ASYNC_MQTT_BROKER_RETAINED_MESSAGES_HPP 22 | -------------------------------------------------------------------------------- /tool/include/broker/session_state_fwd.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2020 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_BROKER_SESSION_STATE_FWD_HPP) 8 | #define ASYNC_MQTT_BROKER_SESSION_STATE_FWD_HPP 9 | 10 | #include // reference_wrapper 11 | 12 | namespace async_mqtt { 13 | 14 | template 15 | struct session_state; 16 | 17 | template 18 | using session_state_ref = std::reference_wrapper>; 19 | 20 | } // namespace async_mqtt 21 | 22 | #endif // ASYNC_MQTT_BROKER_SESSION_STATE_FWD_HPP 23 | -------------------------------------------------------------------------------- /tool/include/broker/sub_con_map.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2020 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_BROKER_SUB_CON_MAP_HPP) 8 | #define ASYNC_MQTT_BROKER_SUB_CON_MAP_HPP 9 | 10 | #include 11 | #include 12 | 13 | namespace async_mqtt { 14 | 15 | template 16 | using sub_con_map = multiple_subscription_map>; 17 | 18 | } // namespace async_mqtt 19 | 20 | #endif // ASYNC_MQTT_BROKER_SUB_CON_MAP_HPP 21 | -------------------------------------------------------------------------------- /tool/include/broker/subscription.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2020 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_BROKER_SUBSCRIPTION_HPP) 8 | #define ASYNC_MQTT_BROKER_SUBSCRIPTION_HPP 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | namespace async_mqtt { 18 | 19 | template 20 | struct subscription { 21 | subscription( 22 | session_state_ref ss, 23 | std::string sharename, 24 | std::string topic, 25 | sub::opts opts, 26 | std::optional sid) 27 | :ss{ss}, 28 | sharename{force_move(sharename)}, 29 | topic{force_move(topic)}, 30 | opts{opts}, 31 | sid{sid} 32 | {} 33 | 34 | session_state_ref ss; 35 | std::string sharename; 36 | std::string topic; 37 | sub::opts opts; 38 | std::optional sid; 39 | }; 40 | 41 | template 42 | inline bool operator<(subscription const& lhs, subscription const& rhs) { 43 | return &lhs.ss.get() < &rhs.ss.get(); 44 | } 45 | 46 | } // namespace async_mqtt 47 | 48 | #endif // ASYNC_MQTT_BROKER_SUBSCRIPTION_HPP 49 | -------------------------------------------------------------------------------- /tool/include/broker/tags.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2020 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_BROKER_TAGS_HPP) 8 | #define ASYNC_MQTT_BROKER_TAGS_HPP 9 | 10 | namespace async_mqtt { 11 | 12 | struct tag_seq {}; 13 | struct tag_con {}; 14 | struct tag_topic{}; 15 | struct tag_topic_filter{}; 16 | struct tag_con_topic_filter {}; 17 | struct tag_cid {}; 18 | struct tag_cid_topic_filter {}; 19 | struct tag_tim {}; 20 | struct tag_pid {}; 21 | struct tag_sn_tp {}; 22 | struct tag_cid_sn {}; 23 | 24 | } // namespace async_mqtt 25 | 26 | #endif // ASYNC_MQTT_BROKER_TAGS_HPP 27 | -------------------------------------------------------------------------------- /tool/include/broker/uuid.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2021 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_BROKER_UUID_HPP) 8 | #define ASYNC_MQTT_BROKER_UUID_HPP 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | 17 | namespace async_mqtt { 18 | 19 | inline std::string create_uuid_string() { 20 | // See https://github.com/boostorg/uuid/issues/121 21 | thread_local boost::uuids::random_generator gen; 22 | return boost::uuids::to_string(gen()); 23 | } 24 | 25 | } // namespace async_mqtt 26 | 27 | #endif // ASYNC_MQTT_BROKER_UUID_HPP 28 | -------------------------------------------------------------------------------- /tool/locked_cout.hpp: -------------------------------------------------------------------------------- 1 | // Copyright Takatoshi Kondo 2019 2 | // 3 | // Distributed under the Boost Software License, Version 1.0. 4 | // (See accompanying file LICENSE_1_0.txt or copy at 5 | // http://www.boost.org/LICENSE_1_0.txt) 6 | 7 | #if !defined(ASYNC_MQTT_LOCKED_COUT_HPP) 8 | #define ASYNC_MQTT_LOCKED_COUT_HPP 9 | 10 | #include 11 | #include 12 | 13 | class locked_stream { 14 | public: 15 | locked_stream(std::ostream& stream) 16 | :lock_(mtx_), 17 | stream_(stream) {} 18 | 19 | friend 20 | locked_stream&& operator<<(locked_stream&& s, std::ostream& (*arg)(std::ostream&)) { 21 | s.stream_ << arg; 22 | return std::move(s); 23 | } 24 | 25 | template 26 | friend 27 | locked_stream&& operator<<(locked_stream&& s, Arg&& arg) { 28 | s.stream_ << std::forward(arg); 29 | return std::move(s); 30 | } 31 | 32 | private: 33 | static std::mutex mtx_; 34 | std::unique_lock lock_; 35 | std::ostream& stream_; 36 | 37 | }; 38 | 39 | std::mutex locked_stream::mtx_{}; 40 | 41 | inline 42 | locked_stream locked_cout() { 43 | return locked_stream(std::cout); 44 | } 45 | 46 | #endif // ASYNC_MQTT_LOCKED_COUT_HPP 47 | -------------------------------------------------------------------------------- /update_picosha2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | curl https://raw.githubusercontent.com/okdshin/PicoSHA2/master/picosha2.h > tool/include/broker/external/picosha2.h 4 | --------------------------------------------------------------------------------