mirror of
https://github.com/FreeRTOS/coreMQTT
synced 2025-05-14 22:30:21 +08:00

* Fixes to timeout of sendMessageVector and refactor of sendBuffer for consistency. * Update size table. * Fixing some small MISRA related issues * Formatting fix * Minor fixes for CBMC. * Updated logical flow to break instead. * Revert "Updated logical flow to break instead." This reverts commit 0ac1c6a61876fe2ee049ce400b46b43b7a3a69e9. * Updated unit tests for coverage. * Fix MQTT_Publish Proof * Fix proofs for connect/sub/unsub API functions * New timing scheme. * Update config defaults to reflect new timing change. * Fix doxygen. Fix formatting. Fix memory table. * Doxygen fixes. * Fix CBMC proofs * Added License identifier back. * Swapped from warning to error for Visual Studio. Co-authored-by: Jason Carroll <czjaso@amazon.com> Co-authored-by: Soren Ptak <skptak@amazon.com> Co-authored-by: Aniruddha Kanhere <60444055+AniruddhaKanhere@users.noreply.github.com>
112 lines
8.5 KiB
Plaintext
112 lines
8.5 KiB
Plaintext
/**
|
|
@page mqtt_timeouts Timeouts in coreMQTT library
|
|
@brief Information about timeouts that coreMQTT library relies on.
|
|
|
|
The coreMQTT library relies on timeouts to handle MQTT keep-alive mechanism and Transport Send and Receive operations.
|
|
Timeouts must be configured correctly for ensuring the expected behavior of the application using the coreMQTT library.
|
|
The timeouts and the recommended configurations are listed below.
|
|
1. [Transport Send and Receive timeouts](@ref mqtt_timeouts_transport_send_receive)
|
|
2. [MQTT Keep Alive interval](@ref mqtt_timeouts_keep_alive)
|
|
3. [MQTT Ping Response timeout](@ref mqtt_timeouts_ping_response)
|
|
4. [MQTT Receive Polling timeout](@ref mqtt_timeouts_receive_polling)
|
|
5. [MQTT Send timeout](@ref mqtt_timeouts_send)
|
|
6. [Timeouts for MQTT_ProcessLoop and MQTT_ReceiveLoop APIs](@ref mqtt_timeouts_process_receive_loop)
|
|
7. [Timeout for MQTT_Connect](@ref mqtt_timeouts_connect)
|
|
|
|
@section mqtt_timeouts_transport_send_receive Transport Send and Receive timeouts
|
|
These are the network send and read operation blocking timeouts used by the implementation
|
|
of Transport Send and Transport Receive functions, respectively, that are supplied to the coreMQTT library.
|
|
Transport Send and Receive timeouts must be configured by the application for the Transport
|
|
interface implementation provided to the coreMQTT library. If it is essential to send more data than
|
|
the size of the TCP buffer, then the Transport Send timeout can be set to a bigger value than that of
|
|
cases in which size of the data to be sent is smaller than the TCP buffer, so as to efficiently wait for the
|
|
TCP buffer to be available to copy the data from MQTT buffers.
|
|
|
|
We recommend using a relatively smaller value for these timeouts as compared to the MQTT Keep Alive interval,
|
|
so as to make sure that an MQTT Control packet including an MQTT ping request packet can be sent to the Server
|
|
even within the Keep Alive interval, even if the Transport functions block for the maximum time.
|
|
|
|
@see [Transport Interface](@ref mqtt_transport_interface)
|
|
|
|
@section mqtt_timeouts_keep_alive MQTT Keep Alive interval
|
|
MQTT Keep Alive interval is the maximum time interval that is permitted to elapse between the point at which
|
|
the MQTT Client finishes transmitting one Control Packet and the point it starts sending the next. If the Server does not
|
|
receive a Control Packet from the Client within one and a half times the Keep Alive time period, it will disconnect
|
|
the MQTT connection to the Client.
|
|
|
|
If @ref mqtt_processloop_function function is used to manage keep alive in the application,
|
|
the MQTT Keep Alive interval must be configured to be a value larger than that of the Transport Send and Receive timeouts.
|
|
This is to make sure that a Control packet including an MQTT ping request packet can be sent to the Server even if
|
|
the Transport functions block for the maximum time. MQTT Keep Alive interval can be configured by setting the
|
|
`keepAliveIntervalSec` member of the [MQTTContext_t](@ref mqtt_struct_types) structure.
|
|
|
|
@see @ref mqtt_keepalive
|
|
|
|
@section mqtt_timeouts_ping_response MQTT Ping Response timeout
|
|
MQTT Ping Response timeout is the time to wait for a ping response to an MQTT ping request as part of the keep-alive
|
|
mechanism in the MQTT Client. This timeout can be configured independent of the Transport timeouts unlike the MQTT Keep Alive
|
|
interval, since this timeout only depends on the MQTT broker, the platform and the network latencies.
|
|
|
|
We recommend to choose a ping response timeout by experimenting with an MQTT application on a sample of devices and collecting the data
|
|
of latency for each ping response from the broker after a ping request is sent. A timeout value can then be chosen based on the statistical
|
|
measure suitable for the end application, such as 99th percentile or average.
|
|
|
|
MQTT Ping Response timeout can be set by defining the configuration @ref MQTT_PINGRESP_TIMEOUT_MS.
|
|
|
|
@section mqtt_timeouts_receive_polling MQTT Receive Polling timeout
|
|
MQTT Receive Polling timeout is the maximum duration between non-empty network reads while receiving an MQTT packet
|
|
via the @ref mqtt_processloop_function or @ref mqtt_receiveloop_function API functions. This timeout represents the maximum polling
|
|
duration that is allowed without any data reception from the network for the incoming packet.
|
|
|
|
It is important to note that having this timeout too short will result in MQTT being disconnected due to the possibility of partial data
|
|
being received. If you have small TCP buffers and a high latency network, the optimum value for the timeout can be surprisingly long.
|
|
In such cases, optimum value for the timeout can be better determined based on experimenting the MQTT applications with payloads
|
|
bigger than the TCP buffer. If a retry is required for a Transport Receive even after hitting a timeout of Transport Receive
|
|
without any data received, we recommend using a value larger than the Transport Receive timeout. If a dummy implementation of the
|
|
@ref MQTTGetCurrentTimeFunc_t timer function, that always returns 0, is used, then this timeout must be set to 0.
|
|
|
|
The MQTT Receive Polling timeout can be set by defining the configuration @ref MQTT_RECV_POLLING_TIMEOUT_MS.
|
|
|
|
@section mqtt_timeouts_send MQTT Send timeout
|
|
MQTT Send timeout is the maximum duration allowed to send an MQTT packet over the transport interface.
|
|
|
|
It is important to note that having this timeout too short will result in MQTT being disconnected due to the possibility
|
|
of partial data being sent. If you have small TCP buffers and a high latency network, the optimum value for the timeout
|
|
can be surprisingly long. In such cases, optimum value for the timeout can be better determined based on experimenting
|
|
the MQTT applications with payloads bigger than the TCP buffer. If a retry is required for a Transport Send even after
|
|
hitting a timeout of Transport Send before any data could be sent to transport layer, we recommend using a value larger
|
|
than the Transport Send timeout. If a dummy implementation of the @ref MQTTGetCurrentTimeFunc_t timer function,
|
|
that always returns 0, is used, then this timeout must be set to 0.
|
|
|
|
The MQTT Send timeout can be set by defining the configuration @ref MQTT_SEND_TIMEOUT_MS.
|
|
|
|
@section mqtt_timeouts_process_receive_loop Timeouts for MQTT_ProcessLoop and MQTT_ReceiveLoop APIs
|
|
This timeout is passed as an argument to @ref mqtt_processloop_function or @ref mqtt_receiveloop_function API functions.
|
|
It is the minimum time that the receive loop in these API functions will run, unless an error occurs. These APIs may be blocked
|
|
for more time than this timeout, since the APIs will attempt to send and receive MQTT packets to the network using the
|
|
Transport implementation. The maximum time spent on Transport functions for send and receive depends on the Transport Send and
|
|
Receive timeouts and the MQTT Receive Polling timeouts as explained in the descriptions of these timeouts above.
|
|
|
|
Passing a timeout value of 0 will run these APIs for a single iteration. The other timeouts mentioned thus far ensure you don't
|
|
disconnect the MQTT just because the network is slow or buffers get full. They are necessary because coreMQTT has no 'memory' of
|
|
being half way through a packet and will just error and disconnect if you don't give enough time for incoming or outgoing packet delivery.
|
|
That means, especially in multi-threaded application, the process loop timeout can be zero.
|
|
|
|
@ref mqtt_processloop_function API can be used to manage the MQTT keep-alive mechanism and if used, application must invoke this API
|
|
faster than the MQTT Keep Alive interval. If a dummy @ref MQTTGetCurrentTimeFunc_t was passed to @ref mqtt_init_function, then the keep-alive mechanism is not supported by the @ref mqtt_processloop_function API; instead the @ref mqtt_receiveloop_function should be used.
|
|
|
|
@see @ref mqtt_receivetimeout
|
|
|
|
@section mqtt_timeouts_connect Timeout for MQTT_Connect
|
|
This timeout is passed as an argument to @ref mqtt_connect_function. It is the maximum time to wait for an MQTT CONNACK packet. If this value is
|
|
set to 0, then instead of a time-based loop, it will attempt to call the Transport Receive function up to a maximum number of retries,
|
|
which is defined by @ref MQTT_MAX_CONNACK_RECEIVE_RETRY_COUNT.
|
|
|
|
We recommend to choose a timeout for @ref mqtt_connect_function by experimenting with an MQTT application on a sample of devices and
|
|
collecting the data of latency for each CONNACK packet received from the broker after an MQTT CONNECT packet is sent. A timeout value can then be chosen
|
|
based on the statistical measure suitable for the end application, such as 99th percentile or average.
|
|
|
|
@see @ref mqtt_receivetimeout
|
|
|
|
*/
|