/**
@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

*/
