response_options.h 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. /////////////////////////////////////////////////////////////////////////////
  2. /// @file response_options.h
  3. /// Implementation of the class 'response_options'
  4. /// @date 26-Aug-2019
  5. /////////////////////////////////////////////////////////////////////////////
  6. /*******************************************************************************
  7. * Copyright (c) 2019-2025 Frank Pagliughi <fpagliughi@mindspring.com>
  8. *
  9. * All rights reserved. This program and the accompanying materials
  10. * are made available under the terms of the Eclipse Public License v2.0
  11. * and Eclipse Distribution License v1.0 which accompany this distribution.
  12. *
  13. * The Eclipse Public License is available at
  14. * http://www.eclipse.org/legal/epl-v20.html
  15. * and the Eclipse Distribution License is available at
  16. * http://www.eclipse.org/org/documents/edl-v10.php.
  17. *
  18. * Contributors:
  19. * Frank Pagliughi - initial implementation and documentation
  20. *******************************************************************************/
  21. #ifndef __mqtt_response_options_h
  22. #define __mqtt_response_options_h
  23. #include "MQTTAsync.h"
  24. #include "mqtt/delivery_token.h"
  25. #include "mqtt/token.h"
  26. #include "subscribe_options.h"
  27. namespace mqtt {
  28. class token_test;
  29. /////////////////////////////////////////////////////////////////////////////
  30. // response_options
  31. /////////////////////////////////////////////////////////////////////////////
  32. /**
  33. * The response options for various asynchronous calls.
  34. *
  35. * This is an internal data structure, only used within the library.
  36. * Therefore it is not totally fleshed out, but rather only exposes the
  37. * functionality currently required by the library.
  38. *
  39. * Note, too, in the C lib, this became a place to add MQTT v5 options for
  40. * the outgoing calls without breaking the API, so is also referred to as the
  41. * "call options".
  42. */
  43. class response_options
  44. {
  45. /** The underlying C structure */
  46. MQTTAsync_responseOptions opts_ MQTTAsync_responseOptions_initializer;
  47. /** The token to which we are connected */
  48. token::weak_ptr_t tok_;
  49. /** Packet Properties (Subscribe/Unsubscribe) */
  50. properties props_;
  51. /** A list of subscription options for subscribe-many */
  52. std::vector<MQTTSubscribe_options> subOpts_;
  53. /** The client has special access */
  54. friend class async_client;
  55. /** Update the underlying C struct to match our data */
  56. void update_c_struct();
  57. public:
  58. /**
  59. * Create an empty response object.
  60. * @param mqttVersion The MQTT version for the response.
  61. */
  62. explicit response_options(int mqttVersion = MQTTVERSION_DEFAULT) {
  63. set_mqtt_version(mqttVersion);
  64. }
  65. /**
  66. * Creates a response object with the specified callbacks.
  67. * @param tok A token to be used as the context.
  68. * @param mqttVersion The MQTT version for the response.
  69. */
  70. response_options(const token_ptr& tok, int mqttVersion = MQTTVERSION_DEFAULT);
  71. /**
  72. * Copy constructor.
  73. * @param other The other options to copy to this one.
  74. */
  75. response_options(const response_options& other);
  76. /**
  77. * Move constructor.
  78. * @param other The other options to move into this one.
  79. */
  80. response_options(response_options&& other);
  81. /**
  82. * Copy operator.
  83. * @param rhs The other options to copy to this one.
  84. */
  85. response_options& operator=(const response_options& rhs);
  86. /**
  87. * Move operator.
  88. * @param rhs The other options to move into this one.
  89. */
  90. response_options& operator=(response_options&& rhs);
  91. /**
  92. * Expose the underlying C struct for the unit tests.
  93. */
  94. #if defined(UNIT_TESTS)
  95. const auto& c_struct() const { return opts_; }
  96. #endif
  97. /**
  98. * Sets the MQTT protocol version used for the response.
  99. * This sets up proper callbacks for MQTT v5 or versions prior to that.
  100. * @param mqttVersion The MQTT version used by the connection.
  101. */
  102. void set_mqtt_version(int mqttVersion);
  103. /**
  104. * Sets the callback context to a generic token.
  105. * @param tok The token to be used as the callback context.
  106. */
  107. void set_token(const token_ptr& tok);
  108. /**
  109. * Gets the properties for the response options.
  110. */
  111. const properties& get_properties() const { return props_; }
  112. /**
  113. * Sets the properties for the response options.
  114. * @param props The properties for the response options.
  115. */
  116. void set_properties(const properties& props) {
  117. props_ = props;
  118. opts_.properties = props_.c_struct();
  119. }
  120. /**
  121. * Moves the properties for the response options.
  122. * @param props The properties to move into the response options.
  123. */
  124. void set_properties(properties&& props) {
  125. props_ = std::move(props);
  126. opts_.properties = props_.c_struct();
  127. }
  128. /**
  129. * Gets the options for a single topic subscription.
  130. * @return The subscribe options.
  131. */
  132. subscribe_options get_subscribe_options() const {
  133. return subscribe_options{opts_.subscribeOptions};
  134. }
  135. /**
  136. * Sets the options for a multi-topic subscription.
  137. * @return The vector of the subscribe options.
  138. */
  139. std::vector<subscribe_options> get_subscribe_many_options() const;
  140. /**
  141. * Sets the options for a single topic subscription.
  142. * @param opts The subscribe options.
  143. */
  144. void set_subscribe_options(const subscribe_options& opts);
  145. /**
  146. * Sets the options for a multi-topic subscription.
  147. * @param opts A vector of the subscribe options.
  148. */
  149. void set_subscribe_many_options(const std::vector<subscribe_options>& opts);
  150. /**
  151. * Sets the options for a multi-topic subscription.
  152. * @param opts A vector of the subscribe options.
  153. * @sa set_subscribe_options
  154. */
  155. void set_subscribe_options(const std::vector<subscribe_options>& opts) {
  156. set_subscribe_many_options(opts);
  157. }
  158. };
  159. /////////////////////////////////////////////////////////////////////////////
  160. /**
  161. * Class to build response options.
  162. */
  163. class response_options_builder
  164. {
  165. /** The underlying options */
  166. response_options opts_;
  167. public:
  168. /** This class */
  169. using self = response_options_builder;
  170. /**
  171. * Default constructor.
  172. */
  173. explicit response_options_builder(int mqttVersion = MQTTVERSION_DEFAULT)
  174. : opts_(mqttVersion) {}
  175. /**
  176. * Sets the MQTT protocol version used for the response.
  177. * This sets up proper callbacks for MQTT v5 or versions prior to that.
  178. * @param mqttVersion The MQTT version used by the connection.
  179. */
  180. auto mqtt_version(int mqttVersion) -> self& {
  181. opts_.set_mqtt_version(mqttVersion);
  182. return *this;
  183. }
  184. /**
  185. * Sets the callback context to a generic token.
  186. * @param tok The token to be used as the callback context.
  187. */
  188. auto token(const token_ptr& tok) -> self& {
  189. opts_.set_token(tok);
  190. return *this;
  191. }
  192. /**
  193. * Sets the properties for the response options.
  194. * @param props The properties for the response options.
  195. */
  196. auto properties(mqtt::properties&& props) -> self& {
  197. opts_.set_properties(std::move(props));
  198. return *this;
  199. }
  200. /**
  201. * Sets the properties for the disconnect message.
  202. * @param props The properties for the disconnect message.
  203. */
  204. auto properties(const mqtt::properties& props) -> self& {
  205. opts_.set_properties(props);
  206. return *this;
  207. }
  208. /**
  209. * Sets the options for a single topic subscription.
  210. * @param opts The subscribe options.
  211. */
  212. auto subscribe_opts(const subscribe_options& opts) -> self& {
  213. opts_.set_subscribe_options(opts);
  214. return *this;
  215. }
  216. /**
  217. * Sets the options for a multi-topic subscription.
  218. * @param opts A vector of the subscribe options.
  219. */
  220. auto subscribe_many_opts(const std::vector<subscribe_options>& opts) -> self& {
  221. opts_.set_subscribe_options(opts);
  222. return *this;
  223. }
  224. /**
  225. * Sets the options for a multi-topic subscription.
  226. * @param opts A vector of the subscribe options.
  227. */
  228. auto subscribe_opts(const std::vector<subscribe_options>& opts) -> self& {
  229. opts_.set_subscribe_options(opts);
  230. return *this;
  231. }
  232. /**
  233. * Finish building the response options and return them.
  234. * @return The response option struct as built.
  235. */
  236. response_options finalize() { return opts_; }
  237. };
  238. /////////////////////////////////////////////////////////////////////////////
  239. // delivery_response_options
  240. /////////////////////////////////////////////////////////////////////////////
  241. /**
  242. * The response options for asynchronous calls targeted at delivery.
  243. * Each of these objects is tied to a specific delivery_token.
  244. */
  245. class delivery_response_options
  246. {
  247. /** The underlying C structure */
  248. MQTTAsync_responseOptions opts_;
  249. /** The delivery token to which we are connected */
  250. delivery_token::weak_ptr_t dtok_;
  251. /** The client has special access */
  252. friend class async_client;
  253. public:
  254. /**
  255. * Create an empty delivery response object.
  256. */
  257. delivery_response_options(int mqttVersion = MQTTVERSION_DEFAULT);
  258. /**
  259. * Creates a response object tied to the specific delivery token.
  260. * @param dtok A delivery token to be used as the context.
  261. * @param mqttVersion The MQTT version for the response
  262. */
  263. delivery_response_options(
  264. const delivery_token_ptr& dtok, int mqttVersion = MQTTVERSION_DEFAULT
  265. );
  266. /**
  267. * Expose the underlying C struct for the unit tests.
  268. */
  269. #if defined(UNIT_TESTS)
  270. const MQTTAsync_responseOptions& c_struct() const { return opts_; }
  271. #endif
  272. /**
  273. * Sets the callback context to a delivery token.
  274. * @param dtok The delivery token to be used as the callback context.
  275. */
  276. void set_token(const delivery_token_ptr& dtok) {
  277. dtok_ = dtok;
  278. opts_.context = dtok.get();
  279. }
  280. };
  281. /////////////////////////////////////////////////////////////////////////////
  282. } // namespace mqtt
  283. #endif // __mqtt_response_options_h