mqttesp32

Questions regarding IDF docs description of esp_mqtt_client_init() config parameters


Can someone provide a more helpful description than the docs have of the MQTT esp_mqtt_client_config_t used in esp_mqtt_client_init(), specifically the following 3 parameters:

struct buffer_t
   size //size of MQTT send/receive buffer
   out_size // size of MQTT output buffer
struct outbox_config_t
   limit //Size limit for the outbox in bytes

The descriptions are vague indicate overlap in functionality. Is the outBox only used for holding esp_mqtt_client_enqueue() messages and esp_mqtt_client_publish() messages bypass the outBox?

What is the difference between size (send/receive buffer) and out_size (output buffer) and how are they used? The terminology is confusing, is output used for send and size used for receive? Thanks


Solution

  • The comments in the source might be easier to follow (they provide a bit more context):

    /**
     * Client buffer size configuration
     *
     * Client have two buffers for input and output respectivelly.
     */
    struct buffer_t {
        int size;     /* size of *MQTT* send/receive buffer*/
        int out_size; /* size of *MQTT* output buffer. If not defined, defaults to the size defined by buffer_size */
    } buffer; /* Buffer size configuration.*/
    
    /**
     * Client outbox configuration options.
     */
    struct outbox_config_t {
        uint64_t limit; /*!< Size limit for the outbox in bytes.*/
    } outbox; /*!< Outbox configuration. */
    

    outBox

    outbox (read from config here, data added here) can be used to limit the size of the outbox (if 0 then there is no limit). This limits the number of bytes used to store messages being queued/published. This is mainly for QOS1/2 messages that may need to be retransmitted if the connection drops (also used for QOS0 messages sent using esp_mqtt_client_enqueue).

    Note that the outbox is a linked list of pointers to the message info (outbox_item_t) and the size will change over time (this is generally checked before data is added e.g.).

    esp_mqtt_client_publish() messages bypass the outBox?

    Sometimes. QOS 0 messages may bypass the outbox because they will be sent (or fail) before esp_mqtt_client_publish returns (and, once sent, the process is complete). QOS1/2 messages do need to be stored because it may be neccessary to resend these (it's possible that the connection is lost before the message is acknowledged).

    esp_mqtt_client_enqueue does not block, so the message needs to be stored in outbox regardless (it's sent by the background process). If you call esp_mqtt_client_enqueue with store=false and qos=0 then an error will be returned (because the message would never be sent).

    Difference between size and out_size

    These are used here summarizing:

    int buffer_size = config->buffer.size;
    if (buffer_size <= 0) {
        buffer_size = MQTT_BUFFER_SIZE_BYTE;
    }
    int out_buffer_size = config->buffer.out_size > 0 ? config->buffer.out_size : buffer_size;
    if (mqtt_msg_buffer_init(&client->mqtt_state.connection, out_buffer_size) != ESP_OK) {...}
    client->mqtt_state.in_buffer = (uint8_t *)malloc(buffer_size);
    

    So, if out_size is set, it's used, otherwise buffer_size is used to set the size of connection->buffer. This buffer is used to build outgoing MQTT packets.

    in_buffer is used when receiving data.

    So, by default, the two buffers, which are used to encode/decode packets, will be the same size. However if you know that your program will receiver larger messages than it sends (or vice versa) then you can specify different sizes to optimise memory use. Note that having buffers that are too small may lead to errors because the library cannot process messages larger than the buffer.