/** @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 Retry timeout](@ref mqtt_timeouts_send_retry) 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_retry MQTT Send Retry timeout MQTT Send Retry timeout is the maximum duration between non-empty network transmissions while sending an MQTT packet via the @ref mqtt_processloop_function or @ref mqtt_receiveloop_function API functions. This timeout represents the maximum duration that is allowed for no data transmission over the network through the Transport Send function. 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 Retry timeout can be set by defining the configuration @ref MQTT_SEND_RETRY_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 */