core_mqtt_serializer.h 48 KB

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