Mqtt5Packets.cpp 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236
  1. /**
  2. * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
  3. * SPDX-License-Identifier: Apache-2.0.
  4. */
  5. #include <aws/crt/mqtt/Mqtt5Client.h>
  6. #include <aws/crt/mqtt/Mqtt5Packets.h>
  7. namespace Aws
  8. {
  9. namespace Crt
  10. {
  11. namespace Mqtt5
  12. {
  13. template <typename T> void setPacketVector(Vector<T> &vector, const T *values, size_t length)
  14. {
  15. vector.clear();
  16. for (size_t i = 0; i < length; ++i)
  17. {
  18. vector.push_back(values[i]);
  19. }
  20. }
  21. template <typename T> void setPacketOptional(Optional<T> &optional, const T *value)
  22. {
  23. if (value != nullptr)
  24. {
  25. optional = *value;
  26. }
  27. else
  28. {
  29. optional.reset();
  30. }
  31. }
  32. void setPacketStringOptional(
  33. Optional<aws_byte_cursor> &optional,
  34. Crt::String &optionalStorage,
  35. const aws_byte_cursor *value)
  36. {
  37. if (value != nullptr)
  38. {
  39. optionalStorage = Crt::String((const char *)value->ptr, value->len);
  40. struct aws_byte_cursor optional_cursor;
  41. optional_cursor.ptr = (uint8_t *)optionalStorage.c_str();
  42. optional_cursor.len = optionalStorage.size();
  43. optional = optional_cursor;
  44. }
  45. }
  46. void setPacketStringOptional(Optional<Crt::String> &optional, const aws_byte_cursor *value)
  47. {
  48. if (value != nullptr)
  49. {
  50. optional = Crt::String((const char *)value->ptr, value->len);
  51. }
  52. else
  53. {
  54. optional.reset();
  55. }
  56. }
  57. void setPacketStringOptional(Optional<Crt::String> &optional, Crt::String &&toMove)
  58. {
  59. if (!toMove.empty())
  60. {
  61. optional = std::move(toMove);
  62. }
  63. else
  64. {
  65. optional.reset();
  66. }
  67. }
  68. void setPacketByteBufOptional(
  69. Optional<aws_byte_cursor> &optional,
  70. ByteBuf &optionalStorage,
  71. Allocator *allocator,
  72. const aws_byte_cursor *value)
  73. {
  74. aws_byte_buf_clean_up(&optionalStorage);
  75. AWS_ZERO_STRUCT(optionalStorage);
  76. if (value != nullptr)
  77. {
  78. aws_byte_buf_init_copy_from_cursor(&optionalStorage, allocator, *value);
  79. optional = aws_byte_cursor_from_buf(&optionalStorage);
  80. }
  81. else
  82. {
  83. optional.reset();
  84. }
  85. }
  86. void setUserProperties(
  87. Vector<UserProperty> &userProperties,
  88. const struct aws_mqtt5_user_property *properties,
  89. size_t propertyCount)
  90. {
  91. for (size_t i = 0; i < propertyCount; ++i)
  92. {
  93. userProperties.push_back(UserProperty(
  94. Aws::Crt::String((const char *)properties[i].name.ptr, properties[i].name.len),
  95. Aws::Crt::String((const char *)properties[i].value.ptr, properties[i].value.len)));
  96. }
  97. }
  98. template <typename T> void setNullableFromOptional(const T *&nullable, const Optional<T> &optional)
  99. {
  100. if (optional.has_value())
  101. {
  102. nullable = &optional.value();
  103. }
  104. }
  105. void s_AllocateUnderlyingUserProperties(
  106. aws_mqtt5_user_property *&dst,
  107. const Crt::Vector<UserProperty> &userProperties,
  108. Allocator *allocator)
  109. {
  110. if (dst != nullptr)
  111. {
  112. aws_mem_release(allocator, (void *)dst);
  113. dst = nullptr;
  114. }
  115. if (userProperties.size() > 0)
  116. {
  117. dst = reinterpret_cast<struct aws_mqtt5_user_property *>(
  118. aws_mem_calloc(allocator, userProperties.size(), sizeof(aws_mqtt5_user_property)));
  119. AWS_ZERO_STRUCT(*dst);
  120. for (size_t index = 0; index < userProperties.size(); ++index)
  121. {
  122. (dst + index)->name = aws_byte_cursor_from_array(
  123. userProperties[index].getName().c_str(), userProperties[index].getName().length());
  124. (dst + index)->value = aws_byte_cursor_from_array(
  125. userProperties[index].getValue().c_str(), userProperties[index].getValue().length());
  126. }
  127. }
  128. }
  129. void s_AllocateStringVector(
  130. aws_array_list &dst,
  131. const Crt::Vector<String> &stringVector,
  132. Allocator *allocator)
  133. {
  134. AWS_ZERO_STRUCT(dst);
  135. if (aws_array_list_init_dynamic(&dst, allocator, stringVector.size(), sizeof(aws_byte_cursor)) !=
  136. AWS_OP_SUCCESS)
  137. {
  138. return;
  139. }
  140. for (auto &topic : stringVector)
  141. {
  142. ByteCursor topicCursor = ByteCursorFromString(topic);
  143. aws_array_list_push_back(&dst, reinterpret_cast<const void *>(&topicCursor));
  144. }
  145. }
  146. void s_AllocateUnderlyingSubscription(
  147. aws_mqtt5_subscription_view *&dst,
  148. const Crt::Vector<Subscription> &subscriptions,
  149. Allocator *allocator)
  150. {
  151. if (dst != nullptr)
  152. {
  153. aws_mem_release(allocator, dst);
  154. dst = nullptr;
  155. }
  156. aws_array_list subscription_list;
  157. AWS_ZERO_STRUCT(subscription_list);
  158. if (aws_array_list_init_dynamic(
  159. &subscription_list, allocator, subscriptions.size(), sizeof(aws_mqtt5_subscription_view)) !=
  160. AWS_OP_SUCCESS)
  161. {
  162. return;
  163. }
  164. for (auto &subscription : subscriptions)
  165. {
  166. aws_mqtt5_subscription_view underlying_subscription;
  167. if (subscription.initializeRawOptions(underlying_subscription) != true)
  168. {
  169. goto clean_up;
  170. }
  171. aws_array_list_push_back(
  172. &subscription_list, reinterpret_cast<const void *>(&underlying_subscription));
  173. }
  174. dst = static_cast<aws_mqtt5_subscription_view *>(subscription_list.data);
  175. return;
  176. clean_up:
  177. aws_array_list_clean_up(&subscription_list);
  178. }
  179. ConnectPacket::ConnectPacket(Allocator *allocator) noexcept
  180. : m_allocator(allocator), m_keepAliveIntervalSec(1200), m_userPropertiesStorage(nullptr)
  181. {
  182. // m_clientId.clear();
  183. AWS_ZERO_STRUCT(m_usernameCursor);
  184. AWS_ZERO_STRUCT(m_passowrdStorage);
  185. AWS_ZERO_STRUCT(m_willStorage);
  186. }
  187. ConnectPacket &ConnectPacket::withKeepAliveIntervalSec(uint16_t second) noexcept
  188. {
  189. m_keepAliveIntervalSec = second;
  190. return *this;
  191. }
  192. ConnectPacket &ConnectPacket::withClientId(Crt::String client_id) noexcept
  193. {
  194. m_clientId = std::move(client_id);
  195. return *this;
  196. }
  197. ConnectPacket &ConnectPacket::withUserName(Crt::String username) noexcept
  198. {
  199. m_username = std::move(username);
  200. m_usernameCursor = ByteCursorFromString(m_username.value());
  201. return *this;
  202. }
  203. ConnectPacket &ConnectPacket::withPassword(Crt::ByteCursor password) noexcept
  204. {
  205. setPacketByteBufOptional(m_password, m_passowrdStorage, m_allocator, &password);
  206. return *this;
  207. }
  208. ConnectPacket &ConnectPacket::withSessionExpiryIntervalSec(uint32_t sessionExpiryIntervalSec) noexcept
  209. {
  210. m_sessionExpiryIntervalSec = sessionExpiryIntervalSec;
  211. return *this;
  212. }
  213. ConnectPacket &ConnectPacket::withRequestResponseInformation(bool requestResponseInformation) noexcept
  214. {
  215. m_requestResponseInformation = requestResponseInformation;
  216. return *this;
  217. }
  218. ConnectPacket &ConnectPacket::withRequestProblemInformation(bool requestProblemInformation) noexcept
  219. {
  220. m_requestProblemInformation = requestProblemInformation;
  221. return *this;
  222. }
  223. ConnectPacket &ConnectPacket::withReceiveMaximum(uint16_t receiveMaximum) noexcept
  224. {
  225. m_receiveMaximum = receiveMaximum;
  226. return *this;
  227. }
  228. ConnectPacket &ConnectPacket::withMaximumPacketSizeBytes(uint32_t maximumPacketSizeBytes) noexcept
  229. {
  230. m_maximumPacketSizeBytes = maximumPacketSizeBytes;
  231. return *this;
  232. }
  233. ConnectPacket &ConnectPacket::withWillDelayIntervalSec(uint32_t willDelayIntervalSec) noexcept
  234. {
  235. m_willDelayIntervalSeconds = willDelayIntervalSec;
  236. return *this;
  237. }
  238. ConnectPacket &ConnectPacket::withWill(std::shared_ptr<PublishPacket> will) noexcept
  239. {
  240. m_will = will;
  241. m_will.value()->initializeRawOptions(m_willStorage);
  242. return *this;
  243. }
  244. ConnectPacket &ConnectPacket::withUserProperties(const Vector<UserProperty> &userProperties) noexcept
  245. {
  246. m_userProperties = userProperties;
  247. return *this;
  248. }
  249. ConnectPacket &ConnectPacket::withUserProperties(Vector<UserProperty> &&userProperties) noexcept
  250. {
  251. m_userProperties = userProperties;
  252. return *this;
  253. }
  254. ConnectPacket &ConnectPacket::withUserProperty(UserProperty &&property) noexcept
  255. {
  256. m_userProperties.push_back(std::move(property));
  257. return *this;
  258. }
  259. bool ConnectPacket::initializeRawOptions(
  260. aws_mqtt5_packet_connect_view &raw_options,
  261. Allocator * /*allocator*/) noexcept
  262. {
  263. AWS_ZERO_STRUCT(raw_options);
  264. raw_options.keep_alive_interval_seconds = m_keepAliveIntervalSec;
  265. raw_options.client_id = ByteCursorFromString(m_clientId);
  266. if (m_username.has_value())
  267. {
  268. raw_options.username = &m_usernameCursor;
  269. }
  270. if (m_password.has_value())
  271. {
  272. raw_options.password = &m_password.value();
  273. }
  274. if (m_sessionExpiryIntervalSec.has_value())
  275. {
  276. raw_options.session_expiry_interval_seconds = &m_sessionExpiryIntervalSec.value();
  277. }
  278. if (m_requestProblemInformation.has_value())
  279. {
  280. m_requestResponseInformationStorage = m_requestResponseInformation.value() ? 1 : 0;
  281. raw_options.request_response_information = &m_requestResponseInformationStorage;
  282. }
  283. if (m_requestProblemInformation.has_value())
  284. {
  285. m_requestProblemInformationStorage = m_requestProblemInformation.value() ? 1 : 0;
  286. raw_options.request_problem_information = &m_requestProblemInformationStorage;
  287. }
  288. if (m_receiveMaximum.has_value())
  289. {
  290. raw_options.receive_maximum = &m_receiveMaximum.value();
  291. }
  292. if (m_maximumPacketSizeBytes.has_value())
  293. {
  294. raw_options.maximum_packet_size_bytes = &m_maximumPacketSizeBytes.value();
  295. }
  296. if (m_willDelayIntervalSeconds.has_value())
  297. {
  298. raw_options.will_delay_interval_seconds = &m_willDelayIntervalSeconds.value();
  299. }
  300. if (m_will.has_value())
  301. {
  302. raw_options.will = &m_willStorage;
  303. }
  304. s_AllocateUnderlyingUserProperties(m_userPropertiesStorage, m_userProperties, m_allocator);
  305. raw_options.user_properties = m_userPropertiesStorage;
  306. raw_options.user_property_count = m_userProperties.size();
  307. return true;
  308. }
  309. ConnectPacket::~ConnectPacket()
  310. {
  311. if (m_userPropertiesStorage != nullptr)
  312. {
  313. aws_mem_release(m_allocator, m_userPropertiesStorage);
  314. m_userProperties.clear();
  315. }
  316. aws_byte_buf_clean_up(&m_passowrdStorage);
  317. }
  318. uint16_t ConnectPacket::getKeepAliveIntervalSec() const noexcept { return m_keepAliveIntervalSec; }
  319. const Crt::String &ConnectPacket::getClientId() const noexcept { return m_clientId; }
  320. const Crt::Optional<Crt::String> &ConnectPacket::getUsername() const noexcept { return m_username; }
  321. const Crt::Optional<Crt::ByteCursor> &ConnectPacket::getPassword() const noexcept { return m_password; }
  322. const Crt::Optional<uint32_t> &ConnectPacket::getSessionExpiryIntervalSec() const noexcept
  323. {
  324. return m_sessionExpiryIntervalSec;
  325. }
  326. const Crt::Optional<bool> &ConnectPacket::getRequestResponseInformation() const noexcept
  327. {
  328. return m_requestResponseInformation;
  329. }
  330. const Crt::Optional<bool> &ConnectPacket::getRequestProblemInformation() const noexcept
  331. {
  332. return m_requestProblemInformation;
  333. }
  334. const Crt::Optional<uint16_t> &ConnectPacket::getReceiveMaximum() const noexcept
  335. {
  336. return m_receiveMaximum;
  337. }
  338. const Crt::Optional<uint32_t> &ConnectPacket::getMaximumPacketSizeBytes() const noexcept
  339. {
  340. return m_maximumPacketSizeBytes;
  341. }
  342. const Crt::Optional<uint32_t> &ConnectPacket::getWillDelayIntervalSec() const noexcept
  343. {
  344. return m_willDelayIntervalSeconds;
  345. }
  346. const Crt::Optional<std::shared_ptr<PublishPacket>> &ConnectPacket::getWill() const noexcept
  347. {
  348. return m_will;
  349. }
  350. const Crt::Vector<UserProperty> &ConnectPacket::getUserProperties() const noexcept
  351. {
  352. return m_userProperties;
  353. }
  354. UserProperty::UserProperty(Crt::String name, Crt::String value) noexcept
  355. : m_name(std::move(name)), m_value(std::move(value))
  356. {
  357. }
  358. UserProperty::~UserProperty() noexcept {}
  359. UserProperty::UserProperty(const UserProperty &toCopy) noexcept
  360. : m_name(toCopy.getName()), m_value(toCopy.getValue())
  361. {
  362. }
  363. UserProperty::UserProperty(UserProperty &&toMove) noexcept
  364. : m_name(std::move(toMove.m_name)), m_value(std::move(toMove.m_value))
  365. {
  366. }
  367. UserProperty &UserProperty::operator=(const UserProperty &toCopy) noexcept
  368. {
  369. if (&toCopy != this)
  370. {
  371. m_name = toCopy.getName();
  372. m_value = toCopy.getValue();
  373. }
  374. return *this;
  375. }
  376. UserProperty &UserProperty::operator=(UserProperty &&toMove) noexcept
  377. {
  378. if (&toMove != this)
  379. {
  380. m_name = std::move(toMove.m_name);
  381. m_value = std::move(toMove.m_value);
  382. }
  383. return *this;
  384. }
  385. PublishPacket::PublishPacket(const aws_mqtt5_packet_publish_view &packet, Allocator *allocator) noexcept
  386. : m_allocator(allocator), m_qos(packet.qos), m_retain(packet.retain),
  387. m_topicName((const char *)packet.topic.ptr, packet.topic.len), m_userPropertiesStorage(nullptr)
  388. {
  389. AWS_ZERO_STRUCT(m_payloadStorage);
  390. AWS_ZERO_STRUCT(m_contentTypeStorage);
  391. AWS_ZERO_STRUCT(m_correlationDataStorage);
  392. AWS_ZERO_STRUCT(m_payload);
  393. withPayload(packet.payload);
  394. setPacketOptional(m_payloadFormatIndicator, packet.payload_format);
  395. setPacketOptional(m_messageExpiryIntervalSec, packet.message_expiry_interval_seconds);
  396. setPacketStringOptional(m_responseTopic, m_responseTopicString, packet.response_topic);
  397. setPacketByteBufOptional(
  398. m_correlationData, m_correlationDataStorage, allocator, packet.correlation_data);
  399. setPacketByteBufOptional(m_contentType, m_contentTypeStorage, allocator, packet.content_type);
  400. setPacketVector(
  401. m_subscriptionIdentifiers, packet.subscription_identifiers, packet.subscription_identifier_count);
  402. setUserProperties(m_userProperties, packet.user_properties, packet.user_property_count);
  403. }
  404. /* Default constructor */
  405. PublishPacket::PublishPacket(Allocator *allocator) noexcept
  406. : m_allocator(allocator), m_qos(QOS::AWS_MQTT5_QOS_AT_MOST_ONCE), m_retain(false), m_topicName(""),
  407. m_userPropertiesStorage(nullptr)
  408. {
  409. AWS_ZERO_STRUCT(m_payloadStorage);
  410. AWS_ZERO_STRUCT(m_contentTypeStorage);
  411. AWS_ZERO_STRUCT(m_correlationDataStorage);
  412. AWS_ZERO_STRUCT(m_payload);
  413. }
  414. PublishPacket::PublishPacket(
  415. Crt::String topic,
  416. ByteCursor payload,
  417. Mqtt5::QOS qos,
  418. Allocator *allocator) noexcept
  419. : m_allocator(allocator), m_qos(qos), m_retain(false), m_topicName(std::move(topic)),
  420. m_userPropertiesStorage(nullptr)
  421. {
  422. AWS_ZERO_STRUCT(m_payloadStorage);
  423. AWS_ZERO_STRUCT(m_contentTypeStorage);
  424. AWS_ZERO_STRUCT(m_correlationDataStorage);
  425. AWS_ZERO_STRUCT(m_payload);
  426. // Setup message payload, sync with PublishPacket::withPayload
  427. aws_byte_buf_clean_up(&m_payloadStorage);
  428. aws_byte_buf_init_copy_from_cursor(&m_payloadStorage, m_allocator, payload);
  429. m_payload = aws_byte_cursor_from_buf(&m_payloadStorage);
  430. }
  431. PublishPacket &PublishPacket::withPayload(ByteCursor payload) noexcept
  432. {
  433. aws_byte_buf_clean_up(&m_payloadStorage);
  434. aws_byte_buf_init_copy_from_cursor(&m_payloadStorage, m_allocator, payload);
  435. m_payload = aws_byte_cursor_from_buf(&m_payloadStorage);
  436. return *this;
  437. }
  438. PublishPacket &PublishPacket::withQOS(Mqtt5::QOS qos) noexcept
  439. {
  440. m_qos = qos;
  441. return *this;
  442. }
  443. PublishPacket &PublishPacket::withRetain(bool retain) noexcept
  444. {
  445. m_retain = retain;
  446. return *this;
  447. }
  448. PublishPacket &PublishPacket::withTopic(Crt::String topic) noexcept
  449. {
  450. m_topicName = std::move(topic);
  451. return *this;
  452. }
  453. PublishPacket &PublishPacket::withPayloadFormatIndicator(PayloadFormatIndicator format) noexcept
  454. {
  455. m_payloadFormatIndicator = format;
  456. return *this;
  457. }
  458. PublishPacket &PublishPacket::withMessageExpiryIntervalSec(uint32_t second) noexcept
  459. {
  460. m_messageExpiryIntervalSec = second;
  461. return *this;
  462. }
  463. PublishPacket &PublishPacket::withResponseTopic(ByteCursor responseTopic) noexcept
  464. {
  465. setPacketStringOptional(m_responseTopic, m_responseTopicString, &responseTopic);
  466. return *this;
  467. }
  468. PublishPacket &PublishPacket::withCorrelationData(ByteCursor correlationData) noexcept
  469. {
  470. setPacketByteBufOptional(m_correlationData, m_correlationDataStorage, m_allocator, &correlationData);
  471. return *this;
  472. }
  473. PublishPacket &PublishPacket::withUserProperties(const Vector<UserProperty> &userProperties) noexcept
  474. {
  475. m_userProperties = userProperties;
  476. return *this;
  477. }
  478. PublishPacket &PublishPacket::withUserProperties(Vector<UserProperty> &&userProperties) noexcept
  479. {
  480. m_userProperties = userProperties;
  481. return *this;
  482. }
  483. PublishPacket &PublishPacket::withUserProperty(UserProperty &&property) noexcept
  484. {
  485. m_userProperties.push_back(std::move(property));
  486. return *this;
  487. }
  488. bool PublishPacket::initializeRawOptions(aws_mqtt5_packet_publish_view &raw_options) noexcept
  489. {
  490. AWS_ZERO_STRUCT(raw_options);
  491. raw_options.payload = m_payload;
  492. raw_options.qos = m_qos;
  493. raw_options.retain = m_retain;
  494. raw_options.topic = ByteCursorFromString(m_topicName);
  495. if (m_payloadFormatIndicator.has_value())
  496. {
  497. raw_options.payload_format =
  498. (aws_mqtt5_payload_format_indicator *)&m_payloadFormatIndicator.value();
  499. }
  500. if (m_messageExpiryIntervalSec.has_value())
  501. {
  502. raw_options.message_expiry_interval_seconds = &m_messageExpiryIntervalSec.value();
  503. }
  504. if (m_responseTopic.has_value())
  505. {
  506. raw_options.response_topic = &m_responseTopic.value();
  507. }
  508. if (m_correlationData.has_value())
  509. {
  510. raw_options.correlation_data = &m_correlationData.value();
  511. }
  512. s_AllocateUnderlyingUserProperties(m_userPropertiesStorage, m_userProperties, m_allocator);
  513. raw_options.user_properties = m_userPropertiesStorage;
  514. raw_options.user_property_count = m_userProperties.size();
  515. return true;
  516. }
  517. const ByteCursor &PublishPacket::getPayload() const noexcept { return m_payload; }
  518. Mqtt5::QOS PublishPacket::getQOS() const noexcept { return m_qos; }
  519. bool PublishPacket::getRetain() const noexcept { return m_retain; }
  520. const Crt::String &PublishPacket::getTopic() const noexcept { return m_topicName; }
  521. const Crt::Optional<PayloadFormatIndicator> &PublishPacket::getPayloadFormatIndicator() const noexcept
  522. {
  523. return m_payloadFormatIndicator;
  524. }
  525. const Crt::Optional<uint32_t> &PublishPacket::getMessageExpiryIntervalSec() const noexcept
  526. {
  527. return m_messageExpiryIntervalSec;
  528. }
  529. const Crt::Optional<ByteCursor> &PublishPacket::getResponseTopic() const noexcept
  530. {
  531. return m_responseTopic;
  532. }
  533. const Crt::Optional<ByteCursor> &PublishPacket::getCorrelationData() const noexcept
  534. {
  535. return m_correlationData;
  536. }
  537. const Crt::Vector<uint32_t> &PublishPacket::getSubscriptionIdentifiers() const noexcept
  538. {
  539. return m_subscriptionIdentifiers;
  540. }
  541. const Crt::Optional<ByteCursor> &PublishPacket::getContentType() const noexcept { return m_contentType; }
  542. const Crt::Vector<UserProperty> &PublishPacket::getUserProperties() const noexcept
  543. {
  544. return m_userProperties;
  545. }
  546. PublishPacket::~PublishPacket()
  547. {
  548. aws_byte_buf_clean_up(&m_payloadStorage);
  549. aws_byte_buf_clean_up(&m_correlationDataStorage);
  550. aws_byte_buf_clean_up(&m_contentTypeStorage);
  551. if (m_userProperties.size() > 0)
  552. {
  553. aws_mem_release(m_allocator, m_userPropertiesStorage);
  554. m_userProperties.clear();
  555. }
  556. }
  557. DisconnectPacket::DisconnectPacket(Allocator *allocator) noexcept
  558. : m_allocator(allocator), m_reasonCode(AWS_MQTT5_DRC_NORMAL_DISCONNECTION),
  559. m_userPropertiesStorage(nullptr)
  560. {
  561. }
  562. bool DisconnectPacket::initializeRawOptions(aws_mqtt5_packet_disconnect_view &raw_options) noexcept
  563. {
  564. AWS_ZERO_STRUCT(raw_options);
  565. raw_options.reason_code = m_reasonCode;
  566. if (m_sessionExpiryIntervalSec.has_value())
  567. {
  568. raw_options.session_expiry_interval_seconds = &m_sessionExpiryIntervalSec.value();
  569. }
  570. if (m_reasonString.has_value())
  571. {
  572. m_reasonStringCursor = ByteCursorFromString(m_reasonString.value());
  573. raw_options.reason_string = &m_reasonStringCursor;
  574. }
  575. if (m_serverReference.has_value())
  576. {
  577. m_serverReferenceCursor = ByteCursorFromString(m_serverReference.value());
  578. raw_options.server_reference = &m_serverReferenceCursor;
  579. }
  580. s_AllocateUnderlyingUserProperties(m_userPropertiesStorage, m_userProperties, m_allocator);
  581. raw_options.user_properties = m_userPropertiesStorage;
  582. raw_options.user_property_count = m_userProperties.size();
  583. return true;
  584. }
  585. DisconnectPacket &DisconnectPacket::withReasonCode(const DisconnectReasonCode code) noexcept
  586. {
  587. m_reasonCode = code;
  588. return *this;
  589. }
  590. DisconnectPacket &DisconnectPacket::withSessionExpiryIntervalSec(const uint32_t second) noexcept
  591. {
  592. m_sessionExpiryIntervalSec = second;
  593. return *this;
  594. }
  595. DisconnectPacket &DisconnectPacket::withReasonString(Crt::String reason) noexcept
  596. {
  597. m_reasonString = std::move(reason);
  598. return *this;
  599. }
  600. DisconnectPacket &DisconnectPacket::withServerReference(Crt::String server_reference) noexcept
  601. {
  602. m_serverReference = std::move(server_reference);
  603. return *this;
  604. }
  605. DisconnectPacket &DisconnectPacket::withUserProperties(const Vector<UserProperty> &userProperties) noexcept
  606. {
  607. m_userProperties = userProperties;
  608. return *this;
  609. }
  610. DisconnectPacket &DisconnectPacket::withUserProperties(Vector<UserProperty> &&userProperties) noexcept
  611. {
  612. m_userProperties = userProperties;
  613. return *this;
  614. }
  615. DisconnectPacket &DisconnectPacket::withUserProperty(UserProperty &&property) noexcept
  616. {
  617. m_userProperties.push_back(std::move(property));
  618. return *this;
  619. }
  620. DisconnectReasonCode DisconnectPacket::getReasonCode() const noexcept { return m_reasonCode; }
  621. const Crt::Optional<uint32_t> &DisconnectPacket::getSessionExpiryIntervalSec() const noexcept
  622. {
  623. return m_sessionExpiryIntervalSec;
  624. }
  625. const Crt::Optional<Crt::String> &DisconnectPacket::getReasonString() const noexcept
  626. {
  627. return m_reasonString;
  628. }
  629. const Crt::Optional<Crt::String> &DisconnectPacket::getServerReference() const noexcept
  630. {
  631. return m_serverReference;
  632. }
  633. const Crt::Vector<UserProperty> &DisconnectPacket::getUserProperties() const noexcept
  634. {
  635. return m_userProperties;
  636. }
  637. DisconnectPacket::DisconnectPacket(
  638. const aws_mqtt5_packet_disconnect_view &packet,
  639. Allocator *allocator) noexcept
  640. : m_allocator(allocator), m_userPropertiesStorage(nullptr)
  641. {
  642. m_reasonCode = packet.reason_code;
  643. setPacketOptional(m_sessionExpiryIntervalSec, packet.session_expiry_interval_seconds);
  644. setPacketStringOptional(m_reasonString, packet.reason_string);
  645. setPacketStringOptional(m_serverReference, packet.server_reference);
  646. setUserProperties(m_userProperties, packet.user_properties, packet.user_property_count);
  647. }
  648. DisconnectPacket::~DisconnectPacket()
  649. {
  650. if (m_userPropertiesStorage != nullptr)
  651. {
  652. aws_mem_release(m_allocator, m_userPropertiesStorage);
  653. }
  654. }
  655. PubAckPacket::PubAckPacket(const aws_mqtt5_packet_puback_view &packet, Allocator * /*allocator*/) noexcept
  656. {
  657. m_reasonCode = packet.reason_code;
  658. setPacketStringOptional(m_reasonString, packet.reason_string);
  659. setUserProperties(m_userProperties, packet.user_properties, packet.user_property_count);
  660. }
  661. PubAckReasonCode PubAckPacket::getReasonCode() const noexcept { return m_reasonCode; }
  662. const Crt::Optional<Crt::String> &PubAckPacket::getReasonString() const noexcept { return m_reasonString; }
  663. const Crt::Vector<UserProperty> &PubAckPacket::getUserProperties() const noexcept
  664. {
  665. return m_userProperties;
  666. }
  667. ConnAckPacket::ConnAckPacket(
  668. const aws_mqtt5_packet_connack_view &packet,
  669. Allocator * /*allocator*/) noexcept
  670. {
  671. m_sessionPresent = packet.session_present;
  672. m_reasonCode = packet.reason_code;
  673. setPacketOptional(m_sessionExpiryInterval, packet.session_expiry_interval);
  674. setPacketOptional(m_receiveMaximum, packet.receive_maximum);
  675. setPacketOptional(m_maximumQOS, packet.maximum_qos);
  676. setPacketOptional(m_retainAvailable, packet.retain_available);
  677. setPacketOptional(m_maximumPacketSize, packet.maximum_packet_size);
  678. setPacketStringOptional(m_assignedClientIdentifier, packet.assigned_client_identifier);
  679. setPacketOptional(m_topicAliasMaximum, packet.topic_alias_maximum);
  680. setPacketStringOptional(m_reasonString, packet.reason_string);
  681. setUserProperties(m_userProperties, packet.user_properties, packet.user_property_count);
  682. setPacketOptional(m_wildcardSubscriptionsAvaliable, packet.wildcard_subscriptions_available);
  683. setPacketOptional(m_subscriptionIdentifiersAvaliable, packet.subscription_identifiers_available);
  684. setPacketOptional(m_sharedSubscriptionsAvaliable, packet.shared_subscriptions_available);
  685. setPacketOptional(m_serverKeepAlive, packet.server_keep_alive);
  686. setPacketStringOptional(m_responseInformation, packet.response_information);
  687. setPacketStringOptional(m_serverReference, packet.server_reference);
  688. }
  689. bool ConnAckPacket::getSessionPresent() const noexcept { return m_sessionPresent; }
  690. ConnectReasonCode ConnAckPacket::getReasonCode() const noexcept { return m_reasonCode; }
  691. const Crt::Optional<uint32_t> &ConnAckPacket::getSessionExpiryInterval() const noexcept
  692. {
  693. return m_sessionExpiryInterval;
  694. }
  695. const Crt::Optional<uint16_t> &ConnAckPacket::getReceiveMaximum() const noexcept
  696. {
  697. return m_receiveMaximum;
  698. }
  699. const Crt::Optional<QOS> &ConnAckPacket::getMaximumQOS() const noexcept { return m_maximumQOS; }
  700. const Crt::Optional<bool> &ConnAckPacket::getRetainAvailable() const noexcept { return m_retainAvailable; }
  701. const Crt::Optional<uint32_t> &ConnAckPacket::getMaximumPacketSize() const noexcept
  702. {
  703. return m_maximumPacketSize;
  704. }
  705. const Crt::Optional<String> &ConnAckPacket::getAssignedClientIdentifier() const noexcept
  706. {
  707. return m_assignedClientIdentifier;
  708. }
  709. const Crt::Optional<uint16_t> ConnAckPacket::getTopicAliasMaximum() const noexcept
  710. {
  711. return m_topicAliasMaximum;
  712. }
  713. const Crt::Optional<String> &ConnAckPacket::getReasonString() const noexcept { return m_reasonString; }
  714. const Vector<UserProperty> &ConnAckPacket::getUserProperty() const noexcept { return m_userProperties; }
  715. const Crt::Optional<bool> &ConnAckPacket::getWildcardSubscriptionsAvaliable() const noexcept
  716. {
  717. return m_wildcardSubscriptionsAvaliable;
  718. }
  719. const Crt::Optional<bool> &ConnAckPacket::getSubscriptionIdentifiersAvaliable() const noexcept
  720. {
  721. return m_subscriptionIdentifiersAvaliable;
  722. }
  723. const Crt::Optional<bool> &ConnAckPacket::getSharedSubscriptionsAvaliable() const noexcept
  724. {
  725. return m_sharedSubscriptionsAvaliable;
  726. }
  727. const Crt::Optional<uint16_t> &ConnAckPacket::getServerKeepAlive() const noexcept
  728. {
  729. return m_serverKeepAlive;
  730. }
  731. const Crt::Optional<String> &ConnAckPacket::getResponseInformation() const noexcept
  732. {
  733. return m_responseInformation;
  734. }
  735. const Crt::Optional<String> &ConnAckPacket::getServerReference() const noexcept
  736. {
  737. return m_serverReference;
  738. }
  739. Subscription::Subscription(Allocator *allocator)
  740. : m_allocator(allocator), m_topicFilter(""), m_qos(QOS::AWS_MQTT5_QOS_AT_MOST_ONCE), m_noLocal(false),
  741. m_retain(false), m_retainHnadlingType(AWS_MQTT5_RHT_SEND_ON_SUBSCRIBE)
  742. {
  743. }
  744. Subscription::Subscription(Crt::String topicFilter, Mqtt5::QOS qos, Allocator *allocator)
  745. : m_allocator(allocator), m_topicFilter(std::move(topicFilter)), m_qos(qos), m_noLocal(false),
  746. m_retain(false), m_retainHnadlingType(AWS_MQTT5_RHT_SEND_ON_SUBSCRIBE)
  747. {
  748. }
  749. Subscription &Subscription::withTopicFilter(Crt::String topicFilter) noexcept
  750. {
  751. m_topicFilter = std::move(topicFilter);
  752. return *this;
  753. }
  754. Subscription &Subscription::withQOS(Mqtt5::QOS qos) noexcept
  755. {
  756. m_qos = qos;
  757. return *this;
  758. }
  759. Subscription &Subscription::withNoLocal(bool noLocal) noexcept
  760. {
  761. m_noLocal = noLocal;
  762. return *this;
  763. }
  764. Subscription &Subscription::withRetain(bool retain) noexcept
  765. {
  766. m_retain = retain;
  767. return *this;
  768. }
  769. Subscription &Subscription::withRetainHandlingType(RetainHandlingType retainHandlingType) noexcept
  770. {
  771. m_retainHnadlingType = retainHandlingType;
  772. return *this;
  773. }
  774. bool Subscription::initializeRawOptions(aws_mqtt5_subscription_view &raw_options) const noexcept
  775. {
  776. AWS_ZERO_STRUCT(raw_options);
  777. raw_options.topic_filter = ByteCursorFromString(m_topicFilter);
  778. raw_options.no_local = m_noLocal;
  779. raw_options.qos = m_qos;
  780. raw_options.retain_as_published = m_retain;
  781. raw_options.retain_handling_type = m_retainHnadlingType;
  782. return true;
  783. }
  784. Subscription::Subscription(const Subscription &toCopy) noexcept
  785. : m_allocator(toCopy.m_allocator), m_topicFilter(toCopy.m_topicFilter), m_qos(toCopy.m_qos),
  786. m_noLocal(toCopy.m_noLocal), m_retain(toCopy.m_retain),
  787. m_retainHnadlingType(toCopy.m_retainHnadlingType)
  788. {
  789. }
  790. Subscription::Subscription(Subscription &&toMove) noexcept
  791. : m_allocator(toMove.m_allocator), m_topicFilter(std::move(toMove.m_topicFilter)), m_qos(toMove.m_qos),
  792. m_noLocal(toMove.m_noLocal), m_retain(toMove.m_retain),
  793. m_retainHnadlingType(toMove.m_retainHnadlingType)
  794. {
  795. }
  796. Subscription &Subscription::operator=(const Subscription &toCopy) noexcept
  797. {
  798. if (&toCopy != this)
  799. {
  800. m_allocator = toCopy.m_allocator;
  801. m_qos = toCopy.m_qos;
  802. m_topicFilter = toCopy.m_topicFilter;
  803. m_noLocal = toCopy.m_noLocal;
  804. m_retain = toCopy.m_retain;
  805. m_retainHnadlingType = toCopy.m_retainHnadlingType;
  806. }
  807. return *this;
  808. }
  809. Subscription &Subscription::operator=(Subscription &&toMove) noexcept
  810. {
  811. if (&toMove != this)
  812. {
  813. m_allocator = toMove.m_allocator;
  814. m_qos = toMove.m_qos;
  815. m_topicFilter = std::move(toMove.m_topicFilter);
  816. m_noLocal = toMove.m_noLocal;
  817. m_retain = toMove.m_retain;
  818. m_retainHnadlingType = toMove.m_retainHnadlingType;
  819. }
  820. return *this;
  821. }
  822. SubscribePacket::SubscribePacket(Allocator *allocator) noexcept
  823. : m_allocator(allocator), m_subscriptionViewStorage(nullptr), m_userPropertiesStorage(nullptr)
  824. {
  825. }
  826. SubscribePacket &SubscribePacket::withUserProperties(const Vector<UserProperty> &userProperties) noexcept
  827. {
  828. m_userProperties = userProperties;
  829. return *this;
  830. }
  831. SubscribePacket &SubscribePacket::withUserProperties(Vector<UserProperty> &&userProperties) noexcept
  832. {
  833. m_userProperties = userProperties;
  834. return *this;
  835. }
  836. SubscribePacket &SubscribePacket::withUserProperty(UserProperty &&property) noexcept
  837. {
  838. m_userProperties.push_back(std::move(property));
  839. return *this;
  840. }
  841. SubscribePacket &SubscribePacket::withSubscriptionIdentifier(uint32_t identifier) noexcept
  842. {
  843. m_subscriptionIdentifier = identifier;
  844. return *this;
  845. }
  846. SubscribePacket &SubscribePacket::withSubscriptions(const Crt::Vector<Subscription> &subscriptions) noexcept
  847. {
  848. m_subscriptions = subscriptions;
  849. return *this;
  850. }
  851. SubscribePacket &SubscribePacket::withSubscriptions(Vector<Subscription> &&subscriptions) noexcept
  852. {
  853. m_subscriptions = subscriptions;
  854. return *this;
  855. }
  856. SubscribePacket &SubscribePacket::withSubscription(Subscription &&subscription) noexcept
  857. {
  858. m_subscriptions.push_back(subscription);
  859. return *this;
  860. }
  861. bool SubscribePacket::initializeRawOptions(aws_mqtt5_packet_subscribe_view &raw_options) noexcept
  862. {
  863. AWS_ZERO_STRUCT(raw_options);
  864. s_AllocateUnderlyingSubscription(m_subscriptionViewStorage, m_subscriptions, m_allocator);
  865. raw_options.subscription_count = m_subscriptions.size();
  866. raw_options.subscriptions = m_subscriptionViewStorage;
  867. s_AllocateUnderlyingUserProperties(m_userPropertiesStorage, m_userProperties, m_allocator);
  868. raw_options.user_properties = m_userPropertiesStorage;
  869. raw_options.user_property_count = m_userProperties.size();
  870. return true;
  871. }
  872. SubscribePacket::~SubscribePacket()
  873. {
  874. if (m_userPropertiesStorage != nullptr)
  875. {
  876. aws_mem_release(m_allocator, m_userPropertiesStorage);
  877. m_userPropertiesStorage = nullptr;
  878. }
  879. if (m_subscriptionViewStorage != nullptr)
  880. {
  881. aws_mem_release(m_allocator, m_subscriptionViewStorage);
  882. m_subscriptionViewStorage = nullptr;
  883. }
  884. }
  885. SubAckPacket::SubAckPacket(const aws_mqtt5_packet_suback_view &packet, Allocator * /*allocator*/) noexcept
  886. {
  887. setPacketStringOptional(m_reasonString, packet.reason_string);
  888. setUserProperties(m_userProperties, packet.user_properties, packet.user_property_count);
  889. for (size_t i = 0; i < packet.reason_code_count; i++)
  890. {
  891. m_reasonCodes.push_back(*(packet.reason_codes + i));
  892. }
  893. }
  894. const Crt::Optional<Crt::String> &SubAckPacket::getReasonString() const noexcept { return m_reasonString; }
  895. const Crt::Vector<UserProperty> &SubAckPacket::getUserProperties() const noexcept
  896. {
  897. return m_userProperties;
  898. }
  899. const Crt::Vector<SubAckReasonCode> &SubAckPacket::getReasonCodes() const noexcept { return m_reasonCodes; }
  900. UnsubscribePacket::UnsubscribePacket(Allocator *allocator) noexcept
  901. : m_allocator(allocator), m_userPropertiesStorage(nullptr)
  902. {
  903. AWS_ZERO_STRUCT(m_topicFiltersList);
  904. }
  905. UnsubscribePacket &UnsubscribePacket::withTopicFilter(Crt::String topicFilter) noexcept
  906. {
  907. m_topicFilters.push_back(std::move(topicFilter));
  908. return *this;
  909. }
  910. UnsubscribePacket &UnsubscribePacket::withTopicFilters(Crt::Vector<String> topicFilters) noexcept
  911. {
  912. m_topicFilters = std::move(topicFilters);
  913. return *this;
  914. }
  915. UnsubscribePacket &UnsubscribePacket::withUserProperties(
  916. const Vector<UserProperty> &userProperties) noexcept
  917. {
  918. m_userProperties = userProperties;
  919. return *this;
  920. }
  921. UnsubscribePacket &UnsubscribePacket::withUserProperties(Vector<UserProperty> &&userProperties) noexcept
  922. {
  923. m_userProperties = userProperties;
  924. return *this;
  925. }
  926. UnsubscribePacket &UnsubscribePacket::withUserProperty(UserProperty &&property) noexcept
  927. {
  928. m_userProperties.push_back(std::move(property));
  929. return *this;
  930. }
  931. bool UnsubscribePacket::initializeRawOptions(aws_mqtt5_packet_unsubscribe_view &raw_options) noexcept
  932. {
  933. AWS_ZERO_STRUCT(raw_options);
  934. s_AllocateStringVector(m_topicFiltersList, m_topicFilters, m_allocator);
  935. raw_options.topic_filters = static_cast<aws_byte_cursor *>(m_topicFiltersList.data);
  936. raw_options.topic_filter_count = m_topicFilters.size();
  937. s_AllocateUnderlyingUserProperties(m_userPropertiesStorage, m_userProperties, m_allocator);
  938. raw_options.user_properties = m_userPropertiesStorage;
  939. raw_options.user_property_count = m_userProperties.size();
  940. return true;
  941. }
  942. UnsubscribePacket::~UnsubscribePacket()
  943. {
  944. aws_array_list_clean_up(&m_topicFiltersList);
  945. AWS_ZERO_STRUCT(m_topicFiltersList);
  946. if (m_userPropertiesStorage != nullptr)
  947. {
  948. aws_mem_release(m_allocator, m_userPropertiesStorage);
  949. m_userPropertiesStorage = nullptr;
  950. }
  951. }
  952. UnSubAckPacket::UnSubAckPacket(const aws_mqtt5_packet_unsuback_view &packet, Allocator *allocator) noexcept
  953. {
  954. (void)allocator;
  955. setPacketStringOptional(m_reasonString, packet.reason_string);
  956. for (size_t i = 0; i < packet.reason_code_count; i++)
  957. {
  958. m_reasonCodes.push_back(*(packet.reason_codes + i));
  959. }
  960. setUserProperties(m_userProperties, packet.user_properties, packet.user_property_count);
  961. }
  962. const Crt::Optional<Crt::String> &UnSubAckPacket::getReasonString() const noexcept
  963. {
  964. return m_reasonString;
  965. }
  966. const Crt::Vector<UserProperty> &UnSubAckPacket::getUserProperties() const noexcept
  967. {
  968. return m_userProperties;
  969. }
  970. const Crt::Vector<UnSubAckReasonCode> &UnSubAckPacket::getReasonCodes() const noexcept
  971. {
  972. return m_reasonCodes;
  973. }
  974. NegotiatedSettings::NegotiatedSettings(
  975. const aws_mqtt5_negotiated_settings &negotiated_settings,
  976. Allocator *allocator) noexcept
  977. {
  978. (void)allocator;
  979. m_maximumQOS = negotiated_settings.maximum_qos;
  980. m_sessionExpiryIntervalSec = negotiated_settings.session_expiry_interval;
  981. m_receiveMaximumFromServer = negotiated_settings.receive_maximum_from_server;
  982. m_maximumPacketSizeBytes = negotiated_settings.maximum_packet_size_to_server;
  983. m_serverKeepAliveSec = negotiated_settings.server_keep_alive;
  984. m_retainAvailable = negotiated_settings.retain_available;
  985. m_wildcardSubscriptionsAvaliable = negotiated_settings.wildcard_subscriptions_available;
  986. m_subscriptionIdentifiersAvaliable = negotiated_settings.subscription_identifiers_available;
  987. m_sharedSubscriptionsAvaliable = negotiated_settings.shared_subscriptions_available;
  988. m_rejoinedSession = negotiated_settings.rejoined_session;
  989. m_clientId = Crt::String(
  990. (const char *)negotiated_settings.client_id_storage.buffer,
  991. negotiated_settings.client_id_storage.len);
  992. }
  993. Mqtt5::QOS NegotiatedSettings::getMaximumQOS() const noexcept { return m_maximumQOS; }
  994. uint32_t NegotiatedSettings::getSessionExpiryIntervalSec() const noexcept
  995. {
  996. return m_sessionExpiryIntervalSec;
  997. }
  998. uint16_t NegotiatedSettings::getReceiveMaximumFromServer() const noexcept
  999. {
  1000. return m_receiveMaximumFromServer;
  1001. }
  1002. uint32_t NegotiatedSettings::getMaximumPacketSizeBytes() const noexcept { return m_maximumPacketSizeBytes; }
  1003. uint16_t NegotiatedSettings::getServerKeepAlive() const noexcept { return m_serverKeepAliveSec; }
  1004. bool NegotiatedSettings::getRetainAvailable() const noexcept { return m_retainAvailable; }
  1005. bool NegotiatedSettings::getWildcardSubscriptionsAvaliable() const noexcept
  1006. {
  1007. return m_wildcardSubscriptionsAvaliable;
  1008. }
  1009. bool NegotiatedSettings::getSubscriptionIdentifiersAvaliable() const noexcept
  1010. {
  1011. return m_subscriptionIdentifiersAvaliable;
  1012. }
  1013. bool NegotiatedSettings::getSharedSubscriptionsAvaliable() const noexcept
  1014. {
  1015. return m_sharedSubscriptionsAvaliable;
  1016. }
  1017. bool NegotiatedSettings::getRejoinedSession() const noexcept { return m_rejoinedSession; }
  1018. const Crt::String &NegotiatedSettings::getClientId() const noexcept { return m_clientId; }
  1019. PublishResult::PublishResult() : m_ack(nullptr), m_errorCode(0) {}
  1020. PublishResult::PublishResult(std::shared_ptr<PubAckPacket> puback) : m_errorCode(0) { m_ack = puback; }
  1021. PublishResult::PublishResult(int error) : m_ack(nullptr), m_errorCode(error) {}
  1022. PublishResult::~PublishResult() noexcept { m_ack.reset(); }
  1023. } // namespace Mqtt5
  1024. } // namespace Crt
  1025. } // namespace Aws