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