aop_connack.hpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * Copyright (c) 2017-2023 zhllxt
  3. *
  4. * author : zhllxt
  5. * email : 37792738@qq.com
  6. *
  7. * Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. */
  10. #ifndef __ASIO2_MQTT_AOP_CONNACK_HPP__
  11. #define __ASIO2_MQTT_AOP_CONNACK_HPP__
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. #pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <asio2/base/iopool.hpp>
  16. #include <asio2/base/detail/function_traits.hpp>
  17. #include <asio2/base/detail/util.hpp>
  18. #include <asio2/mqtt/message.hpp>
  19. namespace asio2::detail
  20. {
  21. template<class caller_t, class args_t>
  22. class mqtt_aop_connack
  23. {
  24. friend caller_t;
  25. protected:
  26. template<class Message, bool IsClient = args_t::is_client>
  27. inline std::enable_if_t<!IsClient, void>
  28. _before_connack_callback(
  29. error_code& ec, std::shared_ptr<caller_t>& caller_ptr, caller_t* caller, mqtt::message& om,
  30. Message& msg)
  31. {
  32. detail::ignore_unused(ec, caller_ptr, caller, om, msg);
  33. // if server recvd connack message, disconnect
  34. ec = mqtt::make_error_code(mqtt::error::malformed_packet);
  35. }
  36. template<class Message, bool IsClient = args_t::is_client>
  37. inline std::enable_if_t<IsClient, void>
  38. _before_connack_callback(
  39. error_code& ec, std::shared_ptr<caller_t>& caller_ptr, caller_t* caller, mqtt::message& om,
  40. Message& msg)
  41. {
  42. detail::ignore_unused(ec, caller_ptr, caller, om, msg);
  43. // if started already and recvd connack message again, disconnect
  44. state_t expected = state_t::started;
  45. if (caller->state_.compare_exchange_strong(expected, state_t::started))
  46. {
  47. ec = mqtt::make_error_code(mqtt::error::malformed_packet);
  48. return;
  49. }
  50. caller->connack_message_ = msg;
  51. }
  52. // must be client
  53. inline void _before_user_callback_impl(
  54. error_code& ec, std::shared_ptr<caller_t>& caller_ptr, caller_t* caller, mqtt::message& om,
  55. mqtt::v3::connack& msg)
  56. {
  57. if (_before_connack_callback(ec, caller_ptr, caller, om, msg); ec)
  58. return;
  59. switch(msg.reason_code())
  60. {
  61. case mqtt::v3::connect_reason_code::success : ec = mqtt::make_error_code(mqtt::error::success ); break;
  62. case mqtt::v3::connect_reason_code::unacceptable_protocol_version : ec = mqtt::make_error_code(mqtt::error::unsupported_protocol_version); break;
  63. case mqtt::v3::connect_reason_code::identifier_rejected : ec = mqtt::make_error_code(mqtt::error::client_identifier_not_valid ); break;
  64. case mqtt::v3::connect_reason_code::server_unavailable : ec = mqtt::make_error_code(mqtt::error::server_unavailable ); break;
  65. case mqtt::v3::connect_reason_code::bad_user_name_or_password : ec = mqtt::make_error_code(mqtt::error::bad_user_name_or_password ); break;
  66. case mqtt::v3::connect_reason_code::not_authorized : ec = mqtt::make_error_code(mqtt::error::not_authorized ); break;
  67. default : ec = mqtt::make_error_code(mqtt::error::malformed_packet ); break;
  68. }
  69. }
  70. // must be client
  71. inline void _before_user_callback_impl(
  72. error_code& ec, std::shared_ptr<caller_t>& caller_ptr, caller_t* caller, mqtt::message& om,
  73. mqtt::v4::connack& msg)
  74. {
  75. if (_before_connack_callback(ec, caller_ptr, caller, om, msg); ec)
  76. return;
  77. switch(msg.reason_code())
  78. {
  79. case mqtt::v4::connect_reason_code::success : ec = mqtt::make_error_code(mqtt::error::success ); break;
  80. case mqtt::v4::connect_reason_code::unacceptable_protocol_version : ec = mqtt::make_error_code(mqtt::error::unsupported_protocol_version); break;
  81. case mqtt::v4::connect_reason_code::identifier_rejected : ec = mqtt::make_error_code(mqtt::error::client_identifier_not_valid ); break;
  82. case mqtt::v4::connect_reason_code::server_unavailable : ec = mqtt::make_error_code(mqtt::error::server_unavailable ); break;
  83. case mqtt::v4::connect_reason_code::bad_user_name_or_password : ec = mqtt::make_error_code(mqtt::error::bad_user_name_or_password ); break;
  84. case mqtt::v4::connect_reason_code::not_authorized : ec = mqtt::make_error_code(mqtt::error::not_authorized ); break;
  85. default : ec = mqtt::make_error_code(mqtt::error::malformed_packet ); break;
  86. }
  87. }
  88. // must be client
  89. inline void _before_user_callback_impl(
  90. error_code& ec, std::shared_ptr<caller_t>& caller_ptr, caller_t* caller, mqtt::message& om,
  91. mqtt::v5::connack& msg)
  92. {
  93. if (_before_connack_callback(ec, caller_ptr, caller, om, msg); ec)
  94. return;
  95. ec = mqtt::make_error_code(static_cast<mqtt::error>(msg.reason_code()));
  96. }
  97. inline void _after_user_callback_impl(
  98. error_code& ec, std::shared_ptr<caller_t>& caller_ptr, caller_t* caller, mqtt::message& om,
  99. mqtt::v3::connack& msg)
  100. {
  101. detail::ignore_unused(ec, caller_ptr, caller, om, msg);
  102. // if already has error, return
  103. if (ec)
  104. return;
  105. switch(msg.reason_code())
  106. {
  107. case mqtt::v3::connect_reason_code::success : ec = mqtt::make_error_code(mqtt::error::success ); break;
  108. case mqtt::v3::connect_reason_code::unacceptable_protocol_version : ec = mqtt::make_error_code(mqtt::error::unsupported_protocol_version); break;
  109. case mqtt::v3::connect_reason_code::identifier_rejected : ec = mqtt::make_error_code(mqtt::error::client_identifier_not_valid ); break;
  110. case mqtt::v3::connect_reason_code::server_unavailable : ec = mqtt::make_error_code(mqtt::error::server_unavailable ); break;
  111. case mqtt::v3::connect_reason_code::bad_user_name_or_password : ec = mqtt::make_error_code(mqtt::error::bad_user_name_or_password ); break;
  112. case mqtt::v3::connect_reason_code::not_authorized : ec = mqtt::make_error_code(mqtt::error::not_authorized ); break;
  113. default : ec = mqtt::make_error_code(mqtt::error::malformed_packet ); break;
  114. }
  115. }
  116. inline void _after_user_callback_impl(
  117. error_code& ec, std::shared_ptr<caller_t>& caller_ptr, caller_t* caller, mqtt::message& om,
  118. mqtt::v4::connack& msg)
  119. {
  120. detail::ignore_unused(ec, caller_ptr, caller, om, msg);
  121. // if already has error, return
  122. if (ec)
  123. return;
  124. switch(msg.reason_code())
  125. {
  126. case mqtt::v4::connect_reason_code::success : ec = mqtt::make_error_code(mqtt::error::success ); break;
  127. case mqtt::v4::connect_reason_code::unacceptable_protocol_version : ec = mqtt::make_error_code(mqtt::error::unsupported_protocol_version); break;
  128. case mqtt::v4::connect_reason_code::identifier_rejected : ec = mqtt::make_error_code(mqtt::error::client_identifier_not_valid ); break;
  129. case mqtt::v4::connect_reason_code::server_unavailable : ec = mqtt::make_error_code(mqtt::error::server_unavailable ); break;
  130. case mqtt::v4::connect_reason_code::bad_user_name_or_password : ec = mqtt::make_error_code(mqtt::error::bad_user_name_or_password ); break;
  131. case mqtt::v4::connect_reason_code::not_authorized : ec = mqtt::make_error_code(mqtt::error::not_authorized ); break;
  132. default : ec = mqtt::make_error_code(mqtt::error::malformed_packet ); break;
  133. }
  134. }
  135. inline void _after_user_callback_impl(
  136. error_code& ec, std::shared_ptr<caller_t>& caller_ptr, caller_t* caller, mqtt::message& om,
  137. mqtt::v5::connack& msg)
  138. {
  139. detail::ignore_unused(ec, caller_ptr, caller, om, msg);
  140. // if already has error, return
  141. if (ec)
  142. return;
  143. ec = mqtt::make_error_code(static_cast<mqtt::error>(msg.reason_code()));
  144. }
  145. };
  146. }
  147. #endif // !__ASIO2_MQTT_AOP_CONNACK_HPP__