error.hpp 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596
  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_ERROR_HPP__
  11. #define __ASIO2_MQTT_ERROR_HPP__
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. #pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <asio2/base/error.hpp>
  16. namespace asio2::mqtt
  17. {
  18. ///// The type of error category used by the library
  19. //using error_category = asio::error_category;
  20. ///// The type of error condition used by the library
  21. //using error_condition = std::error_condition;
  22. //enum class error
  23. //{
  24. // success = 0,
  25. // failure,
  26. // persistence_error,
  27. // disconnected,
  28. // max_messages_inflight,
  29. // bad_utf8_string,
  30. // null_parameter,
  31. // topicname_truncated,
  32. // bad_structure,
  33. // bad_qos,
  34. // no_more_msgids,
  35. // operation_incomplete,
  36. // max_buffered_messages,
  37. // ssl_not_supported,
  38. // bad_mqtt_version,
  39. // bad_protocol,
  40. // bad_mqtt_option,
  41. // wrong_mqtt_version,
  42. // zero_len_will_topic,
  43. //};
  44. //enum class condition
  45. //{
  46. // success = 0,
  47. // failure,
  48. // persistence_error, // unspecified_error
  49. // disconnected, // disconnect_with_will_message
  50. // max_messages_inflight, // message_rate_too_high
  51. // bad_utf8_string, // topic_filter_invalid topic_name_invalid topic_alias_invalid
  52. // null_parameter, // malformed_packet
  53. // topicname_truncated, // topic_name_invalid
  54. // bad_structure, // protocol_error implementation_specific_error
  55. // bad_qos, // qos_not_supported
  56. // no_more_msgids, // packet_identifier_not_found no_matching_subscribers no_subscription_existed
  57. // operation_incomplete, // server_busy
  58. // max_buffered_messages, // packet_too_large
  59. // ssl_not_supported, // unsupported_protocol_version server_unavailable
  60. // bad_mqtt_version, // unsupported_protocol_version
  61. // bad_protocol, // protocol_error
  62. // bad_mqtt_option, // payload_format_invalid protocol_error malformed_packet
  63. // wrong_mqtt_version, // unsupported_protocol_version
  64. // zero_len_will_topic, // topic_filter_invalid topic_name_invalid topic_alias_invalid
  65. //};
  66. //class mqtt_error_category : public error_category
  67. //{
  68. //public:
  69. // const char* name() const noexcept override
  70. // {
  71. // return "asio2.mqtt";
  72. // }
  73. // inline std::string message(int ev) const override
  74. // {
  75. // switch (static_cast<error>(ev))
  76. // {
  77. // case error::success : return "Success";
  78. // case error::failure : return "Failure";
  79. // case error::persistence_error : return "Persistence error";
  80. // case error::disconnected : return "Disconnected";
  81. // case error::max_messages_inflight : return "Maximum in-flight messages amount reached";
  82. // case error::bad_utf8_string : return "Invalid UTF8 string";
  83. // case error::null_parameter : return "Invalid (NULL) parameter";
  84. // case error::topicname_truncated : return "Topic containing NULL characters has been truncated";
  85. // case error::bad_structure : return "Bad structure";
  86. // case error::bad_qos : return "Invalid QoS value";
  87. // case error::no_more_msgids : return "Too many pending commands";
  88. // case error::operation_incomplete : return "Operation discarded before completion";
  89. // case error::max_buffered_messages : return "No more messages can be buffered";
  90. // case error::ssl_not_supported : return "SSL is not supported";
  91. // case error::bad_mqtt_version : return "Unrecognized MQTT version";
  92. // case error::bad_protocol : return "Invalid protocol scheme";
  93. // case error::bad_mqtt_option : return "Options for wrong MQTT version";
  94. // case error::wrong_mqtt_version : return "Client created for another version of MQTT";
  95. // case error::zero_len_will_topic : return "Zero length will topic on connect";
  96. // default : return "Unknown";
  97. // }
  98. // }
  99. // inline error_condition default_error_condition(int ev) const noexcept override
  100. // {
  101. // //switch (static_cast<error>(ev))
  102. // //{
  103. // //default:
  104. // //case error::disconnected : return condition::disconnected ;
  105. // //case error::max_messages_inflight : return condition::max_messages_inflight ;
  106. // //case error::bad_utf8_string : return condition::bad_utf8_string ;
  107. // //case error::null_parameter : return condition::null_parameter ;
  108. // //case error::topicname_truncated : return condition::topicname_truncated ;
  109. // //case error::bad_structure : return condition::bad_structure ;
  110. // //case error::bad_qos : return condition::bad_qos ;
  111. // //case error::ssl_not_supported : return condition::ssl_not_supported ;
  112. // //case error::bad_mqtt_version : return condition::bad_mqtt_version ;
  113. // //case error::bad_protocol : return condition::bad_protocol ;
  114. // //case error::bad_mqtt_option : return condition::bad_mqtt_option ;
  115. // //case error::wrong_mqtt_version : return condition::wrong_mqtt_version ;
  116. // //}
  117. // return error_condition{ ev, *this };
  118. // }
  119. //};
  120. //inline const mqtt_error_category& mqtt_category() noexcept
  121. //{
  122. // static mqtt_error_category const cat{};
  123. // return cat;
  124. //}
  125. //inline error_code make_error_code(error e)
  126. //{
  127. // return error_code{ static_cast<std::underlying_type<error>::type>(e), mqtt_category() };
  128. //}
  129. //inline error_condition make_error_condition(condition c)
  130. //{
  131. // return error_condition{ static_cast<std::underlying_type<condition>::type>(c), mqtt_category() };
  132. //}
  133. /**
  134. * Reason Code
  135. *
  136. * A Reason Code is a one byte unsigned value that indicates the result of an operation. Reason Codes
  137. * less than 0x80 indicate successful completion of an operation. The normal Reason Code for success
  138. * is 0. Reason Code values of 0x80 or greater indicate failure.
  139. *
  140. * The Reason Codes share a common set of values as shown below.
  141. *
  142. * https://docs.oasis-open.org/mqtt/mqtt/v5.0/os/mqtt-v5.0-os.html#_Toc3901031
  143. */
  144. enum class error : std::uint8_t
  145. {
  146. // The operation completed successfully.
  147. success = 0,
  148. // Close the connection normally. Do not send the Will Message.
  149. normal_disconnection = 0,
  150. // Granted the PUBLISH Quality of Service is 0
  151. granted_qos_0 = 0,
  152. // Granted the PUBLISH Quality of Service is 1
  153. granted_qos_1 = 1,
  154. // Granted the PUBLISH Quality of Service is 2
  155. granted_qos_2 = 2,
  156. // The Client wishes to disconnect but requires that the Server also publishes its Will Message.
  157. disconnect_with_will_message = 4,
  158. // The message is accepted but there are no subscribers. This is sent only by the Server. If the Server knows that there are no matching subscribers, it MAY use this Reason Code instead of 0x00 (Success).
  159. no_matching_subscribers = 16,
  160. // No subscription existed
  161. no_subscription_existed = 17,
  162. // Continue the authentication with another step
  163. continue_authentication = 24,
  164. // Initiate a re-authentication
  165. reauthenticate = 25,
  166. // The Server or Client does not wish to reveal the reason for the failure, or none of the other Reason Codes apply.
  167. unspecified_error = 128,
  168. // The received packet does not conform to this specification.
  169. malformed_packet = 129,
  170. // An unexpected or out of order packet was received.
  171. protocol_error = 130,
  172. // The packet received is valid but cannot be processed by this implementation.
  173. implementation_specific_error = 131,
  174. // The Server does not support the version of the MQTT protocol requested by the Client.
  175. unsupported_protocol_version = 132,
  176. // The Client Identifier is a valid string but is not allowed by the Server.
  177. client_identifier_not_valid = 133,
  178. // The Server does not accept the User Name or Password specified by the Client
  179. bad_user_name_or_password = 134,
  180. // The request is not authorized.
  181. not_authorized = 135,
  182. // The MQTT Server is not available.
  183. server_unavailable = 136,
  184. // The Server is busy and cannot continue processing requests from this Client.
  185. server_busy = 137,
  186. // This Client has been banned by administrative action. Contact the server administrator.
  187. banned = 138,
  188. // The Server is shutting down.
  189. server_shutting_down = 139,
  190. // The authentication method is not supported or does not match the authentication method currently in use.
  191. bad_authentication_method = 140,
  192. // The Connection is closed because no packet has been received for 1.5 times the Keepalive time.
  193. keep_alive_timeout = 141,
  194. // Another Connection using the same ClientID has connected causing this Connection to be closed.
  195. session_taken_over = 142,
  196. // The Topic Filter is correctly formed, but is not accepted by this Sever.
  197. topic_filter_invalid = 143,
  198. // The Topic Name is not malformed, but is not accepted by this Client or Server.
  199. topic_name_invalid = 144,
  200. // The Packet Identifier is already in use. This might indicate a mismatch in the Session State between the Client and Server.
  201. packet_identifier_in_use = 145,
  202. // The Packet Identifier is not known. This is not an error during recovery, but at other times indicates a mismatch between the Session State on the Client and Server.
  203. packet_identifier_not_found = 146,
  204. // The Client or Server has received more than Receive Maximum publication for which it has not sent PUBACK or PUBCOMP.
  205. receive_maximum_exceeded = 147,
  206. // The Client or Server has received a PUBLISH packet containing a Topic Alias which is greater than the Maximum Topic Alias it sent in the CONNECT or CONNACK packet.
  207. topic_alias_invalid = 148,
  208. // The packet size is greater than Maximum Packet Size for this Client or Server.
  209. packet_too_large = 149,
  210. // The received data rate is too high.
  211. message_rate_too_high = 150,
  212. // An implementation or administrative imposed limit has been exceeded.
  213. quota_exceeded = 151,
  214. // The Connection is closed due to an administrative action.
  215. administrative_action = 152,
  216. // The payload format does not match the specified Payload Format Indicator.
  217. payload_format_invalid = 153,
  218. // The Server has does not support retained messages.
  219. retain_not_supported = 154,
  220. // The Server does not support the QoS set in Will QoS.
  221. qos_not_supported = 155,
  222. // The Client should temporarily use another server.
  223. use_another_server = 156,
  224. // The Server is moved and the Client should permanently use another server.
  225. server_moved = 157,
  226. // The Server does not support Shared Subscriptions.
  227. shared_subscriptions_not_supported = 158,
  228. // The connection rate limit has been exceeded.
  229. connection_rate_exceeded = 159,
  230. // The maximum connection time authorized for this connection has been exceeded.
  231. maximum_connect_time = 160,
  232. // The Server does not support Subscription Identifiers; the subscription is not accepted.
  233. subscription_identifiers_not_supported = 161,
  234. // The Server does not support Wildcard Subscriptions; the subscription is not accepted.
  235. wildcard_subscriptions_not_supported = 162,
  236. };
  237. enum class condition : std::uint8_t
  238. {
  239. // The operation completed successfully.
  240. success = 0,
  241. // Close the connection normally. Do not send the Will Message.
  242. normal_disconnection = 0,
  243. // Granted the PUBLISH Quality of Service is 0
  244. granted_qos_0 = 0,
  245. // Granted the PUBLISH Quality of Service is 1
  246. granted_qos_1 = 1,
  247. // Granted the PUBLISH Quality of Service is 2
  248. granted_qos_2 = 2,
  249. // The Client wishes to disconnect but requires that the Server also publishes its Will Message.
  250. disconnect_with_will_message = 4,
  251. // The message is accepted but there are no subscribers. This is sent only by the Server. If the Server knows that there are no matching subscribers, it MAY use this Reason Code instead of 0x00 (Success).
  252. no_matching_subscribers = 16,
  253. // No subscription existed
  254. no_subscription_existed = 17,
  255. // Continue the authentication with another step
  256. continue_authentication = 24,
  257. // Initiate a re-authentication
  258. reauthenticate = 25,
  259. // The Server or Client does not wish to reveal the reason for the failure, or none of the other Reason Codes apply.
  260. unspecified_error = 128,
  261. // The received packet does not conform to this specification.
  262. malformed_packet = 129,
  263. // An unexpected or out of order packet was received.
  264. protocol_error = 130,
  265. // The packet received is valid but cannot be processed by this implementation.
  266. implementation_specific_error = 131,
  267. // The Server does not support the version of the MQTT protocol requested by the Client.
  268. unsupported_protocol_version = 132,
  269. // The Client Identifier is a valid string but is not allowed by the Server.
  270. client_identifier_not_valid = 133,
  271. // The Server does not accept the User Name or Password specified by the Client
  272. bad_user_name_or_password = 134,
  273. // The request is not authorized.
  274. not_authorized = 135,
  275. // The MQTT Server is not available.
  276. server_unavailable = 136,
  277. // The Server is busy and cannot continue processing requests from this Client.
  278. server_busy = 137,
  279. // This Client has been banned by administrative action. Contact the server administrator.
  280. banned = 138,
  281. // The Server is shutting down.
  282. server_shutting_down = 139,
  283. // The authentication method is not supported or does not match the authentication method currently in use.
  284. bad_authentication_method = 140,
  285. // The Connection is closed because no packet has been received for 1.5 times the Keepalive time.
  286. keep_alive_timeout = 141,
  287. // Another Connection using the same ClientID has connected causing this Connection to be closed.
  288. session_taken_over = 142,
  289. // The Topic Filter is correctly formed, but is not accepted by this Sever.
  290. topic_filter_invalid = 143,
  291. // The Topic Name is not malformed, but is not accepted by this Client or Server.
  292. topic_name_invalid = 144,
  293. // The Packet Identifier is already in use. This might indicate a mismatch in the Session State between the Client and Server.
  294. packet_identifier_in_use = 145,
  295. // The Packet Identifier is not known. This is not an error during recovery, but at other times indicates a mismatch between the Session State on the Client and Server.
  296. packet_identifier_not_found = 146,
  297. // The Client or Server has received more than Receive Maximum publication for which it has not sent PUBACK or PUBCOMP.
  298. receive_maximum_exceeded = 147,
  299. // The Client or Server has received a PUBLISH packet containing a Topic Alias which is greater than the Maximum Topic Alias it sent in the CONNECT or CONNACK packet.
  300. topic_alias_invalid = 148,
  301. // The packet size is greater than Maximum Packet Size for this Client or Server.
  302. packet_too_large = 149,
  303. // The received data rate is too high.
  304. message_rate_too_high = 150,
  305. // An implementation or administrative imposed limit has been exceeded.
  306. quota_exceeded = 151,
  307. // The Connection is closed due to an administrative action.
  308. administrative_action = 152,
  309. // The payload format does not match the specified Payload Format Indicator.
  310. payload_format_invalid = 153,
  311. // The Server has does not support retained messages.
  312. retain_not_supported = 154,
  313. // The Server does not support the QoS set in Will QoS.
  314. qos_not_supported = 155,
  315. // The Client should temporarily use another server.
  316. use_another_server = 156,
  317. // The Server is moved and the Client should permanently use another server.
  318. server_moved = 157,
  319. // The Server does not support Shared Subscriptions.
  320. shared_subscriptions_not_supported = 158,
  321. // The connection rate limit has been exceeded.
  322. connection_rate_exceeded = 159,
  323. // The maximum connection time authorized for this connection has been exceeded.
  324. maximum_connect_time = 160,
  325. // The Server does not support Subscription Identifiers; the subscription is not accepted.
  326. subscription_identifiers_not_supported = 161,
  327. // The Server does not support Wildcard Subscriptions; the subscription is not accepted.
  328. wildcard_subscriptions_not_supported = 162,
  329. };
  330. /// The type of error category used by the library
  331. using error_category = asio::error_category;
  332. /// The type of error condition used by the library
  333. using error_condition = asio::error_condition;
  334. class mqtt_error_category : public error_category
  335. {
  336. public:
  337. const char* name() const noexcept override
  338. {
  339. return "asio2.mqtt";
  340. }
  341. inline std::string message(int ev) const override
  342. {
  343. switch (static_cast<error>(ev))
  344. {
  345. case error::success : return "The operation completed successfully.";
  346. //case error::normal_disconnection : return "Close the connection normally. Do not send the Will Message.";
  347. //case error::granted_qos_0 : return "Granted the PUBLISH Quality of Service is 0";
  348. case error::granted_qos_1 : return "Granted the PUBLISH Quality of Service is 1";
  349. case error::granted_qos_2 : return "Granted the PUBLISH Quality of Service is 2";
  350. case error::disconnect_with_will_message : return "The Client wishes to disconnect but requires that the Server also publishes its Will Message.";
  351. case error::no_matching_subscribers : return "The message is accepted but there are no subscribers. This is sent only by the Server. If the Server knows that there are no matching subscribers, it MAY use this Reason Code instead of 0x00 (Success).";
  352. case error::no_subscription_existed : return "No subscription existed";
  353. case error::continue_authentication : return "Continue the authentication with another step";
  354. case error::reauthenticate : return "Initiate a re-authentication";
  355. case error::unspecified_error : return "The Server or Client does not wish to reveal the reason for the failure, or none of the other Reason Codes apply.";
  356. case error::malformed_packet : return "The received packet does not conform to this specification.";
  357. case error::protocol_error : return "An unexpected or out of order packet was received.";
  358. case error::implementation_specific_error : return "The packet received is valid but cannot be processed by this implementation.";
  359. case error::unsupported_protocol_version : return "The Server does not support the version of the MQTT protocol requested by the Client.";
  360. case error::client_identifier_not_valid : return "The Client Identifier is a valid string but is not allowed by the Server.";
  361. case error::bad_user_name_or_password : return "The Server does not accept the User Name or Password specified by the Client";
  362. case error::not_authorized : return "The request is not authorized.";
  363. case error::server_unavailable : return "The MQTT Server is not available.";
  364. case error::server_busy : return "The Server is busy and cannot continue processing requests from this Client.";
  365. case error::banned : return "This Client has been banned by administrative action. Contact the server administrator.";
  366. case error::server_shutting_down : return "The Server is shutting down.";
  367. case error::bad_authentication_method : return "The authentication method is not supported or does not match the authentication method currently in use.";
  368. case error::keep_alive_timeout : return "The Connection is closed because no packet has been received for 1.5 times the Keepalive time.";
  369. case error::session_taken_over : return "Another Connection using the same ClientID has connected causing this Connection to be closed.";
  370. case error::topic_filter_invalid : return "The Topic Filter is correctly formed, but is not accepted by this Sever.";
  371. case error::topic_name_invalid : return "The Topic Name is not malformed, but is not accepted by this Client or Server.";
  372. case error::packet_identifier_in_use : return "The Packet Identifier is already in use. This might indicate a mismatch in the Session State between the Client and Server.";
  373. case error::packet_identifier_not_found : return "The Packet Identifier is not known. This is not an error during recovery, but at other times indicates a mismatch between the Session State on the Client and Server.";
  374. case error::receive_maximum_exceeded : return "The Client or Server has received more than Receive Maximum publication for which it has not sent PUBACK or PUBCOMP.";
  375. case error::topic_alias_invalid : return "The Client or Server has received a PUBLISH packet containing a Topic Alias which is greater than the Maximum Topic Alias it sent in the CONNECT or CONNACK packet.";
  376. case error::packet_too_large : return "The packet size is greater than Maximum Packet Size for this Client or Server.";
  377. case error::message_rate_too_high : return "The received data rate is too high.";
  378. case error::quota_exceeded : return "An implementation or administrative imposed limit has been exceeded.";
  379. case error::administrative_action : return "The Connection is closed due to an administrative action.";
  380. case error::payload_format_invalid : return "The payload format does not match the specified Payload Format Indicator.";
  381. case error::retain_not_supported : return "The Server has does not support retained messages.";
  382. case error::qos_not_supported : return "The Server does not support the QoS set in Will QoS.";
  383. case error::use_another_server : return "The Client should temporarily use another server.";
  384. case error::server_moved : return "The Server is moved and the Client should permanently use another server.";
  385. case error::shared_subscriptions_not_supported : return "The Server does not support Shared Subscriptions.";
  386. case error::connection_rate_exceeded : return "The connection rate limit has been exceeded.";
  387. case error::maximum_connect_time : return "The maximum connection time authorized for this connection has been exceeded.";
  388. case error::subscription_identifiers_not_supported: return "The Server does not support Subscription Identifiers; the subscription is not accepted.";
  389. case error::wildcard_subscriptions_not_supported : return "The Server does not support Wildcard Subscriptions; the subscription is not accepted.";
  390. default : return "Unknown error";
  391. }
  392. }
  393. inline error_condition default_error_condition(int ev) const noexcept override
  394. {
  395. return error_condition{ ev, *this };
  396. }
  397. };
  398. inline const mqtt_error_category& mqtt_category() noexcept
  399. {
  400. static mqtt_error_category const cat{};
  401. return cat;
  402. }
  403. inline asio::error_code make_error_code(error e)
  404. {
  405. return asio::error_code{ static_cast<std::underlying_type<error>::type>(e), mqtt_category() };
  406. }
  407. inline error_condition make_error_condition(condition c)
  408. {
  409. return error_condition{ static_cast<std::underlying_type<condition>::type>(c), mqtt_category() };
  410. }
  411. template<typename = void>
  412. inline constexpr std::string_view to_string(error e)
  413. {
  414. using namespace std::string_view_literals;
  415. switch (e)
  416. {
  417. case error::success : return "The operation completed successfully.";
  418. //case error::normal_disconnection : return "Close the connection normally. Do not send the Will Message.";
  419. //case error::granted_qos_0 : return "Granted the PUBLISH Quality of Service is 0";
  420. case error::granted_qos_1 : return "Granted the PUBLISH Quality of Service is 1";
  421. case error::granted_qos_2 : return "Granted the PUBLISH Quality of Service is 2";
  422. case error::disconnect_with_will_message : return "The Client wishes to disconnect but requires that the Server also publishes its Will Message.";
  423. case error::no_matching_subscribers : return "The message is accepted but there are no subscribers. This is sent only by the Server. If the Server knows that there are no matching subscribers, it MAY use this Reason Code instead of 0x00 (Success).";
  424. case error::no_subscription_existed : return "No subscription existed";
  425. case error::continue_authentication : return "Continue the authentication with another step";
  426. case error::reauthenticate : return "Initiate a re-authentication";
  427. case error::unspecified_error : return "The Server or Client does not wish to reveal the reason for the failure, or none of the other Reason Codes apply.";
  428. case error::malformed_packet : return "The received packet does not conform to this specification.";
  429. case error::protocol_error : return "An unexpected or out of order packet was received.";
  430. case error::implementation_specific_error : return "The packet received is valid but cannot be processed by this implementation.";
  431. case error::unsupported_protocol_version : return "The Server does not support the version of the MQTT protocol requested by the Client.";
  432. case error::client_identifier_not_valid : return "The Client Identifier is a valid string but is not allowed by the Server.";
  433. case error::bad_user_name_or_password : return "The Server does not accept the User Name or Password specified by the Client";
  434. case error::not_authorized : return "The request is not authorized.";
  435. case error::server_unavailable : return "The MQTT Server is not available.";
  436. case error::server_busy : return "The Server is busy and cannot continue processing requests from this Client.";
  437. case error::banned : return "This Client has been banned by administrative action. Contact the server administrator.";
  438. case error::server_shutting_down : return "The Server is shutting down.";
  439. case error::bad_authentication_method : return "The authentication method is not supported or does not match the authentication method currently in use.";
  440. case error::keep_alive_timeout : return "The Connection is closed because no packet has been received for 1.5 times the Keepalive time.";
  441. case error::session_taken_over : return "Another Connection using the same ClientID has connected causing this Connection to be closed.";
  442. case error::topic_filter_invalid : return "The Topic Filter is correctly formed, but is not accepted by this Sever.";
  443. case error::topic_name_invalid : return "The Topic Name is not malformed, but is not accepted by this Client or Server.";
  444. case error::packet_identifier_in_use : return "The Packet Identifier is already in use. This might indicate a mismatch in the Session State between the Client and Server.";
  445. case error::packet_identifier_not_found : return "The Packet Identifier is not known. This is not an error during recovery, but at other times indicates a mismatch between the Session State on the Client and Server.";
  446. case error::receive_maximum_exceeded : return "The Client or Server has received more than Receive Maximum publication for which it has not sent PUBACK or PUBCOMP.";
  447. case error::topic_alias_invalid : return "The Client or Server has received a PUBLISH packet containing a Topic Alias which is greater than the Maximum Topic Alias it sent in the CONNECT or CONNACK packet.";
  448. case error::packet_too_large : return "The packet size is greater than Maximum Packet Size for this Client or Server.";
  449. case error::message_rate_too_high : return "The received data rate is too high.";
  450. case error::quota_exceeded : return "An implementation or administrative imposed limit has been exceeded.";
  451. case error::administrative_action : return "The Connection is closed due to an administrative action.";
  452. case error::payload_format_invalid : return "The payload format does not match the specified Payload Format Indicator.";
  453. case error::retain_not_supported : return "The Server has does not support retained messages.";
  454. case error::qos_not_supported : return "The Server does not support the QoS set in Will QoS.";
  455. case error::use_another_server : return "The Client should temporarily use another server.";
  456. case error::server_moved : return "The Server is moved and the Client should permanently use another server.";
  457. case error::shared_subscriptions_not_supported : return "The Server does not support Shared Subscriptions.";
  458. case error::connection_rate_exceeded : return "The connection rate limit has been exceeded.";
  459. case error::maximum_connect_time : return "The maximum connection time authorized for this connection has been exceeded.";
  460. case error::subscription_identifiers_not_supported: return "The Server does not support Subscription Identifiers; the subscription is not accepted.";
  461. case error::wildcard_subscriptions_not_supported : return "The Server does not support Wildcard Subscriptions; the subscription is not accepted.";
  462. default : return "Unknown error";
  463. }
  464. return "Unknown error";
  465. };
  466. }
  467. namespace mqtt = ::asio2::mqtt;
  468. namespace std
  469. {
  470. template<>
  471. struct is_error_code_enum<::asio2::mqtt::error>
  472. {
  473. static bool const value = true;
  474. };
  475. template<>
  476. struct is_error_condition_enum<::asio2::mqtt::condition>
  477. {
  478. static bool const value = true;
  479. };
  480. }
  481. #endif // !__ASIO2_MQTT_ERROR_HPP__