core_mqtt_state.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  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_state.h
  26. * @brief Function to keep state of MQTT PUBLISH packet deliveries.
  27. */
  28. #ifndef CORE_MQTT_STATE_H
  29. #define CORE_MQTT_STATE_H
  30. /* *INDENT-OFF* */
  31. #ifdef __cplusplus
  32. extern "C" {
  33. #endif
  34. /* *INDENT-ON* */
  35. #include "core_mqtt.h"
  36. /**
  37. * @ingroup mqtt_constants
  38. * @brief Initializer value for an #MQTTStateCursor_t, indicating a search
  39. * should start at the beginning of a state record array
  40. */
  41. #define MQTT_STATE_CURSOR_INITIALIZER ( ( size_t ) 0 )
  42. /**
  43. * @ingroup mqtt_basic_types
  44. * @brief Cursor for iterating through state records.
  45. */
  46. typedef size_t MQTTStateCursor_t;
  47. /**
  48. * @cond DOXYGEN_IGNORE
  49. * Doxygen should ignore this section, this enum is private.
  50. *
  51. * @brief Value indicating either send or receive.
  52. */
  53. typedef enum MQTTStateOperation
  54. {
  55. MQTT_SEND,
  56. MQTT_RECEIVE
  57. } MQTTStateOperation_t;
  58. /** @endcond */
  59. /**
  60. * @fn MQTTStatus_t MQTT_ReserveState( const MQTTContext_t * pMqttContext, uint16_t packetId, MQTTQoS_t qos );
  61. * @brief Reserve an entry for an outgoing QoS 1 or Qos 2 publish.
  62. *
  63. * @param[in] pMqttContext Initialized MQTT context.
  64. * @param[in] packetId The ID of the publish packet.
  65. * @param[in] qos 1 or 2.
  66. *
  67. * @return MQTTSuccess, MQTTNoMemory, or MQTTStateCollision.
  68. */
  69. /**
  70. * @cond DOXYGEN_IGNORE
  71. * Doxygen should ignore this definition, this function is private.
  72. */
  73. MQTTStatus_t MQTT_ReserveState( const MQTTContext_t * pMqttContext,
  74. uint16_t packetId,
  75. MQTTQoS_t qos );
  76. /** @endcond */
  77. /**
  78. * @fn MQTTPublishState_t MQTT_CalculateStatePublish( MQTTStateOperation_t opType, MQTTQoS_t qos )
  79. * @brief Calculate the new state for a publish from its qos and operation type.
  80. *
  81. * @param[in] opType Send or Receive.
  82. * @param[in] qos 0, 1, or 2.
  83. *
  84. * @return The calculated state.
  85. */
  86. /**
  87. * @cond DOXYGEN_IGNORE
  88. * Doxygen should ignore this definition, this function is private.
  89. */
  90. MQTTPublishState_t MQTT_CalculateStatePublish( MQTTStateOperation_t opType,
  91. MQTTQoS_t qos );
  92. /** @endcond */
  93. /**
  94. * @fn MQTTStatus_t MQTT_UpdateStatePublish( const MQTTContext_t * pMqttContext, uint16_t packetId, MQTTStateOperation_t opType, MQTTQoS_t qos, MQTTPublishState_t * pNewState );
  95. * @brief Update the state record for a PUBLISH packet.
  96. *
  97. * @param[in] pMqttContext Initialized MQTT context.
  98. * @param[in] packetId ID of the PUBLISH packet.
  99. * @param[in] opType Send or Receive.
  100. * @param[in] qos 0, 1, or 2.
  101. * @param[out] pNewState Updated state of the publish.
  102. *
  103. * @return #MQTTBadParameter, #MQTTIllegalState, #MQTTStateCollision or
  104. * #MQTTSuccess.
  105. */
  106. /**
  107. * @cond DOXYGEN_IGNORE
  108. * Doxygen should ignore this definition, this function is private.
  109. */
  110. MQTTStatus_t MQTT_UpdateStatePublish( const MQTTContext_t * pMqttContext,
  111. uint16_t packetId,
  112. MQTTStateOperation_t opType,
  113. MQTTQoS_t qos,
  114. MQTTPublishState_t * pNewState );
  115. /** @endcond */
  116. /**
  117. * @fn MQTTStatus_t MQTT_RemoveStateRecord( const MQTTContext_t * pMqttContext, uint16_t packetId );
  118. * @brief Remove the state record for a PUBLISH packet.
  119. *
  120. * @param[in] pMqttContext Initialized MQTT context.
  121. * @param[in] packetId ID of the PUBLISH packet.
  122. *
  123. * @return #MQTTBadParameter or #MQTTSuccess.
  124. */
  125. /**
  126. * @cond DOXYGEN_IGNORE
  127. * Doxygen should ignore this definition, this function is private.
  128. */
  129. MQTTStatus_t MQTT_RemoveStateRecord( const MQTTContext_t * pMqttContext,
  130. uint16_t packetId );
  131. /** @endcond */
  132. /**
  133. * @fn MQTTPublishState_t MQTT_CalculateStateAck( MQTTPubAckType_t packetType, MQTTStateOperation_t opType, MQTTQoS_t qos );
  134. * @brief Calculate the state from a PUBACK, PUBREC, PUBREL, or PUBCOMP.
  135. *
  136. * @param[in] packetType PUBACK, PUBREC, PUBREL, or PUBCOMP.
  137. * @param[in] opType Send or Receive.
  138. * @param[in] qos 1 or 2.
  139. *
  140. * @return The calculated state.
  141. */
  142. /**
  143. * @cond DOXYGEN_IGNORE
  144. * Doxygen should ignore this definition, this function is private.
  145. */
  146. MQTTPublishState_t MQTT_CalculateStateAck( MQTTPubAckType_t packetType,
  147. MQTTStateOperation_t opType,
  148. MQTTQoS_t qos );
  149. /** @endcond */
  150. /**
  151. * @fn MQTTStatus_t MQTT_UpdateStateAck( const MQTTContext_t * pMqttContext, uint16_t packetId, MQTTPubAckType_t packetType, MQTTStateOperation_t opType, MQTTPublishState_t * pNewState );
  152. * @brief Update the state record for an ACKed publish.
  153. *
  154. * @param[in] pMqttContext Initialized MQTT context.
  155. * @param[in] packetId ID of the ack packet.
  156. * @param[in] packetType PUBACK, PUBREC, PUBREL, or PUBCOMP.
  157. * @param[in] opType Send or Receive.
  158. * @param[out] pNewState Updated state of the publish.
  159. *
  160. * @return #MQTTBadParameter if an invalid parameter is passed;
  161. * #MQTTBadResponse if the packet from the network is not found in the records;
  162. * #MQTTIllegalState if the requested update would result in an illegal transition;
  163. * #MQTTSuccess otherwise.
  164. */
  165. /**
  166. * @cond DOXYGEN_IGNORE
  167. * Doxygen should ignore this definition, this function is private.
  168. */
  169. MQTTStatus_t MQTT_UpdateStateAck( const MQTTContext_t * pMqttContext,
  170. uint16_t packetId,
  171. MQTTPubAckType_t packetType,
  172. MQTTStateOperation_t opType,
  173. MQTTPublishState_t * pNewState );
  174. /** @endcond */
  175. /**
  176. * @fn uint16_t MQTT_PubrelToResend( const MQTTContext_t * pMqttContext, MQTTStateCursor_t * pCursor, MQTTPublishState_t * pState );
  177. * @brief Get the packet ID of next pending PUBREL ack to be resent.
  178. *
  179. * This function will need to be called to get the packet for which a PUBREL
  180. * need to be sent when a session is reestablished. Calling this function
  181. * repeatedly until packet id is 0 will give all the packets for which
  182. * a PUBREL need to be resent in the correct order.
  183. *
  184. * @param[in] pMqttContext Initialized MQTT context.
  185. * @param[in,out] pCursor Index at which to start searching.
  186. * @param[out] pState State indicating that PUBREL packet need to be sent.
  187. */
  188. /**
  189. * @cond DOXYGEN_IGNORE
  190. * Doxygen should ignore this definition, this function is private.
  191. */
  192. uint16_t MQTT_PubrelToResend( const MQTTContext_t * pMqttContext,
  193. MQTTStateCursor_t * pCursor,
  194. MQTTPublishState_t * pState );
  195. /** @endcond */
  196. /**
  197. * @brief Get the packet ID of next pending publish to be resent.
  198. *
  199. * This function will need to be called to get the packet for which a publish
  200. * need to be sent when a session is reestablished. Calling this function
  201. * repeatedly until packet id is 0 will give all the packets for which
  202. * a publish need to be resent in the correct order.
  203. *
  204. * @param[in] pMqttContext Initialized MQTT context.
  205. * @param[in,out] pCursor Index at which to start searching.
  206. *
  207. * <b>Example</b>
  208. * @code{c}
  209. *
  210. * // For this example assume this function returns an outgoing unacknowledged
  211. * // QoS 1 or 2 publish from its packet identifier.
  212. * MQTTPublishInfo_t * getPublish( uint16_t packetID );
  213. *
  214. * // Variables used in this example.
  215. * MQTTStatus_t status;
  216. * MQTTStateCursor_t cursor = MQTT_STATE_CURSOR_INITIALIZER;
  217. * bool sessionPresent;
  218. * uint16_t packetID;
  219. * MQTTPublishInfo_t * pResendPublish = NULL;
  220. * MQTTConnectInfo_t connectInfo = { 0 };
  221. *
  222. * // This is assumed to have been initialized before the call to MQTT_Connect().
  223. * MQTTContext_t * pContext;
  224. *
  225. * // Set clean session to false to attempt session resumption.
  226. * connectInfo.cleanSession = false;
  227. * connectInfo.pClientIdentifier = "someClientID";
  228. * connectInfo.clientIdentifierLength = strlen( connectInfo.pClientIdentifier );
  229. * connectInfo.keepAliveSeconds = 60;
  230. * // Optional connect parameters are not relevant to this example.
  231. *
  232. * // Create an MQTT connection. Use 100 milliseconds as a timeout.
  233. * status = MQTT_Connect( pContext, &connectInfo, NULL, 100, &sessionPresent );
  234. *
  235. * if( status == MQTTSuccess )
  236. * {
  237. * if( sessionPresent )
  238. * {
  239. * // Loop while packet ID is nonzero.
  240. * while( ( packetID = MQTT_PublishToResend( pContext, &cursor ) ) != 0 )
  241. * {
  242. * // Assume this function will succeed.
  243. * pResendPublish = getPublish( packetID );
  244. * // Set DUP flag.
  245. * pResendPublish->dup = true;
  246. * status = MQTT_Publish( pContext, pResendPublish, packetID );
  247. *
  248. * if( status != MQTTSuccess )
  249. * {
  250. * // Application can decide how to handle a failure.
  251. * }
  252. * }
  253. * }
  254. * else
  255. * {
  256. * // The broker did not resume a session, so we can clean up the
  257. * // list of outgoing publishes.
  258. * }
  259. * }
  260. * @endcode
  261. */
  262. /* @[declare_mqtt_publishtoresend] */
  263. uint16_t MQTT_PublishToResend( const MQTTContext_t * pMqttContext,
  264. MQTTStateCursor_t * pCursor );
  265. /* @[declare_mqtt_publishtoresend] */
  266. /**
  267. * @fn const char * MQTT_State_strerror( MQTTPublishState_t state );
  268. * @brief State to string conversion for state engine.
  269. *
  270. * @param[in] state The state to convert to a string.
  271. *
  272. * @return The string representation of the state.
  273. */
  274. /**
  275. * @cond DOXYGEN_IGNORE
  276. * Doxygen should ignore this definition, this function is private.
  277. */
  278. const char * MQTT_State_strerror( MQTTPublishState_t state );
  279. /** @endcond */
  280. /* *INDENT-OFF* */
  281. #ifdef __cplusplus
  282. }
  283. #endif
  284. /* *INDENT-ON* */
  285. #endif /* ifndef CORE_MQTT_STATE_H */