core_mqtt_serializer.h 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292
  1. /*
  2. * coreMQTT <DEVELOPMENT BRANCH>
  3. * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  4. *
  5. * SPDX-License-Identifier: MIT
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  8. * this software and associated documentation files (the "Software"), to deal in
  9. * the Software without restriction, including without limitation the rights to
  10. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  11. * the Software, and to permit persons to whom the Software is furnished to do so,
  12. * subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in all
  15. * copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  19. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  20. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  21. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23. */
  24. /**
  25. * @file core_mqtt_serializer.h
  26. * @brief User-facing functions for serializing and deserializing MQTT 3.1.1
  27. * packets. This header should be included for building a lighter weight MQTT
  28. * client than the managed CSDK MQTT library API in core_mqtt.h, by using the
  29. * serializer and de-serializer functions exposed in this file's API.
  30. */
  31. #ifndef CORE_MQTT_SERIALIZER_H
  32. #define CORE_MQTT_SERIALIZER_H
  33. #include <stddef.h>
  34. #include <stdint.h>
  35. #include <stdbool.h>
  36. /* *INDENT-OFF* */
  37. #ifdef __cplusplus
  38. extern "C" {
  39. #endif
  40. /* *INDENT-ON */
  41. #include "core_mqtt_config_defaults.h"
  42. /**
  43. * @ingroup mqtt_constants
  44. * @brief The size of MQTT PUBACK, PUBREC, PUBREL, and PUBCOMP packets, per MQTT spec.
  45. */
  46. #define MQTT_PUBLISH_ACK_PACKET_SIZE ( 4UL )
  47. /* Structures defined in this file. */
  48. struct MQTTFixedBuffer;
  49. struct MQTTConnectInfo;
  50. struct MQTTSubscribeInfo;
  51. struct MQTTPublishInfo;
  52. struct MQTTPacketInfo;
  53. /**
  54. * @ingroup mqtt_enum_types
  55. * @brief Return codes from MQTT functions.
  56. */
  57. typedef enum MQTTStatus
  58. {
  59. MQTTSuccess = 0, /**< Function completed successfully. */
  60. MQTTBadParameter, /**< At least one parameter was invalid. */
  61. MQTTNoMemory, /**< A provided buffer was too small. */
  62. MQTTSendFailed, /**< The transport send function failed. */
  63. MQTTRecvFailed, /**< The transport receive function failed. */
  64. MQTTBadResponse, /**< An invalid packet was received from the server. */
  65. MQTTServerRefused, /**< The server refused a CONNECT or SUBSCRIBE. */
  66. MQTTNoDataAvailable, /**< No data available from the transport interface. */
  67. MQTTIllegalState, /**< An illegal state in the state record. */
  68. MQTTStateCollision, /**< A collision with an existing state record entry. */
  69. MQTTKeepAliveTimeout, /**< Timeout while waiting for PINGRESP. */
  70. MQTTNeedMoreBytes, /**< MQTT_ProcessLoop/MQTT_ReceiveLoop has received
  71. incomplete data; it should be called again (probably after
  72. a delay). */
  73. MQTTStatusConnected, /**< MQTT connection is established with the broker. */
  74. MQTTStatusNotConnected, /**< MQTT connection is not established with the broker. */
  75. MQTTStatusDisconnectPending, /**< Transport Interface has failed and MQTT connection needs to be closed. */
  76. MQTTPublishStoreFailed, /**< User provided API to store a copy of outgoing publish for retransmission purposes,
  77. has failed. */
  78. MQTTPublishRetrieveFailed /**< User provided API to retrieve the copy of a publish while reconnecting
  79. with an unclean session has failed. */
  80. } MQTTStatus_t;
  81. /**
  82. * @ingroup mqtt_enum_types
  83. * @brief MQTT Quality of Service values.
  84. */
  85. typedef enum MQTTQoS
  86. {
  87. MQTTQoS0 = 0, /**< Delivery at most once. */
  88. MQTTQoS1 = 1, /**< Delivery at least once. */
  89. MQTTQoS2 = 2 /**< Delivery exactly once. */
  90. } MQTTQoS_t;
  91. /**
  92. * @ingroup mqtt_struct_types
  93. * @brief Buffer passed to MQTT library.
  94. *
  95. * These buffers are not copied and must remain in scope for the duration of the
  96. * MQTT operation.
  97. */
  98. typedef struct MQTTFixedBuffer
  99. {
  100. uint8_t * pBuffer; /**< @brief Pointer to buffer. */
  101. size_t size; /**< @brief Size of buffer. */
  102. } MQTTFixedBuffer_t;
  103. /**
  104. * @ingroup mqtt_struct_types
  105. * @brief MQTT CONNECT packet parameters.
  106. */
  107. typedef struct MQTTConnectInfo
  108. {
  109. /**
  110. * @brief Whether to establish a new, clean session or resume a previous session.
  111. */
  112. bool cleanSession;
  113. /**
  114. * @brief MQTT keep alive period.
  115. */
  116. uint16_t keepAliveSeconds;
  117. /**
  118. * @brief MQTT client identifier. Must be unique per client.
  119. */
  120. const char * pClientIdentifier;
  121. /**
  122. * @brief Length of the client identifier.
  123. */
  124. uint16_t clientIdentifierLength;
  125. /**
  126. * @brief MQTT user name. Set to NULL if not used.
  127. */
  128. const char * pUserName;
  129. /**
  130. * @brief Length of MQTT user name. Set to 0 if not used.
  131. */
  132. uint16_t userNameLength;
  133. /**
  134. * @brief MQTT password. Set to NULL if not used.
  135. */
  136. const char * pPassword;
  137. /**
  138. * @brief Length of MQTT password. Set to 0 if not used.
  139. */
  140. uint16_t passwordLength;
  141. } MQTTConnectInfo_t;
  142. /**
  143. * @ingroup mqtt_struct_types
  144. * @brief MQTT SUBSCRIBE packet parameters.
  145. */
  146. typedef struct MQTTSubscribeInfo
  147. {
  148. /**
  149. * @brief Quality of Service for subscription.
  150. */
  151. MQTTQoS_t qos;
  152. /**
  153. * @brief Topic filter to subscribe to.
  154. */
  155. const char * pTopicFilter;
  156. /**
  157. * @brief Length of subscription topic filter.
  158. */
  159. uint16_t topicFilterLength;
  160. } MQTTSubscribeInfo_t;
  161. /**
  162. * @ingroup mqtt_struct_types
  163. * @brief MQTT PUBLISH packet parameters.
  164. */
  165. typedef struct MQTTPublishInfo
  166. {
  167. /**
  168. * @brief Quality of Service for message.
  169. */
  170. MQTTQoS_t qos;
  171. /**
  172. * @brief Whether this is a retained message.
  173. */
  174. bool retain;
  175. /**
  176. * @brief Whether this is a duplicate publish message.
  177. */
  178. bool dup;
  179. /**
  180. * @brief Topic name on which the message is published.
  181. */
  182. const char * pTopicName;
  183. /**
  184. * @brief Length of topic name.
  185. */
  186. uint16_t topicNameLength;
  187. /**
  188. * @brief Message payload.
  189. */
  190. const void * pPayload;
  191. /**
  192. * @brief Message payload length.
  193. */
  194. size_t payloadLength;
  195. } MQTTPublishInfo_t;
  196. /**
  197. * @ingroup mqtt_struct_types
  198. * @brief MQTT incoming packet parameters.
  199. */
  200. typedef struct MQTTPacketInfo
  201. {
  202. /**
  203. * @brief Type of incoming MQTT packet.
  204. */
  205. uint8_t type;
  206. /**
  207. * @brief Remaining serialized data in the MQTT packet.
  208. */
  209. uint8_t * pRemainingData;
  210. /**
  211. * @brief Length of remaining serialized data.
  212. */
  213. size_t remainingLength;
  214. /**
  215. * @brief The length of the MQTT header including the type and length.
  216. */
  217. size_t headerLength;
  218. } MQTTPacketInfo_t;
  219. /**
  220. * @brief Get the size and Remaining Length of an MQTT CONNECT packet.
  221. *
  222. * This function must be called before #MQTT_SerializeConnect in order to get
  223. * the size of the MQTT CONNECT packet that is generated from #MQTTConnectInfo_t
  224. * and optional #MQTTPublishInfo_t. The size of the #MQTTFixedBuffer_t supplied
  225. * to #MQTT_SerializeConnect must be at least @p pPacketSize. The provided
  226. * @p pConnectInfo and @p pWillInfo are valid for serialization with
  227. * #MQTT_SerializeConnect only if this function returns #MQTTSuccess. The
  228. * remaining length returned in @p pRemainingLength and the packet size returned
  229. * in @p pPacketSize are valid only if this function returns #MQTTSuccess.
  230. *
  231. * @param[in] pConnectInfo MQTT CONNECT packet parameters.
  232. * @param[in] pWillInfo Last Will and Testament. Pass NULL if not used.
  233. * @param[out] pRemainingLength The Remaining Length of the MQTT CONNECT packet.
  234. * @param[out] pPacketSize The total size of the MQTT CONNECT packet.
  235. *
  236. * @return #MQTTBadParameter if the packet would exceed the size allowed by the
  237. * MQTT spec; #MQTTSuccess otherwise.
  238. *
  239. * <b>Example</b>
  240. * @code{c}
  241. *
  242. * // Variables used in this example.
  243. * MQTTStatus_t status;
  244. * MQTTConnectInfo_t connectInfo = { 0 };
  245. * MQTTPublishInfo_t willInfo = { 0 };
  246. * size_t remainingLength = 0, packetSize = 0;
  247. *
  248. * // Initialize the connection info, the details are out of scope for this example.
  249. * initializeConnectInfo( &connectInfo );
  250. *
  251. * // Initialize the optional will info, the details are out of scope for this example.
  252. * initializeWillInfo( &willInfo );
  253. *
  254. * // Get the size requirement for the connect packet.
  255. * status = MQTT_GetConnectPacketSize(
  256. * &connectInfo, &willInfo, &remainingLength, &packetSize
  257. * );
  258. *
  259. * if( status == MQTTSuccess )
  260. * {
  261. * // The application should allocate or use a static #MQTTFixedBuffer_t
  262. * // of size >= packetSize to serialize the connect request.
  263. * }
  264. * @endcode
  265. */
  266. /* @[declare_mqtt_getconnectpacketsize] */
  267. MQTTStatus_t MQTT_GetConnectPacketSize( const MQTTConnectInfo_t * pConnectInfo,
  268. const MQTTPublishInfo_t * pWillInfo,
  269. size_t * pRemainingLength,
  270. size_t * pPacketSize );
  271. /* @[declare_mqtt_getconnectpacketsize] */
  272. /**
  273. * @brief Serialize an MQTT CONNECT packet in the given fixed buffer @p pFixedBuffer.
  274. *
  275. * #MQTT_GetConnectPacketSize should be called with @p pConnectInfo and
  276. * @p pWillInfo before invoking this function to get the size of the required
  277. * #MQTTFixedBuffer_t and @p remainingLength. The @p remainingLength must be
  278. * the same as returned by #MQTT_GetConnectPacketSize. The #MQTTFixedBuffer_t
  279. * must be at least as large as the size returned by #MQTT_GetConnectPacketSize.
  280. *
  281. * @param[in] pConnectInfo MQTT CONNECT packet parameters.
  282. * @param[in] pWillInfo Last Will and Testament. Pass NULL if not used.
  283. * @param[in] remainingLength Remaining Length provided by #MQTT_GetConnectPacketSize.
  284. * @param[out] pFixedBuffer Buffer for packet serialization.
  285. *
  286. * @return #MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet;
  287. * #MQTTBadParameter if invalid parameters are passed;
  288. * #MQTTSuccess otherwise.
  289. *
  290. * <b>Example</b>
  291. * @code{c}
  292. *
  293. * // Variables used in this example.
  294. * MQTTStatus_t status;
  295. * MQTTConnectInfo_t connectInfo = { 0 };
  296. * MQTTPublishInfo_t willInfo = { 0 };
  297. * MQTTFixedBuffer_t fixedBuffer;
  298. * uint8_t buffer[ BUFFER_SIZE ];
  299. * size_t remainingLength = 0, packetSize = 0;
  300. *
  301. * fixedBuffer.pBuffer = buffer;
  302. * fixedBuffer.size = BUFFER_SIZE;
  303. *
  304. * // Assume connectInfo and willInfo are initialized. Get the size requirement for
  305. * // the connect packet.
  306. * status = MQTT_GetConnectPacketSize(
  307. * &connectInfo, &willInfo, &remainingLength, &packetSize
  308. * );
  309. * assert( status == MQTTSuccess );
  310. * assert( packetSize <= BUFFER_SIZE );
  311. *
  312. * // Serialize the connect packet into the fixed buffer.
  313. * status = MQTT_SerializeConnect( &connectInfo, &willInfo, remainingLength, &fixedBuffer );
  314. *
  315. * if( status == MQTTSuccess )
  316. * {
  317. * // The connect packet can now be sent to the broker.
  318. * }
  319. * @endcode
  320. */
  321. /* @[declare_mqtt_serializeconnect] */
  322. MQTTStatus_t MQTT_SerializeConnect( const MQTTConnectInfo_t * pConnectInfo,
  323. const MQTTPublishInfo_t * pWillInfo,
  324. size_t remainingLength,
  325. const MQTTFixedBuffer_t * pFixedBuffer );
  326. /* @[declare_mqtt_serializeconnect] */
  327. /**
  328. * @brief Get packet size and Remaining Length of an MQTT SUBSCRIBE packet.
  329. *
  330. * This function must be called before #MQTT_SerializeSubscribe in order to get
  331. * the size of the MQTT SUBSCRIBE packet that is generated from the list of
  332. * #MQTTSubscribeInfo_t. The size of the #MQTTFixedBuffer_t supplied
  333. * to #MQTT_SerializeSubscribe must be at least @p pPacketSize. The provided
  334. * @p pSubscriptionList is valid for serialization with #MQTT_SerializeSubscribe
  335. * only if this function returns #MQTTSuccess. The remaining length returned in
  336. * @p pRemainingLength and the packet size returned in @p pPacketSize are valid
  337. * only if this function returns #MQTTSuccess.
  338. *
  339. * @param[in] pSubscriptionList List of MQTT subscription info.
  340. * @param[in] subscriptionCount The number of elements in pSubscriptionList.
  341. * @param[out] pRemainingLength The Remaining Length of the MQTT SUBSCRIBE packet.
  342. * @param[out] pPacketSize The total size of the MQTT SUBSCRIBE packet.
  343. *
  344. * @return #MQTTBadParameter if the packet would exceed the size allowed by the
  345. * MQTT spec; #MQTTSuccess otherwise.
  346. *
  347. * <b>Example</b>
  348. * @code{c}
  349. *
  350. * // Variables used in this example.
  351. * MQTTStatus_t status;
  352. * MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
  353. * size_t remainingLength = 0, packetSize = 0;
  354. * // This is assumed to be a list of filters we want to subscribe to.
  355. * const char * filters[ NUMBER_OF_SUBSCRIPTIONS ];
  356. *
  357. * // Set each subscription.
  358. * for( int i = 0; i < NUMBER_OF_SUBSCRIPTIONS; i++ )
  359. * {
  360. * subscriptionList[ i ].qos = MQTTQoS0;
  361. * // Each subscription needs a topic filter.
  362. * subscriptionList[ i ].pTopicFilter = filters[ i ];
  363. * subscriptionList[ i ].topicFilterLength = strlen( filters[ i ] );
  364. * }
  365. *
  366. * // Get the size requirement for the subscribe packet.
  367. * status = MQTT_GetSubscribePacketSize(
  368. * &subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
  369. * );
  370. *
  371. * if( status == MQTTSuccess )
  372. * {
  373. * // The application should allocate or use a static #MQTTFixedBuffer_t
  374. * // of size >= packetSize to serialize the subscribe request.
  375. * }
  376. * @endcode
  377. */
  378. /* @[declare_mqtt_getsubscribepacketsize] */
  379. MQTTStatus_t MQTT_GetSubscribePacketSize( const MQTTSubscribeInfo_t * pSubscriptionList,
  380. size_t subscriptionCount,
  381. size_t * pRemainingLength,
  382. size_t * pPacketSize );
  383. /* @[declare_mqtt_getsubscribepacketsize] */
  384. /**
  385. * @brief Serialize an MQTT SUBSCRIBE packet in the given buffer.
  386. *
  387. * #MQTT_GetSubscribePacketSize should be called with @p pSubscriptionList
  388. * before invoking this function to get the size of the required
  389. * #MQTTFixedBuffer_t and @p remainingLength. The @p remainingLength must be
  390. * the same as returned by #MQTT_GetSubscribePacketSize. The #MQTTFixedBuffer_t
  391. * must be at least as large as the size returned by #MQTT_GetSubscribePacketSize.
  392. *
  393. * @param[in] pSubscriptionList List of MQTT subscription info.
  394. * @param[in] subscriptionCount The number of elements in pSubscriptionList.
  395. * @param[in] packetId packet ID generated by #MQTT_GetPacketId.
  396. * @param[in] remainingLength Remaining Length provided by #MQTT_GetSubscribePacketSize.
  397. * @param[out] pFixedBuffer Buffer for packet serialization.
  398. *
  399. * @return #MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet;
  400. * #MQTTBadParameter if invalid parameters are passed;
  401. * #MQTTSuccess otherwise.
  402. *
  403. * <b>Example</b>
  404. * @code{c}
  405. *
  406. * // Variables used in this example.
  407. * MQTTStatus_t status;
  408. * MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
  409. * MQTTFixedBuffer_t fixedBuffer;
  410. * uint8_t buffer[ BUFFER_SIZE ];
  411. * size_t remainingLength = 0, packetSize = 0;
  412. * uint16_t packetId;
  413. *
  414. * fixedBuffer.pBuffer = buffer;
  415. * fixedBuffer.size = BUFFER_SIZE;
  416. *
  417. * // Function to return a valid, unused packet identifier. The details are out of
  418. * // scope for this example.
  419. * packetId = getNewPacketId();
  420. *
  421. * // Assume subscriptionList has been initialized. Get the subscribe packet size.
  422. * status = MQTT_GetSubscribePacketSize(
  423. * &subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
  424. * );
  425. * assert( status == MQTTSuccess );
  426. * assert( packetSize <= BUFFER_SIZE );
  427. *
  428. * // Serialize the subscribe packet into the fixed buffer.
  429. * status = MQTT_SerializeSubscribe(
  430. * &subscriptionList[ 0 ],
  431. * NUMBER_OF_SUBSCRIPTIONS,
  432. * packetId,
  433. * remainingLength,
  434. * &fixedBuffer
  435. * );
  436. *
  437. * if( status == MQTTSuccess )
  438. * {
  439. * // The subscribe packet can now be sent to the broker.
  440. * }
  441. * @endcode
  442. */
  443. /* @[declare_mqtt_serializesubscribe] */
  444. MQTTStatus_t MQTT_SerializeSubscribe( const MQTTSubscribeInfo_t * pSubscriptionList,
  445. size_t subscriptionCount,
  446. uint16_t packetId,
  447. size_t remainingLength,
  448. const MQTTFixedBuffer_t * pFixedBuffer );
  449. /* @[declare_mqtt_serializesubscribe] */
  450. /**
  451. * @brief Get packet size and Remaining Length of an MQTT UNSUBSCRIBE packet.
  452. *
  453. * This function must be called before #MQTT_SerializeUnsubscribe in order to
  454. * get the size of the MQTT UNSUBSCRIBE packet that is generated from the list
  455. * of #MQTTSubscribeInfo_t. The size of the #MQTTFixedBuffer_t supplied
  456. * to #MQTT_SerializeUnsubscribe must be at least @p pPacketSize. The provided
  457. * @p pSubscriptionList is valid for serialization with #MQTT_SerializeUnsubscribe
  458. * only if this function returns #MQTTSuccess. The remaining length returned in
  459. * @p pRemainingLength and the packet size returned in @p pPacketSize are valid
  460. * only if this function returns #MQTTSuccess.
  461. *
  462. * @param[in] pSubscriptionList List of MQTT subscription info.
  463. * @param[in] subscriptionCount The number of elements in pSubscriptionList.
  464. * @param[out] pRemainingLength The Remaining Length of the MQTT UNSUBSCRIBE packet.
  465. * @param[out] pPacketSize The total size of the MQTT UNSUBSCRIBE packet.
  466. *
  467. * @return #MQTTBadParameter if the packet would exceed the size allowed by the
  468. * MQTT spec; #MQTTSuccess otherwise.
  469. *
  470. * <b>Example</b>
  471. * @code{c}
  472. *
  473. * // Variables used in this example.
  474. * MQTTStatus_t status;
  475. * MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
  476. * size_t remainingLength = 0, packetSize = 0;
  477. *
  478. * // Initialize the subscribe info. The details are out of scope for this example.
  479. * initializeSubscribeInfo( &subscriptionList[ 0 ] );
  480. *
  481. * // Get the size requirement for the unsubscribe packet.
  482. * status = MQTT_GetUnsubscribePacketSize(
  483. * &subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
  484. * );
  485. *
  486. * if( status == MQTTSuccess )
  487. * {
  488. * // The application should allocate or use a static #MQTTFixedBuffer_t
  489. * // of size >= packetSize to serialize the unsubscribe request.
  490. * }
  491. * @endcode
  492. */
  493. /* @[declare_mqtt_getunsubscribepacketsize] */
  494. MQTTStatus_t MQTT_GetUnsubscribePacketSize( const MQTTSubscribeInfo_t * pSubscriptionList,
  495. size_t subscriptionCount,
  496. size_t * pRemainingLength,
  497. size_t * pPacketSize );
  498. /* @[declare_mqtt_getunsubscribepacketsize] */
  499. /**
  500. * @brief Serialize an MQTT UNSUBSCRIBE packet in the given buffer.
  501. *
  502. * #MQTT_GetUnsubscribePacketSize should be called with @p pSubscriptionList
  503. * before invoking this function to get the size of the required
  504. * #MQTTFixedBuffer_t and @p remainingLength. The @p remainingLength must be
  505. * the same as returned by #MQTT_GetUnsubscribePacketSize. The #MQTTFixedBuffer_t
  506. * must be at least as large as the size returned by #MQTT_GetUnsubscribePacketSize.
  507. *
  508. * @param[in] pSubscriptionList List of MQTT subscription info.
  509. * @param[in] subscriptionCount The number of elements in pSubscriptionList.
  510. * @param[in] packetId packet ID generated by #MQTT_GetPacketId.
  511. * @param[in] remainingLength Remaining Length provided by #MQTT_GetUnsubscribePacketSize.
  512. * @param[out] pFixedBuffer Buffer for packet serialization.
  513. *
  514. * @return #MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet;
  515. * #MQTTBadParameter if invalid parameters are passed;
  516. * #MQTTSuccess otherwise.
  517. *
  518. * <b>Example</b>
  519. * @code{c}
  520. *
  521. * // Variables used in this example.
  522. * MQTTStatus_t status;
  523. * MQTTSubscribeInfo_t subscriptionList[ NUMBER_OF_SUBSCRIPTIONS ] = { 0 };
  524. * MQTTFixedBuffer_t fixedBuffer;
  525. * uint8_t buffer[ BUFFER_SIZE ];
  526. * size_t remainingLength = 0, packetSize = 0;
  527. * uint16_t packetId;
  528. *
  529. * fixedBuffer.pBuffer = buffer;
  530. * fixedBuffer.size = BUFFER_SIZE;
  531. *
  532. * // Function to return a valid, unused packet identifier. The details are out of
  533. * // scope for this example.
  534. * packetId = getNewPacketId();
  535. *
  536. * // Assume subscriptionList has been initialized. Get the unsubscribe packet size.
  537. * status = MQTT_GetUnsubscribePacketSize(
  538. * &subscriptionList[ 0 ], NUMBER_OF_SUBSCRIPTIONS, &remainingLength, &packetSize
  539. * );
  540. * assert( status == MQTTSuccess );
  541. * assert( packetSize <= BUFFER_SIZE );
  542. *
  543. * // Serialize the unsubscribe packet into the fixed buffer.
  544. * status = MQTT_SerializeUnsubscribe(
  545. * &subscriptionList[ 0 ],
  546. * NUMBER_OF_SUBSCRIPTIONS,
  547. * packetId,
  548. * remainingLength,
  549. * &fixedBuffer
  550. * );
  551. *
  552. * if( status == MQTTSuccess )
  553. * {
  554. * // The unsubscribe packet can now be sent to the broker.
  555. * }
  556. * @endcode
  557. */
  558. /* @[declare_mqtt_serializeunsubscribe] */
  559. MQTTStatus_t MQTT_SerializeUnsubscribe( const MQTTSubscribeInfo_t * pSubscriptionList,
  560. size_t subscriptionCount,
  561. uint16_t packetId,
  562. size_t remainingLength,
  563. const MQTTFixedBuffer_t * pFixedBuffer );
  564. /* @[declare_mqtt_serializeunsubscribe] */
  565. /**
  566. * @brief Get the packet size and remaining length of an MQTT PUBLISH packet.
  567. *
  568. * This function must be called before #MQTT_SerializePublish in order to get
  569. * the size of the MQTT PUBLISH packet that is generated from #MQTTPublishInfo_t.
  570. * The size of the #MQTTFixedBuffer_t supplied to #MQTT_SerializePublish must be
  571. * at least @p pPacketSize. The provided @p pPublishInfo is valid for
  572. * serialization with #MQTT_SerializePublish only if this function returns
  573. * #MQTTSuccess. The remaining length returned in @p pRemainingLength and the
  574. * packet size returned in @p pPacketSize are valid only if this function
  575. * returns #MQTTSuccess.
  576. *
  577. * @param[in] pPublishInfo MQTT PUBLISH packet parameters.
  578. * @param[out] pRemainingLength The Remaining Length of the MQTT PUBLISH packet.
  579. * @param[out] pPacketSize The total size of the MQTT PUBLISH packet.
  580. *
  581. * @return #MQTTBadParameter if the packet would exceed the size allowed by the
  582. * MQTT spec or if invalid parameters are passed; #MQTTSuccess otherwise.
  583. *
  584. * <b>Example</b>
  585. * @code{c}
  586. *
  587. * // Variables used in this example.
  588. * MQTTStatus_t status;
  589. * MQTTPublishInfo_t publishInfo = { 0 };
  590. * size_t remainingLength = 0, packetSize = 0;
  591. *
  592. * // Initialize the publish info.
  593. * publishInfo.qos = MQTTQoS0;
  594. * publishInfo.pTopicName = "/some/topic/name";
  595. * publishInfo.topicNameLength = strlen( publishInfo.pTopicName );
  596. * publishInfo.pPayload = "Hello World!";
  597. * publishInfo.payloadLength = strlen( "Hello World!" );
  598. *
  599. * // Get the size requirement for the publish packet.
  600. * status = MQTT_GetPublishPacketSize(
  601. * &publishInfo, &remainingLength, &packetSize
  602. * );
  603. *
  604. * if( status == MQTTSuccess )
  605. * {
  606. * // The application should allocate or use a static #MQTTFixedBuffer_t
  607. * // of size >= packetSize to serialize the publish.
  608. * }
  609. * @endcode
  610. */
  611. /* @[declare_mqtt_getpublishpacketsize] */
  612. MQTTStatus_t MQTT_GetPublishPacketSize( const MQTTPublishInfo_t * pPublishInfo,
  613. size_t * pRemainingLength,
  614. size_t * pPacketSize );
  615. /* @[declare_mqtt_getpublishpacketsize] */
  616. /**
  617. * @brief Serialize an MQTT PUBLISH packet in the given buffer.
  618. *
  619. * This function will serialize complete MQTT PUBLISH packet into
  620. * the given buffer. If the PUBLISH payload can be sent separately,
  621. * consider using #MQTT_SerializePublishHeader, which will serialize
  622. * only the PUBLISH header into the buffer.
  623. *
  624. * #MQTT_GetPublishPacketSize should be called with @p pPublishInfo before
  625. * invoking this function to get the size of the required #MQTTFixedBuffer_t and
  626. * @p remainingLength. The @p remainingLength must be the same as returned by
  627. * #MQTT_GetPublishPacketSize. The #MQTTFixedBuffer_t must be at least as large
  628. * as the size returned by #MQTT_GetPublishPacketSize.
  629. *
  630. * @param[in] pPublishInfo MQTT PUBLISH packet parameters.
  631. * @param[in] packetId packet ID generated by #MQTT_GetPacketId.
  632. * @param[in] remainingLength Remaining Length provided by #MQTT_GetPublishPacketSize.
  633. * @param[out] pFixedBuffer Buffer for packet serialization.
  634. *
  635. * @return #MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet;
  636. * #MQTTBadParameter if invalid parameters are passed;
  637. * #MQTTSuccess otherwise.
  638. *
  639. * <b>Example</b>
  640. * @code{c}
  641. *
  642. * // Variables used in this example.
  643. * MQTTStatus_t status;
  644. * MQTTPublishInfo_t publishInfo = { 0 };
  645. * MQTTFixedBuffer_t fixedBuffer;
  646. * uint8_t buffer[ BUFFER_SIZE ];
  647. * size_t remainingLength = 0, packetSize = 0;
  648. * uint16_t packetId;
  649. *
  650. * fixedBuffer.pBuffer = buffer;
  651. * fixedBuffer.size = BUFFER_SIZE;
  652. *
  653. * // A packet identifier is unused for QoS 0 publishes. Otherwise, a valid, unused packet
  654. * // identifier must be used.
  655. * packetId = 0;
  656. *
  657. * // Assume publishInfo has been initialized. Get publish packet size.
  658. * status = MQTT_GetPublishPacketSize(
  659. * &publishInfo, &remainingLength, &packetSize
  660. * );
  661. * assert( status == MQTTSuccess );
  662. * assert( packetSize <= BUFFER_SIZE );
  663. *
  664. * // Serialize the publish packet into the fixed buffer.
  665. * status = MQTT_SerializePublish(
  666. * &publishInfo,
  667. * packetId,
  668. * remainingLength,
  669. * &fixedBuffer
  670. * );
  671. *
  672. * if( status == MQTTSuccess )
  673. * {
  674. * // The publish packet can now be sent to the broker.
  675. * }
  676. * @endcode
  677. */
  678. /* @[declare_mqtt_serializepublish] */
  679. MQTTStatus_t MQTT_SerializePublish( const MQTTPublishInfo_t * pPublishInfo,
  680. uint16_t packetId,
  681. size_t remainingLength,
  682. const MQTTFixedBuffer_t * pFixedBuffer );
  683. /* @[declare_mqtt_serializepublish] */
  684. /**
  685. * @brief Serialize an MQTT PUBLISH packet header without the topic string in the
  686. * given buffer. This function will add the topic string length to the provided
  687. * buffer. This helps reduce an unnecessary copy of the topic string into the
  688. * buffer.
  689. *
  690. * @param[in] pPublishInfo MQTT PUBLISH packet parameters.
  691. * @param[in] remainingLength Remaining Length provided by #MQTT_GetPublishPacketSize.
  692. * @param[out] pBuffer Buffer for packet serialization.
  693. * @param[out] headerSize Size of the serialized MQTT PUBLISH header.
  694. *
  695. * @return #MQTTSuccess if the serialization is successful. Otherwise, #MQTTBadParameter.
  696. */
  697. MQTTStatus_t MQTT_SerializePublishHeaderWithoutTopic( const MQTTPublishInfo_t * pPublishInfo,
  698. size_t remainingLength,
  699. uint8_t * pBuffer,
  700. size_t * headerSize );
  701. /**
  702. * @brief Serialize an MQTT PUBLISH packet header in the given buffer.
  703. *
  704. * This function serializes PUBLISH header in to the given buffer. The payload
  705. * for PUBLISH will not be copied over to the buffer. This will help reduce
  706. * the memory needed for the buffer and avoid an unwanted copy operation of the
  707. * PUBLISH payload into the buffer. If the payload also would need to be part of
  708. * the serialized buffer, consider using #MQTT_SerializePublish.
  709. *
  710. * #MQTT_GetPublishPacketSize should be called with @p pPublishInfo before
  711. * invoking this function to get the size of the required #MQTTFixedBuffer_t and
  712. * @p remainingLength. The @p remainingLength must be the same as returned by
  713. * #MQTT_GetPublishPacketSize. The #MQTTFixedBuffer_t must be at least as large
  714. * as the size returned by #MQTT_GetPublishPacketSize.
  715. *
  716. * @param[in] pPublishInfo MQTT PUBLISH packet parameters.
  717. * @param[in] packetId packet ID generated by #MQTT_GetPacketId.
  718. * @param[in] remainingLength Remaining Length provided by #MQTT_GetPublishPacketSize.
  719. * @param[out] pFixedBuffer Buffer for packet serialization.
  720. * @param[out] pHeaderSize Size of the serialized MQTT PUBLISH header.
  721. *
  722. * @return #MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet;
  723. * #MQTTBadParameter if invalid parameters are passed;
  724. * #MQTTSuccess otherwise.
  725. *
  726. * <b>Example</b>
  727. * @code{c}
  728. *
  729. * // Variables used in this example.
  730. * MQTTStatus_t status;
  731. * MQTTPublishInfo_t publishInfo = { 0 };
  732. * MQTTFixedBuffer_t fixedBuffer;
  733. * uint8_t buffer[ BUFFER_SIZE ];
  734. * size_t remainingLength = 0, packetSize = 0, headerSize = 0;
  735. * uint16_t packetId;
  736. * int32_t bytesSent;
  737. *
  738. * fixedBuffer.pBuffer = buffer;
  739. * fixedBuffer.size = BUFFER_SIZE;
  740. *
  741. * // A packet identifier is unused for QoS 0 publishes. Otherwise, a valid, unused packet
  742. * // identifier must be used.
  743. * packetId = 0;
  744. *
  745. * // Assume publishInfo has been initialized. Get the publish packet size.
  746. * status = MQTT_GetPublishPacketSize(
  747. * &publishInfo, &remainingLength, &packetSize
  748. * );
  749. * assert( status == MQTTSuccess );
  750. * // The payload will not be serialized, so the the fixed buffer does not need to hold it.
  751. * assert( ( packetSize - publishInfo.payloadLength ) <= BUFFER_SIZE );
  752. *
  753. * // Serialize the publish packet header into the fixed buffer.
  754. * status = MQTT_SerializePublishHeader(
  755. * &publishInfo,
  756. * packetId,
  757. * remainingLength,
  758. * &fixedBuffer,
  759. * &headerSize
  760. * );
  761. *
  762. * if( status == MQTTSuccess )
  763. * {
  764. * // The publish header and payload can now be sent to the broker.
  765. * // mqttSocket here is a socket descriptor created and connected to the MQTT
  766. * // broker outside of this function.
  767. * bytesSent = send( mqttSocket, ( void * ) fixedBuffer.pBuffer, headerSize, 0 );
  768. * assert( bytesSent == headerSize );
  769. * bytesSent = send( mqttSocket, publishInfo.pPayload, publishInfo.payloadLength, 0 );
  770. * assert( bytesSent == publishInfo.payloadLength );
  771. * }
  772. * @endcode
  773. */
  774. /* @[declare_mqtt_serializepublishheader] */
  775. MQTTStatus_t MQTT_SerializePublishHeader( const MQTTPublishInfo_t * pPublishInfo,
  776. uint16_t packetId,
  777. size_t remainingLength,
  778. const MQTTFixedBuffer_t * pFixedBuffer,
  779. size_t * pHeaderSize );
  780. /* @[declare_mqtt_serializepublishheader] */
  781. /**
  782. * @brief Serialize an MQTT PUBACK, PUBREC, PUBREL, or PUBCOMP into the given
  783. * buffer.
  784. *
  785. * @param[out] pFixedBuffer Buffer for packet serialization.
  786. * @param[in] packetType Byte of the corresponding packet fixed header per the
  787. * MQTT spec.
  788. * @param[in] packetId Packet ID of the publish.
  789. *
  790. * @return #MQTTBadParameter, #MQTTNoMemory, or #MQTTSuccess.
  791. *
  792. * <b>Example</b>
  793. * @code{c}
  794. *
  795. * // Variables used in this example.
  796. * MQTTStatus_t status;
  797. * MQTTFixedBuffer_t fixedBuffer;
  798. * uint8_t buffer[ BUFFER_SIZE ];
  799. * uint16_t packetId;
  800. * uint8_t packetType;
  801. *
  802. * fixedBuffer.pBuffer = buffer;
  803. * fixedBuffer.size = BUFFER_SIZE;
  804. * // The fixed buffer must be large enough to hold 4 bytes.
  805. * assert( BUFFER_SIZE >= MQTT_PUBLISH_ACK_PACKET_SIZE );
  806. *
  807. * // The packet ID must be the same as the original publish packet.
  808. * packetId = publishPacketId;
  809. *
  810. * // The byte representing a packet of type ACK. This function accepts PUBACK, PUBREC, PUBREL, or PUBCOMP.
  811. * packetType = MQTT_PACKET_TYPE_PUBACK;
  812. *
  813. * // Serialize the publish acknowledgment into the fixed buffer.
  814. * status = MQTT_SerializeAck( &fixedBuffer, packetType, packetId );
  815. *
  816. * if( status == MQTTSuccess )
  817. * {
  818. * // The publish acknowledgment can now be sent to the broker.
  819. * }
  820. * @endcode
  821. */
  822. /* @[declare_mqtt_serializeack] */
  823. MQTTStatus_t MQTT_SerializeAck( const MQTTFixedBuffer_t * pFixedBuffer,
  824. uint8_t packetType,
  825. uint16_t packetId );
  826. /* @[declare_mqtt_serializeack] */
  827. /**
  828. * @brief Get the size of an MQTT DISCONNECT packet.
  829. *
  830. * @param[out] pPacketSize The size of the MQTT DISCONNECT packet.
  831. *
  832. * @return #MQTTSuccess, or #MQTTBadParameter if @p pPacketSize is NULL.
  833. *
  834. * <b>Example</b>
  835. * @code{c}
  836. *
  837. * // Variables used in this example.
  838. * MQTTStatus_t status;
  839. * size_t packetSize = 0;
  840. *
  841. * // Get the size requirement for the disconnect packet.
  842. * status = MQTT_GetDisconnectPacketSize( &packetSize );
  843. * assert( status == MQTTSuccess );
  844. * assert( packetSize == 2 );
  845. *
  846. * // The application should allocate or use a static #MQTTFixedBuffer_t of
  847. * // size >= 2 to serialize the disconnect packet.
  848. *
  849. * @endcode
  850. */
  851. /* @[declare_mqtt_getdisconnectpacketsize] */
  852. MQTTStatus_t MQTT_GetDisconnectPacketSize( size_t * pPacketSize );
  853. /* @[declare_mqtt_getdisconnectpacketsize] */
  854. /**
  855. * @brief Serialize an MQTT DISCONNECT packet into the given buffer.
  856. *
  857. * The input #MQTTFixedBuffer_t.size must be at least as large as the size
  858. * returned by #MQTT_GetDisconnectPacketSize.
  859. *
  860. * @param[out] pFixedBuffer Buffer for packet serialization.
  861. *
  862. * @return #MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet;
  863. * #MQTTBadParameter if invalid parameters are passed;
  864. * #MQTTSuccess otherwise.
  865. *
  866. * <b>Example</b>
  867. * @code{c}
  868. *
  869. * // Variables used in this example.
  870. * MQTTStatus_t status;
  871. * MQTTFixedBuffer_t fixedBuffer;
  872. * uint8_t buffer[ BUFFER_SIZE ];
  873. *
  874. * fixedBuffer.pBuffer = buffer;
  875. * fixedBuffer.size = BUFFER_SIZE;
  876. *
  877. * // Get the disconnect packet size.
  878. * status = MQTT_GetDisconnectPacketSize( &packetSize );
  879. * assert( status == MQTTSuccess );
  880. * assert( packetSize <= BUFFER_SIZE );
  881. *
  882. * // Serialize the disconnect into the fixed buffer.
  883. * status = MQTT_SerializeDisconnect( &fixedBuffer );
  884. *
  885. * if( status == MQTTSuccess )
  886. * {
  887. * // The disconnect packet can now be sent to the broker.
  888. * }
  889. * @endcode
  890. */
  891. /* @[declare_mqtt_serializedisconnect] */
  892. MQTTStatus_t MQTT_SerializeDisconnect( const MQTTFixedBuffer_t * pFixedBuffer );
  893. /* @[declare_mqtt_serializedisconnect] */
  894. /**
  895. * @brief Get the size of an MQTT PINGREQ packet.
  896. *
  897. * @param[out] pPacketSize The size of the MQTT PINGREQ packet.
  898. *
  899. * @return #MQTTSuccess or #MQTTBadParameter if pPacketSize is NULL.
  900. *
  901. * <b>Example</b>
  902. * @code{c}
  903. *
  904. * // Variables used in this example.
  905. * MQTTStatus_t status;
  906. * size_t packetSize = 0;
  907. *
  908. * // Get the size requirement for the ping request packet.
  909. * status = MQTT_GetPingreqPacketSize( &packetSize );
  910. * assert( status == MQTTSuccess );
  911. * assert( packetSize == 2 );
  912. *
  913. * // The application should allocate or use a static #MQTTFixedBuffer_t of
  914. * // size >= 2 to serialize the ping request.
  915. *
  916. * @endcode
  917. */
  918. /* @[declare_mqtt_getpingreqpacketsize] */
  919. MQTTStatus_t MQTT_GetPingreqPacketSize( size_t * pPacketSize );
  920. /* @[declare_mqtt_getpingreqpacketsize] */
  921. /**
  922. * @brief Serialize an MQTT PINGREQ packet into the given buffer.
  923. *
  924. * The input #MQTTFixedBuffer_t.size must be at least as large as the size
  925. * returned by #MQTT_GetPingreqPacketSize.
  926. *
  927. * @param[out] pFixedBuffer Buffer for packet serialization.
  928. *
  929. * @return #MQTTNoMemory if pFixedBuffer is too small to hold the MQTT packet;
  930. * #MQTTBadParameter if invalid parameters are passed;
  931. * #MQTTSuccess otherwise.
  932. *
  933. * <b>Example</b>
  934. * @code{c}
  935. *
  936. * // Variables used in this example.
  937. * MQTTStatus_t status;
  938. * MQTTFixedBuffer_t fixedBuffer;
  939. * uint8_t buffer[ BUFFER_SIZE ];
  940. *
  941. * fixedBuffer.pBuffer = buffer;
  942. * fixedBuffer.size = BUFFER_SIZE;
  943. *
  944. * // Get the ping request packet size.
  945. * status = MQTT_GetPingreqPacketSize( &packetSize );
  946. * assert( status == MQTTSuccess );
  947. * assert( packetSize <= BUFFER_SIZE );
  948. *
  949. * // Serialize the ping request into the fixed buffer.
  950. * status = MQTT_SerializePingreq( &fixedBuffer );
  951. *
  952. * if( status == MQTTSuccess )
  953. * {
  954. * // The ping request can now be sent to the broker.
  955. * }
  956. * @endcode
  957. */
  958. /* @[declare_mqtt_serializepingreq] */
  959. MQTTStatus_t MQTT_SerializePingreq( const MQTTFixedBuffer_t * pFixedBuffer );
  960. /* @[declare_mqtt_serializepingreq] */
  961. /**
  962. * @brief Deserialize an MQTT PUBLISH packet.
  963. *
  964. * @param[in] pIncomingPacket #MQTTPacketInfo_t containing the buffer.
  965. * @param[out] pPacketId The packet ID obtained from the buffer.
  966. * @param[out] pPublishInfo Struct containing information about the publish.
  967. *
  968. * @return #MQTTBadParameter, #MQTTBadResponse, or #MQTTSuccess.
  969. *
  970. * <b>Example</b>
  971. * @code{c}
  972. *
  973. * // TransportRecv_t function for reading from the network.
  974. * int32_t socket_recv(
  975. * NetworkContext_t * pNetworkContext,
  976. * void * pBuffer,
  977. * size_t bytesToRecv
  978. * );
  979. * // Some context to be used with the above transport receive function.
  980. * NetworkContext_t networkContext;
  981. *
  982. * // Other variables used in this example.
  983. * MQTTStatus_t status;
  984. * MQTTPacketInfo_t incomingPacket;
  985. * MQTTPublishInfo_t publishInfo = { 0 };
  986. * uint16_t packetId;
  987. *
  988. * int32_t bytesRecvd;
  989. * // A buffer to hold remaining data of the incoming packet.
  990. * uint8_t buffer[ BUFFER_SIZE ];
  991. *
  992. * // Populate all fields of the incoming packet.
  993. * status = MQTT_GetIncomingPacketTypeAndLength(
  994. * socket_recv,
  995. * &networkContext,
  996. * &incomingPacket
  997. * );
  998. * assert( status == MQTTSuccess );
  999. * assert( incomingPacket.remainingLength <= BUFFER_SIZE );
  1000. * bytesRecvd = socket_recv(
  1001. * &networkContext,
  1002. * ( void * ) buffer,
  1003. * incomingPacket.remainingLength
  1004. * );
  1005. * incomingPacket.pRemainingData = buffer;
  1006. *
  1007. * // Deserialize the publish information if the incoming packet is a publish.
  1008. * if( ( incomingPacket.type & 0xF0 ) == MQTT_PACKET_TYPE_PUBLISH )
  1009. * {
  1010. * status = MQTT_DeserializePublish( &incomingPacket, &packetId, &publishInfo );
  1011. * if( status == MQTTSuccess )
  1012. * {
  1013. * // The deserialized publish information can now be used from `publishInfo`.
  1014. * }
  1015. * }
  1016. * @endcode
  1017. */
  1018. /* @[declare_mqtt_deserializepublish] */
  1019. MQTTStatus_t MQTT_DeserializePublish( const MQTTPacketInfo_t * pIncomingPacket,
  1020. uint16_t * pPacketId,
  1021. MQTTPublishInfo_t * pPublishInfo );
  1022. /* @[declare_mqtt_deserializepublish] */
  1023. /**
  1024. * @brief Deserialize an MQTT CONNACK, SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL,
  1025. * PUBCOMP, or PINGRESP.
  1026. *
  1027. * @param[in] pIncomingPacket #MQTTPacketInfo_t containing the buffer.
  1028. * @param[out] pPacketId The packet ID of obtained from the buffer. Not used
  1029. * in CONNACK or PINGRESP.
  1030. * @param[out] pSessionPresent Boolean flag from a CONNACK indicating present session.
  1031. *
  1032. * @return #MQTTBadParameter, #MQTTBadResponse, #MQTTServerRefused, or #MQTTSuccess.
  1033. *
  1034. * <b>Example</b>
  1035. * @code{c}
  1036. *
  1037. * // Variables used in this example.
  1038. * MQTTStatus_t status;
  1039. * MQTTPacketInfo_t incomingPacket;
  1040. * // Used for SUBACK, UNSUBACK, PUBACK, PUBREC, PUBREL, and PUBCOMP.
  1041. * uint16_t packetId;
  1042. * // Used for CONNACK.
  1043. * bool sessionPresent;
  1044. *
  1045. * // Receive an incoming packet and populate all fields. The details are out of scope
  1046. * // for this example.
  1047. * receiveIncomingPacket( &incomingPacket );
  1048. *
  1049. * // Deserialize ack information if the incoming packet is not a publish.
  1050. * if( ( incomingPacket.type & 0xF0 ) != MQTT_PACKET_TYPE_PUBLISH )
  1051. * {
  1052. * status = MQTT_DeserializeAck( &incomingPacket, &packetId, &sessionPresent );
  1053. * if( status == MQTTSuccess )
  1054. * {
  1055. * // The packet ID or session present flag information is available. For
  1056. * // ping response packets, the only information is the status code.
  1057. * }
  1058. * }
  1059. * @endcode
  1060. */
  1061. /* @[declare_mqtt_deserializeack] */
  1062. MQTTStatus_t MQTT_DeserializeAck( const MQTTPacketInfo_t * pIncomingPacket,
  1063. uint16_t * pPacketId,
  1064. bool * pSessionPresent );
  1065. /* @[declare_mqtt_deserializeack] */
  1066. /**
  1067. * @brief Extract the MQTT packet type and length from incoming packet.
  1068. *
  1069. * This function must be called for every incoming packet to retrieve the
  1070. * #MQTTPacketInfo_t.type and #MQTTPacketInfo_t.remainingLength. A
  1071. * #MQTTPacketInfo_t is not valid until this routine has been invoked.
  1072. *
  1073. * @param[in] readFunc Transport layer read function pointer.
  1074. * @param[in] pNetworkContext The network context pointer provided by the application.
  1075. * @param[out] pIncomingPacket Pointer to MQTTPacketInfo_t structure. This is
  1076. * where type, remaining length and packet identifier are stored.
  1077. *
  1078. * @return #MQTTSuccess on successful extraction of type and length,
  1079. * #MQTTBadParameter if @p pIncomingPacket is invalid,
  1080. * #MQTTRecvFailed on transport receive failure,
  1081. * #MQTTBadResponse if an invalid packet is read, and
  1082. * #MQTTNoDataAvailable if there is nothing to read.
  1083. *
  1084. * <b>Example</b>
  1085. * @code{c}
  1086. *
  1087. * // TransportRecv_t function for reading from the network.
  1088. * int32_t socket_recv(
  1089. * NetworkContext_t * pNetworkContext,
  1090. * void * pBuffer,
  1091. * size_t bytesToRecv
  1092. * );
  1093. * // Some context to be used with above transport receive function.
  1094. * NetworkContext_t networkContext;
  1095. *
  1096. * // Struct to hold the incoming packet information.
  1097. * MQTTPacketInfo_t incomingPacket;
  1098. * MQTTStatus_t status = MQTTSuccess;
  1099. * int32_t bytesRecvd;
  1100. * // Buffer to hold the remaining data of the incoming packet.
  1101. * uint8_t buffer[ BUFFER_SIZE ];
  1102. *
  1103. * // Loop until data is available to be received.
  1104. * do{
  1105. * status = MQTT_GetIncomingPacketTypeAndLength(
  1106. * socket_recv,
  1107. * &networkContext,
  1108. * &incomingPacket
  1109. * );
  1110. * } while( status == MQTTNoDataAvailable );
  1111. *
  1112. * assert( status == MQTTSuccess );
  1113. *
  1114. * // Receive the rest of the incoming packet.
  1115. * assert( incomingPacket.remainingLength <= BUFFER_SIZE );
  1116. * bytesRecvd = socket_recv(
  1117. * &networkContext,
  1118. * ( void * ) buffer,
  1119. * incomingPacket.remainingLength
  1120. * );
  1121. *
  1122. * // Set the remaining data field.
  1123. * incomingPacket.pRemainingData = buffer;
  1124. * @endcode
  1125. */
  1126. /* @[declare_mqtt_getincomingpackettypeandlength] */
  1127. MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength( TransportRecv_t readFunc,
  1128. NetworkContext_t * pNetworkContext,
  1129. MQTTPacketInfo_t * pIncomingPacket );
  1130. /* @[declare_mqtt_getincomingpackettypeandlength] */
  1131. /**
  1132. * @brief Extract the MQTT packet type and length from incoming packet.
  1133. *
  1134. * This function must be called for every incoming packet to retrieve the
  1135. * #MQTTPacketInfo_t.type and #MQTTPacketInfo_t.remainingLength. A
  1136. * #MQTTPacketInfo_t is not valid until this routine has been invoked.
  1137. *
  1138. * @param[in] pBuffer The buffer holding the raw data to be processed
  1139. * @param[in] pIndex Pointer to the index within the buffer to marking the end
  1140. * of raw data available.
  1141. * @param[out] pIncomingPacket Structure used to hold the fields of the
  1142. * incoming packet.
  1143. *
  1144. * @return #MQTTSuccess on successful extraction of type and length,
  1145. * #MQTTBadParameter if @p pIncomingPacket is invalid,
  1146. * #MQTTBadResponse if an invalid packet is read, and
  1147. * #MQTTNoDataAvailable if there is nothing to read.
  1148. */
  1149. /* @[declare_mqtt_processincomingpackettypeandlength] */
  1150. MQTTStatus_t MQTT_ProcessIncomingPacketTypeAndLength( const uint8_t * pBuffer,
  1151. const size_t * pIndex,
  1152. MQTTPacketInfo_t * pIncomingPacket );
  1153. /* @[declare_mqtt_processincomingpackettypeandlength] */
  1154. /**
  1155. * @brief Update the duplicate publish flag within the given header of the publish packet.
  1156. *
  1157. * @param[in] pHeader The buffer holding the header content
  1158. * @param[in] set If true then the flag will be set else cleared
  1159. *
  1160. * @return #MQTTSuccess on successful setting of the duplicate flag,
  1161. * #MQTTBadParameter for invalid parameters
  1162. */
  1163. /* @[declare_mqtt_updateduplicatepublishflag] */
  1164. MQTTStatus_t MQTT_UpdateDuplicatePublishFlag( uint8_t * pHeader , bool set);
  1165. /* @[declare_mqtt_updateduplicatepublishflag] */
  1166. /**
  1167. * @fn uint8_t * MQTT_SerializeConnectFixedHeader( uint8_t * pIndex, const MQTTConnectInfo_t * pConnectInfo, const MQTTPublishInfo_t * pWillInfo, size_t remainingLength );
  1168. * @brief Serialize the fixed part of the connect packet header.
  1169. *
  1170. * @param[out] pIndex Pointer to the buffer where the header is to
  1171. * be serialized.
  1172. * @param[in] pConnectInfo The connect information.
  1173. * @param[in] pWillInfo The last will and testament information.
  1174. * @param[in] remainingLength The remaining length of the packet to be
  1175. * serialized.
  1176. *
  1177. * @return A pointer to the end of the encoded string.
  1178. */
  1179. /**
  1180. * @cond DOXYGEN_IGNORE
  1181. * Doxygen should ignore this definition, this function is private.
  1182. */
  1183. uint8_t * MQTT_SerializeConnectFixedHeader( uint8_t * pIndex,
  1184. const MQTTConnectInfo_t * pConnectInfo,
  1185. const MQTTPublishInfo_t * pWillInfo,
  1186. size_t remainingLength );
  1187. /** @endcond */
  1188. /**
  1189. * @fn uint8_t * MQTT_SerializeSubscribeHeader( size_t remainingLength, uint8_t * pIndex, uint16_t packetId );
  1190. * @brief Serialize the fixed part of the subscribe packet header.
  1191. *
  1192. * @param[in] remainingLength The remaining length of the packet to be
  1193. * serialized.
  1194. * @param[in] pIndex Pointer to the buffer where the header is to
  1195. * be serialized.
  1196. * @param[in] packetId The packet ID to be serialized.
  1197. *
  1198. * @return A pointer to the end of the encoded string.
  1199. */
  1200. /**
  1201. * @cond DOXYGEN_IGNORE
  1202. * Doxygen should ignore this definition, this function is private.
  1203. */
  1204. uint8_t * MQTT_SerializeSubscribeHeader( size_t remainingLength,
  1205. uint8_t * pIndex,
  1206. uint16_t packetId );
  1207. /** @endcond */
  1208. /**
  1209. * @fn uint8_t * MQTT_SerializeUnsubscribeHeader( size_t remainingLength, uint8_t * pIndex, uint16_t packetId );
  1210. * @brief Serialize the fixed part of the unsubscribe packet header.
  1211. *
  1212. * @param[in] remainingLength The remaining length of the packet to be
  1213. * serialized.
  1214. * @param[in] pIndex Pointer to the buffer where the header is to
  1215. * be serialized.
  1216. * @param[in] packetId The packet ID to be serialized.
  1217. *
  1218. * @return A pointer to the end of the encoded string.
  1219. */
  1220. /**
  1221. * @cond DOXYGEN_IGNORE
  1222. * Doxygen should ignore this definition, this function is private.
  1223. */
  1224. uint8_t * MQTT_SerializeUnsubscribeHeader( size_t remainingLength,
  1225. uint8_t * pIndex,
  1226. uint16_t packetId );
  1227. /** @endcond */
  1228. /* *INDENT-OFF* */
  1229. #ifdef __cplusplus
  1230. }
  1231. #endif
  1232. /* *INDENT-ON* */
  1233. #endif /* ifndef CORE_MQTT_SERIALIZER_H */