mirror of
https://github.com/espressif/esp-mqtt.git
synced 2026-10-13 11:17:36 +00:00
refactor: Reorganize mqtt5 property management to mqtt5_msg library
This commit is contained in:
committed by
Euripedes Rocha Filho
parent
69ca2fb79b
commit
5de986916c
+1
-65
@@ -8,6 +8,7 @@
|
||||
#define _MQTT5_CLIENT_H_
|
||||
|
||||
#include "mqtt_client.h"
|
||||
#include "mqtt_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -77,11 +78,6 @@ typedef enum mqtt5_reason_code_t {
|
||||
*/
|
||||
typedef __attribute__((deprecated)) esp_mqtt5_reason_code_t esp_mqtt5_error_reason_code_t;
|
||||
|
||||
/**
|
||||
* MQTT5 user property handle
|
||||
*/
|
||||
typedef struct mqtt5_user_property_list_t *mqtt5_user_property_handle_t;
|
||||
|
||||
/**
|
||||
* MQTT5 protocol connect properties and will properties configuration, more details refer to MQTT5 protocol document section 3.1.2.11 and 3.3.2.3
|
||||
*/
|
||||
@@ -106,58 +102,6 @@ typedef struct {
|
||||
will_user_property; /*!< The handle for will message user property, call function esp_mqtt5_client_set_user_property to set it */
|
||||
} esp_mqtt5_connection_property_config_t;
|
||||
|
||||
/**
|
||||
* MQTT5 protocol publish properties configuration, more details refer to MQTT5 protocol document section 3.3.2.3
|
||||
*/
|
||||
typedef struct {
|
||||
bool payload_format_indicator; /*!< This value is to indicator publish message payload format */
|
||||
uint32_t message_expiry_interval; /*!< The time interval that message expiry */
|
||||
uint16_t topic_alias; /*!< An integer value to identify the topic instead of using topic name string */
|
||||
const char *response_topic; /*!< Topic name for a response message */
|
||||
const char *correlation_data; /*!< Binary data for receiver to match the response message */
|
||||
uint16_t correlation_data_len; /*!< The length of correlation data */
|
||||
const char
|
||||
*content_type; /*!< This value is to indicator publish message content type, use a MIME content type string */
|
||||
mqtt5_user_property_handle_t
|
||||
user_property; /*!< The handle for user property, call function esp_mqtt5_client_set_user_property to set it */
|
||||
} esp_mqtt5_publish_property_config_t;
|
||||
|
||||
/**
|
||||
* MQTT5 protocol subscribe properties configuration, more details refer to MQTT5 protocol document section 3.8.2.1
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t subscribe_id; /*!< A variable byte represents the identifier of the subscription */
|
||||
bool no_local_flag; /*!< Subscription Option to allow that server publish message that client sent */
|
||||
bool retain_as_published_flag; /*!< Subscription Option to keep the retain flag as published option */
|
||||
uint8_t retain_handle; /*!< Subscription Option to handle retain option */
|
||||
bool is_share_subscribe; /*!< Whether subscribe is a shared subscription */
|
||||
const char
|
||||
*share_name; /*!< The name of shared subscription which is a part of $share/{share_name}/{topic} */
|
||||
mqtt5_user_property_handle_t
|
||||
user_property; /*!< The handle for user property, call function esp_mqtt5_client_set_user_property to set it */
|
||||
} esp_mqtt5_subscribe_property_config_t;
|
||||
|
||||
/**
|
||||
* MQTT5 protocol unsubscribe properties configuration, more details refer to MQTT5 protocol document section 3.10.2.1
|
||||
*/
|
||||
typedef struct {
|
||||
bool is_share_subscribe; /*!< Whether subscribe is a shared subscription */
|
||||
const char
|
||||
*share_name; /*!< The name of shared subscription which is a part of $share/{share_name}/{topic} */
|
||||
mqtt5_user_property_handle_t
|
||||
user_property; /*!< The handle for user property, call function esp_mqtt5_client_set_user_property to set it */
|
||||
} esp_mqtt5_unsubscribe_property_config_t;
|
||||
|
||||
/**
|
||||
* MQTT5 protocol disconnect properties configuration, more details refer to MQTT5 protocol document section 3.14.2.2
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t session_expiry_interval; /*!< The interval time of session expiry */
|
||||
uint8_t disconnect_reason; /*!< The reason that connection disconnect, refer to mqtt5_error_reason_code */
|
||||
mqtt5_user_property_handle_t
|
||||
user_property; /*!< The handle for user property, call function esp_mqtt5_client_set_user_property to set it */
|
||||
} esp_mqtt5_disconnect_property_config_t;
|
||||
|
||||
/**
|
||||
* MQTT5 server response properties from CONNACK (section 3.2.2.3)
|
||||
*
|
||||
@@ -194,14 +138,6 @@ typedef struct {
|
||||
esp_mqtt5_server_resp_property_t server; /*!< Server response properties from CONNACK (valid only in MQTT_EVENT_CONNECTED) */
|
||||
} esp_mqtt5_event_property_t;
|
||||
|
||||
/**
|
||||
* MQTT5 protocol for user property
|
||||
*/
|
||||
typedef struct {
|
||||
const char *key; /*!< Item key name */
|
||||
const char *value; /*!< Item value string */
|
||||
} esp_mqtt5_user_property_item_t;
|
||||
|
||||
/**
|
||||
* @brief Set MQTT5 client connect property configuration
|
||||
*
|
||||
|
||||
+1
-23
@@ -18,6 +18,7 @@
|
||||
#include "esp_err.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_transport.h"
|
||||
#include "mqtt_common.h"
|
||||
#ifdef CONFIG_MQTT_PROTOCOL_5
|
||||
#include "mqtt5_client.h"
|
||||
#endif
|
||||
@@ -28,11 +29,6 @@ extern "C" {
|
||||
|
||||
typedef struct esp_mqtt_client *esp_mqtt_client_handle_t;
|
||||
|
||||
#define MQTT_OVER_TCP_SCHEME "mqtt"
|
||||
#define MQTT_OVER_SSL_SCHEME "mqtts"
|
||||
#define MQTT_OVER_WS_SCHEME "ws"
|
||||
#define MQTT_OVER_WSS_SCHEME "wss"
|
||||
|
||||
/**
|
||||
* @brief *MQTT* event types.
|
||||
*
|
||||
@@ -152,16 +148,6 @@ typedef enum esp_mqtt_transport_t {
|
||||
``wss`` */
|
||||
} esp_mqtt_transport_t;
|
||||
|
||||
/**
|
||||
* *MQTT* protocol version used for connection
|
||||
*/
|
||||
typedef enum esp_mqtt_protocol_ver_t {
|
||||
MQTT_PROTOCOL_UNDEFINED = 0,
|
||||
MQTT_PROTOCOL_V_3_1,
|
||||
MQTT_PROTOCOL_V_3_1_1,
|
||||
MQTT_PROTOCOL_V_5,
|
||||
} esp_mqtt_protocol_ver_t;
|
||||
|
||||
/**
|
||||
* States of MQTT client connection
|
||||
*/
|
||||
@@ -408,14 +394,6 @@ typedef struct esp_mqtt_client_config_t {
|
||||
} outbox; /*!< Outbox configuration. */
|
||||
} esp_mqtt_client_config_t;
|
||||
|
||||
/**
|
||||
* Topic definition struct
|
||||
*/
|
||||
typedef struct topic_t {
|
||||
const char *filter; /*!< Topic filter to subscribe */
|
||||
int qos; /*!< Max QoS level of the subscription */
|
||||
} esp_mqtt_topic_t;
|
||||
|
||||
/**
|
||||
* @brief Creates *MQTT* client handle based on the configuration
|
||||
*
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MQTT_OVER_TCP_SCHEME "mqtt"
|
||||
#define MQTT_OVER_SSL_SCHEME "mqtts"
|
||||
#define MQTT_OVER_WS_SCHEME "ws"
|
||||
#define MQTT_OVER_WSS_SCHEME "wss"
|
||||
|
||||
/**
|
||||
* *MQTT* protocol version used for connection
|
||||
*/
|
||||
typedef enum esp_mqtt_protocol_ver_t {
|
||||
MQTT_PROTOCOL_UNDEFINED = 0,
|
||||
MQTT_PROTOCOL_V_3_1,
|
||||
MQTT_PROTOCOL_V_3_1_1,
|
||||
MQTT_PROTOCOL_V_5,
|
||||
} esp_mqtt_protocol_ver_t;
|
||||
|
||||
/**
|
||||
* Topic definition struct
|
||||
*/
|
||||
typedef struct topic_t {
|
||||
const char *filter; /*!< Topic filter to subscribe */
|
||||
int qos; /*!< Max QoS level of the subscription */
|
||||
} esp_mqtt_topic_t;
|
||||
|
||||
/**
|
||||
* MQTT5 user property handle
|
||||
*/
|
||||
typedef struct mqtt5_user_property_list_t *mqtt5_user_property_handle_t;
|
||||
|
||||
/**
|
||||
* MQTT5 protocol for user property
|
||||
*/
|
||||
typedef struct {
|
||||
const char *key; /*!< Item key name */
|
||||
const char *value; /*!< Item value string */
|
||||
} esp_mqtt5_user_property_item_t;
|
||||
|
||||
/**
|
||||
* MQTT5 protocol publish properties configuration, more details refer to MQTT5 protocol document section 3.3.2.3
|
||||
*/
|
||||
typedef struct {
|
||||
bool payload_format_indicator; /*!< This value is to indicator publish message payload format */
|
||||
uint32_t message_expiry_interval; /*!< The time interval that message expiry */
|
||||
uint16_t topic_alias; /*!< An integer value to identify the topic instead of using topic name string */
|
||||
const char *response_topic; /*!< Topic name for a response message */
|
||||
const char *correlation_data; /*!< Binary data for receiver to match the response message */
|
||||
uint16_t correlation_data_len; /*!< The length of correlation data */
|
||||
const char *content_type; /*!< This value is to indicator publish message content type, use a MIME content type string */
|
||||
mqtt5_user_property_handle_t user_property; /*!< The handle for user property, call function esp_mqtt5_client_set_user_property to set it */
|
||||
} esp_mqtt5_publish_property_config_t;
|
||||
|
||||
/**
|
||||
* MQTT5 protocol subscribe properties configuration, more details refer to MQTT5 protocol document section 3.8.2.1
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t subscribe_id; /*!< A variable byte represents the identifier of the subscription */
|
||||
bool no_local_flag; /*!< Subscription Option to allow that server publish message that client sent */
|
||||
bool retain_as_published_flag; /*!< Subscription Option to keep the retain flag as published option */
|
||||
uint8_t retain_handle; /*!< Subscription Option to handle retain option */
|
||||
bool is_share_subscribe; /*!< Whether subscribe is a shared subscription */
|
||||
const char *share_name; /*!< The name of shared subscription which is a part of $share/{share_name}/{topic} */
|
||||
mqtt5_user_property_handle_t user_property; /*!< The handle for user property, call function esp_mqtt5_client_set_user_property to set it */
|
||||
} esp_mqtt5_subscribe_property_config_t;
|
||||
|
||||
/**
|
||||
* MQTT5 protocol disconnect properties configuration, more details refer to MQTT5 protocol document section 3.14.2.2
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t session_expiry_interval; /*!< The interval time of session expiry */
|
||||
uint8_t disconnect_reason; /*!< The reason that connection disconnect, refer to mqtt5_error_reason_code */
|
||||
mqtt5_user_property_handle_t user_property; /*!< The handle for user property, call function esp_mqtt5_client_set_user_property to set it */
|
||||
} esp_mqtt5_disconnect_property_config_t;
|
||||
|
||||
/**
|
||||
* MQTT5 protocol unsubscribe properties configuration, more details refer to MQTT5 protocol document section 3.10.2.1
|
||||
*/
|
||||
typedef struct {
|
||||
bool is_share_subscribe; /*!< Whether subscribe is a shared subscription */
|
||||
const char *share_name; /*!< The name of shared subscription which is a part of $share/{share_name}/{topic} */
|
||||
mqtt5_user_property_handle_t user_property; /*!< The handle for user property, call function esp_mqtt5_client_set_user_property to set it */
|
||||
} esp_mqtt5_unsubscribe_property_config_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -16,13 +16,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct mqtt5_topic_alias {
|
||||
char *topic;
|
||||
uint16_t topic_len;
|
||||
uint16_t topic_alias;
|
||||
STAILQ_ENTRY(mqtt5_topic_alias) next;
|
||||
} mqtt5_topic_alias_t;
|
||||
STAILQ_HEAD(mqtt5_topic_alias_list_t, mqtt5_topic_alias);
|
||||
typedef struct mqtt5_topic_alias_list_t *mqtt5_topic_alias_handle_t;
|
||||
typedef struct mqtt5_topic_alias *mqtt5_topic_alias_item_t;
|
||||
|
||||
|
||||
+11
-9
@@ -7,10 +7,8 @@
|
||||
#define MQTT5_MSG_H
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "sys/queue.h"
|
||||
#include "mqtt_config.h"
|
||||
#include "mqtt_msg.h"
|
||||
#include "mqtt_client.h"
|
||||
#include "mqtt_common.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -45,12 +43,6 @@ enum mqtt_properties_type {
|
||||
MQTT5_PROPERTY_SHARED_SUBSCR_AVAILABLE = 0x2A,
|
||||
};
|
||||
|
||||
typedef struct mqtt5_user_property {
|
||||
char *key;
|
||||
char *value;
|
||||
STAILQ_ENTRY(mqtt5_user_property) next;
|
||||
} mqtt5_user_property_t;
|
||||
STAILQ_HEAD(mqtt5_user_property_list_t, mqtt5_user_property);
|
||||
typedef struct mqtt5_user_property *mqtt5_user_property_item_t;
|
||||
|
||||
typedef struct {
|
||||
@@ -141,6 +133,16 @@ mqtt_message_t *mqtt5_msg_pubrel(mqtt_message_t *message, uint16_t message_id);
|
||||
mqtt_message_t *mqtt5_msg_pubrec(mqtt_message_t *message, uint16_t message_id);
|
||||
mqtt_message_t *mqtt5_msg_puback(mqtt_message_t *message, uint16_t message_id);
|
||||
|
||||
mqtt5_user_property_handle_t mqtt5_msg_create_user_property_list(void);
|
||||
esp_err_t mqtt5_msg_set_user_property(mqtt5_user_property_handle_t *user_property_list, const char *key, size_t key_len,
|
||||
const char *value, size_t value_len);
|
||||
void mqtt5_msg_delete_user_property(mqtt5_user_property_handle_t user_property_list);
|
||||
esp_err_t mqtt5_msg_get_user_property(mqtt5_user_property_handle_t user_property_list,
|
||||
esp_mqtt5_user_property_item_t *item, uint8_t *item_num);
|
||||
uint8_t mqtt5_msg_get_user_property_count(mqtt5_user_property_handle_t user_property_list);
|
||||
esp_err_t mqtt5_msg_copy_user_property(mqtt5_user_property_handle_t user_property_new,
|
||||
const struct mqtt5_user_property_list_t *user_property_old);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include "platform.h"
|
||||
|
||||
#include "esp_event.h"
|
||||
#include "mqtt_config.h"
|
||||
#include "mqtt_client.h"
|
||||
#include "mqtt_msg.h"
|
||||
#ifdef MQTT_PROTOCOL_5
|
||||
|
||||
@@ -8,9 +8,10 @@
|
||||
#define MQTT_MSG_H
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include "esp_err.h"
|
||||
#include "mqtt_common.h"
|
||||
|
||||
#include "mqtt_config.h"
|
||||
#include "mqtt_client.h"
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
+137
-33
@@ -5,11 +5,11 @@
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "mqtt5_msg.h"
|
||||
#include "mqtt_client.h"
|
||||
#include "mqtt_config.h"
|
||||
#include "esp_err.h"
|
||||
#include "mqtt_common.h"
|
||||
#include "platform.h"
|
||||
#include "esp_log.h"
|
||||
#include "mqtt_client_priv.h"
|
||||
#include "sys/queue.h"
|
||||
|
||||
#define MQTT5_MAX_FIXED_HEADER_SIZE 5
|
||||
#define MQTT5_MAX_PROPERTY_STRING_LEN (16 * 1024)
|
||||
@@ -32,6 +32,13 @@ static const char *TAG = "mqtt5_msg";
|
||||
#define MQTT5_CONVERT_TWO_BYTE(i, a) i = (a >> 8) & 0xff; \
|
||||
i = a & 0xff;
|
||||
|
||||
typedef struct mqtt5_user_property {
|
||||
char *key;
|
||||
char *value;
|
||||
STAILQ_ENTRY(mqtt5_user_property) next;
|
||||
} mqtt5_user_property_t;
|
||||
STAILQ_HEAD(mqtt5_user_property_list_t, mqtt5_user_property);
|
||||
|
||||
enum mqtt5_connect_flag {
|
||||
MQTT5_CONNECT_FLAG_USERNAME = 1 << 7,
|
||||
MQTT5_CONNECT_FLAG_PASSWORD = 1 << 6,
|
||||
@@ -234,13 +241,12 @@ static mqtt_message_t *fini_message(mqtt_message_t *message, int type, int dup,
|
||||
return message;
|
||||
}
|
||||
|
||||
static esp_err_t mqtt5_msg_set_user_property(mqtt5_user_property_handle_t *user_property, char *key, size_t key_len,
|
||||
char *value, size_t value_len)
|
||||
esp_err_t mqtt5_msg_set_user_property(mqtt5_user_property_handle_t *user_property_list, const char *key, size_t key_len,
|
||||
const char *value, size_t value_len)
|
||||
{
|
||||
if (!*user_property) {
|
||||
*user_property = calloc(1, sizeof(struct mqtt5_user_property_list_t));
|
||||
ESP_MEM_CHECK(TAG, *user_property, return ESP_FAIL);
|
||||
STAILQ_INIT(*user_property);
|
||||
if (!*user_property_list) {
|
||||
*user_property_list = mqtt5_msg_create_user_property_list();
|
||||
ESP_MEM_CHECK(TAG, *user_property_list, return ESP_FAIL);
|
||||
}
|
||||
|
||||
mqtt5_user_property_item_t user_property_item = calloc(1, sizeof(mqtt5_user_property_t));
|
||||
@@ -260,13 +266,13 @@ static esp_err_t mqtt5_msg_set_user_property(mqtt5_user_property_handle_t *user_
|
||||
});
|
||||
memcpy(user_property_item->value, value, value_len);
|
||||
user_property_item->value[value_len] = '\0';
|
||||
STAILQ_INSERT_TAIL(*user_property, user_property_item, next);
|
||||
STAILQ_INSERT_TAIL(*user_property_list, user_property_item, next);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static mqtt5_user_property_handle_t mqtt5_msg_get_user_property(uint8_t *buffer, size_t buffer_length)
|
||||
static mqtt5_user_property_handle_t mqtt5_msg_parse_user_property(uint8_t *buffer, size_t buffer_length)
|
||||
{
|
||||
mqtt5_user_property_handle_t user_porperty = NULL;
|
||||
mqtt5_user_property_handle_t user_property = NULL;
|
||||
uint8_t *property = buffer;
|
||||
uint16_t property_offset = 0, len = 0;
|
||||
|
||||
@@ -327,8 +333,7 @@ static mqtt5_user_property_handle_t mqtt5_msg_get_user_property(uint8_t *buffer,
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
|
||||
|
||||
if (mqtt5_msg_set_user_property(&user_porperty, (char *)key, key_len, (char *)value, value_len) != ESP_OK) {
|
||||
#pragma GCC diagnostic pop
|
||||
if (mqtt5_msg_set_user_property(&user_property, (char *)key, key_len, (char *)value, value_len) != ESP_OK) {
|
||||
ESP_LOGE(TAG, "mqtt5_msg_set_user_property fail");
|
||||
goto err;
|
||||
}
|
||||
@@ -342,9 +347,9 @@ static mqtt5_user_property_handle_t mqtt5_msg_get_user_property(uint8_t *buffer,
|
||||
}
|
||||
}
|
||||
|
||||
return user_porperty;
|
||||
return user_property;
|
||||
err:
|
||||
esp_mqtt5_client_delete_user_property(user_porperty);
|
||||
mqtt5_msg_delete_user_property(user_property);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -562,7 +567,7 @@ char *mqtt5_get_publish_property_payload(uint8_t *buffer, size_t buffer_length,
|
||||
property_offset += len;
|
||||
|
||||
if (mqtt5_msg_set_user_property(user_property, (char *)key, key_len, (char *)value, value_len) != ESP_OK) {
|
||||
esp_mqtt5_client_delete_user_property(*user_property);
|
||||
mqtt5_msg_delete_user_property(*user_property);
|
||||
*user_property = NULL;
|
||||
ESP_LOGE(TAG, "mqtt5_msg_set_user_property fail");
|
||||
return NULL;
|
||||
@@ -613,7 +618,7 @@ char *mqtt5_get_suback_data(uint8_t *buffer, size_t *length, mqtt5_user_property
|
||||
|
||||
if (*user_property) {
|
||||
ESP_LOGE(TAG, "user_property not freed before mqtt5_get_suback_data");
|
||||
esp_mqtt5_client_delete_user_property(*user_property);
|
||||
mqtt5_msg_delete_user_property(*user_property);
|
||||
*user_property = NULL;
|
||||
}
|
||||
|
||||
@@ -637,16 +642,11 @@ char *mqtt5_get_suback_data(uint8_t *buffer, size_t *length, mqtt5_user_property
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* False positive: the previous *user_property value is freed above if non-NULL.
|
||||
* The analyzer cannot track the deallocation across the TU boundary. */
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
|
||||
*user_property = mqtt5_msg_get_user_property(buffer + offset, property_len);
|
||||
#pragma GCC diagnostic pop
|
||||
*user_property = mqtt5_msg_parse_user_property(buffer + offset, property_len);
|
||||
offset += property_len;
|
||||
|
||||
if (offset >= totlen) {
|
||||
esp_mqtt5_client_delete_user_property(*user_property);
|
||||
mqtt5_msg_delete_user_property(*user_property);
|
||||
*user_property = NULL;
|
||||
*length = 0;
|
||||
return NULL;
|
||||
@@ -667,7 +667,7 @@ char *mqtt5_get_puback_data(uint8_t *buffer, size_t *length, mqtt5_user_property
|
||||
|
||||
if (*user_property) {
|
||||
ESP_LOGE(TAG, "user_property not freed before mqtt5_get_puback_data");
|
||||
esp_mqtt5_client_delete_user_property(*user_property);
|
||||
mqtt5_msg_delete_user_property(*user_property);
|
||||
*user_property = NULL;
|
||||
}
|
||||
|
||||
@@ -689,12 +689,7 @@ char *mqtt5_get_puback_data(uint8_t *buffer, size_t *length, mqtt5_user_property
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* False positive: the previous *user_property value is freed above if non-NULL.
|
||||
* The analyzer cannot track the deallocation across the TU boundary. */
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
|
||||
*user_property = mqtt5_msg_get_user_property(buffer + offset, property_len);
|
||||
#pragma GCC diagnostic pop
|
||||
*user_property = mqtt5_msg_parse_user_property(buffer + offset, property_len);
|
||||
}
|
||||
|
||||
return data;
|
||||
@@ -1006,7 +1001,7 @@ esp_err_t mqtt5_msg_parse_connack_property(uint8_t *buffer, size_t buffer_len, m
|
||||
property_offset += len;
|
||||
|
||||
if (mqtt5_msg_set_user_property(user_property, (char *)key, key_len, (char *)value, value_len) != ESP_OK) {
|
||||
esp_mqtt5_client_delete_user_property(*user_property);
|
||||
mqtt5_msg_delete_user_property(*user_property);
|
||||
*user_property = NULL;
|
||||
ESP_LOGE(TAG, "mqtt5_msg_set_user_property fail");
|
||||
return ESP_FAIL;
|
||||
@@ -1543,3 +1538,112 @@ mqtt_message_t *mqtt5_msg_pubcomp(mqtt_message_t *message, uint16_t message_id)
|
||||
properties_offset), fail_message(message));
|
||||
return fini_message(message, MQTT_MSG_TYPE_PUBCOMP, 0, 0, 0);
|
||||
}
|
||||
|
||||
void mqtt5_msg_delete_user_property(mqtt5_user_property_handle_t user_property_list)
|
||||
{
|
||||
if (user_property_list) {
|
||||
mqtt5_user_property_item_t item;
|
||||
mqtt5_user_property_item_t tmp;
|
||||
STAILQ_FOREACH_SAFE(item, user_property_list, next, tmp) {
|
||||
STAILQ_REMOVE(user_property_list, item, mqtt5_user_property, next);
|
||||
free(item->key);
|
||||
free(item->value);
|
||||
free(item);
|
||||
}
|
||||
}
|
||||
|
||||
free(user_property_list);
|
||||
}
|
||||
|
||||
mqtt5_user_property_handle_t mqtt5_msg_create_user_property_list(void)
|
||||
{
|
||||
mqtt5_user_property_handle_t user_property = calloc(1, sizeof(struct mqtt5_user_property_list_t));
|
||||
ESP_MEM_CHECK(TAG, user_property, return NULL);
|
||||
STAILQ_INIT(user_property);
|
||||
return user_property;
|
||||
}
|
||||
|
||||
uint8_t mqtt5_msg_get_user_property_count(mqtt5_user_property_handle_t user_property_list)
|
||||
{
|
||||
uint8_t count = 0;
|
||||
mqtt5_user_property_item_t item;
|
||||
STAILQ_FOREACH(item, user_property_list, next) {
|
||||
count ++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static void mqtt5_msg_free_user_property_result(esp_mqtt5_user_property_item_t *item)
|
||||
{
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||
free((void *)item->key);
|
||||
free((void *)item->value);
|
||||
#pragma GCC diagnostic pop
|
||||
item->key = NULL;
|
||||
item->value = NULL;
|
||||
}
|
||||
|
||||
esp_err_t mqtt5_msg_get_user_property(mqtt5_user_property_handle_t user_property_list,
|
||||
esp_mqtt5_user_property_item_t *item, uint8_t *item_num)
|
||||
{
|
||||
int property_item_idx = 0;
|
||||
int j = 0;
|
||||
mqtt5_user_property_item_t user_property_item;
|
||||
uint8_t num = *item_num;
|
||||
STAILQ_FOREACH(user_property_item, user_property_list, next) {
|
||||
if (property_item_idx < num) {
|
||||
size_t item_key_len = strlen(user_property_item->key);
|
||||
size_t item_value_len = strlen(user_property_item->value);
|
||||
char *key = calloc(1, item_key_len + 1);
|
||||
ESP_MEM_CHECK(TAG, key, goto err);
|
||||
memcpy(key, user_property_item->key, item_key_len);
|
||||
key[item_key_len] = '\0';
|
||||
char *value = calloc(1, item_value_len + 1);
|
||||
ESP_MEM_CHECK(TAG, value, {
|
||||
free(key);
|
||||
goto err;
|
||||
});
|
||||
memcpy(value, user_property_item->value, item_value_len);
|
||||
value[item_value_len] = '\0';
|
||||
item[property_item_idx].key = key;
|
||||
item[property_item_idx].value = value;
|
||||
property_item_idx ++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*item_num = property_item_idx;
|
||||
return ESP_OK;
|
||||
err:
|
||||
|
||||
for (j = 0; j < property_item_idx; j ++) {
|
||||
mqtt5_msg_free_user_property_result(&item[j]);
|
||||
}
|
||||
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
esp_err_t mqtt5_msg_copy_user_property(mqtt5_user_property_handle_t user_property_new,
|
||||
const struct mqtt5_user_property_list_t *user_property_old)
|
||||
{
|
||||
mqtt5_user_property_item_t old_item;
|
||||
mqtt5_user_property_item_t new_item;
|
||||
STAILQ_FOREACH(old_item, user_property_old, next) {
|
||||
new_item = calloc(1, sizeof(mqtt5_user_property_t));
|
||||
ESP_MEM_CHECK(TAG, new_item, return ESP_FAIL);
|
||||
new_item->key = strdup(old_item->key);
|
||||
ESP_MEM_CHECK(TAG, new_item->key, {
|
||||
free(new_item);
|
||||
return ESP_FAIL;
|
||||
});
|
||||
new_item->value = strdup(old_item->value);
|
||||
ESP_MEM_CHECK(TAG, new_item->value, {
|
||||
free(new_item->key);
|
||||
free(new_item);
|
||||
return ESP_FAIL;
|
||||
});
|
||||
STAILQ_INSERT_TAIL(user_property_new, new_item, next);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "esp_heap_caps.h"
|
||||
#include "mqtt_client.h"
|
||||
#include "mqtt_msg.h"
|
||||
#include "mqtt_config.h"
|
||||
#include "platform.h"
|
||||
|
||||
+35
-130
@@ -4,15 +4,29 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "mqtt_config.h"
|
||||
#include "mqtt_client.h"
|
||||
#include "mqtt_client_priv.h"
|
||||
#include "mqtt5_client.h"
|
||||
#include "mqtt5_msg.h"
|
||||
#include "esp_log.h"
|
||||
#include <string.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
static const char *TAG = "mqtt5_client";
|
||||
|
||||
// Receive Maximum is optional in CONNACK; when absent the limit is 65535
|
||||
#define MQTT5_DEFAULT_RECEIVE_MAXIMUM 65535
|
||||
|
||||
typedef struct mqtt5_topic_alias {
|
||||
char *topic;
|
||||
uint16_t topic_len;
|
||||
uint16_t topic_alias;
|
||||
STAILQ_ENTRY(mqtt5_topic_alias) next;
|
||||
} mqtt5_topic_alias_t;
|
||||
STAILQ_HEAD(mqtt5_topic_alias_list_t, mqtt5_topic_alias);
|
||||
|
||||
static void esp_mqtt5_print_error_code(esp_mqtt5_client_handle_t client, int code);
|
||||
static esp_err_t esp_mqtt5_client_update_topic_alias(mqtt5_topic_alias_handle_t topic_alias_handle,
|
||||
uint16_t topic_alias, char *topic, size_t topic_len);
|
||||
@@ -505,25 +519,7 @@ static esp_err_t esp_mqtt5_user_property_copy(mqtt5_user_property_handle_t user_
|
||||
ESP_LOGE(TAG, "Input is NULL");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
mqtt5_user_property_item_t old_item, new_item;
|
||||
STAILQ_FOREACH(old_item, user_property_old, next) {
|
||||
new_item = calloc(1, sizeof(mqtt5_user_property_t));
|
||||
ESP_MEM_CHECK(TAG, new_item, return ESP_FAIL);
|
||||
new_item->key = strdup(old_item->key);
|
||||
ESP_MEM_CHECK(TAG, new_item->key, {
|
||||
free(new_item);
|
||||
return ESP_FAIL;
|
||||
});
|
||||
new_item->value = strdup(old_item->value);
|
||||
ESP_MEM_CHECK(TAG, new_item->value, {
|
||||
free(new_item->key);
|
||||
free(new_item);
|
||||
return ESP_FAIL;
|
||||
});
|
||||
STAILQ_INSERT_TAIL(user_property_new, new_item, next);
|
||||
}
|
||||
return ESP_OK;
|
||||
return mqtt5_msg_copy_user_property(user_property_new, user_property_old);
|
||||
}
|
||||
|
||||
esp_err_t esp_mqtt5_client_set_publish_property(esp_mqtt5_client_handle_t client,
|
||||
@@ -688,17 +684,11 @@ esp_err_t esp_mqtt5_client_set_disconnect_property(esp_mqtt5_client_handle_t cli
|
||||
|
||||
if (property->user_property) {
|
||||
esp_mqtt5_client_delete_user_property(client->mqtt5_config->disconnect_property_info.user_property);
|
||||
/* False positive: the allocation remains owned by disconnect_property_info
|
||||
* until it is replaced or the MQTT 5 configuration is destroyed. */
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
|
||||
client->mqtt5_config->disconnect_property_info.user_property = calloc(1, sizeof(struct mqtt5_user_property_list_t));
|
||||
client->mqtt5_config->disconnect_property_info.user_property = mqtt5_msg_create_user_property_list();
|
||||
ESP_MEM_CHECK(TAG, client->mqtt5_config->disconnect_property_info.user_property, {
|
||||
MQTT_API_UNLOCK(client);
|
||||
return ESP_ERR_NO_MEM;
|
||||
});
|
||||
#pragma GCC diagnostic pop
|
||||
STAILQ_INIT(client->mqtt5_config->disconnect_property_info.user_property);
|
||||
|
||||
if (esp_mqtt5_user_property_copy(client->mqtt5_config->disconnect_property_info.user_property,
|
||||
property->user_property) != ESP_OK) {
|
||||
@@ -772,9 +762,8 @@ esp_err_t esp_mqtt5_client_set_connect_property(esp_mqtt5_client_handle_t client
|
||||
|
||||
if (connect_property->user_property) {
|
||||
esp_mqtt5_client_delete_user_property(client->mqtt5_config->connect_property_info.user_property);
|
||||
client->mqtt5_config->connect_property_info.user_property = calloc(1, sizeof(struct mqtt5_user_property_list_t));
|
||||
client->mqtt5_config->connect_property_info.user_property = mqtt5_msg_create_user_property_list();
|
||||
ESP_MEM_CHECK(TAG, client->mqtt5_config->connect_property_info.user_property, goto _mqtt_set_config_failed);
|
||||
STAILQ_INIT(client->mqtt5_config->connect_property_info.user_property);
|
||||
|
||||
if (esp_mqtt5_user_property_copy(client->mqtt5_config->connect_property_info.user_property,
|
||||
connect_property->user_property) != ESP_OK) {
|
||||
@@ -817,14 +806,8 @@ esp_err_t esp_mqtt5_client_set_connect_property(esp_mqtt5_client_handle_t client
|
||||
|
||||
if (connect_property->will_user_property) {
|
||||
esp_mqtt5_client_delete_user_property(client->mqtt5_config->will_property_info.user_property);
|
||||
/* False positive: esp_mqtt_destroy_config() releases this allocation on failure,
|
||||
* but the analyzer cannot follow that cleanup across the translation-unit boundary. */
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
|
||||
client->mqtt5_config->will_property_info.user_property = calloc(1, sizeof(struct mqtt5_user_property_list_t));
|
||||
client->mqtt5_config->will_property_info.user_property = mqtt5_msg_create_user_property_list();
|
||||
ESP_MEM_CHECK(TAG, client->mqtt5_config->will_property_info.user_property, goto _mqtt_set_config_failed);
|
||||
#pragma GCC diagnostic pop
|
||||
STAILQ_INIT(client->mqtt5_config->will_property_info.user_property);
|
||||
|
||||
if (esp_mqtt5_user_property_copy(client->mqtt5_config->will_property_info.user_property,
|
||||
connect_property->will_user_property) != ESP_OK) {
|
||||
@@ -842,7 +825,7 @@ _mqtt_set_config_failed:
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
esp_err_t esp_mqtt5_client_set_user_property(mqtt5_user_property_handle_t *user_property,
|
||||
esp_err_t esp_mqtt5_client_set_user_property(mqtt5_user_property_handle_t *user_property_list,
|
||||
esp_mqtt5_user_property_item_t item[], uint8_t item_num)
|
||||
{
|
||||
if (!item_num || !item) {
|
||||
@@ -850,124 +833,46 @@ esp_err_t esp_mqtt5_client_set_user_property(mqtt5_user_property_handle_t *user_
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
if (!*user_property) {
|
||||
*user_property = calloc(1, sizeof(struct mqtt5_user_property_list_t));
|
||||
ESP_MEM_CHECK(TAG, *user_property, return ESP_ERR_NO_MEM);
|
||||
STAILQ_INIT(*user_property);
|
||||
}
|
||||
|
||||
for (int i = 0; i < item_num; i ++) {
|
||||
if (item[i].key && item[i].value) {
|
||||
mqtt5_user_property_item_t user_property_item = calloc(1, sizeof(mqtt5_user_property_t));
|
||||
ESP_MEM_CHECK(TAG, user_property_item, goto err);
|
||||
size_t key_len = strlen(item[i].key);
|
||||
size_t value_len = strlen(item[i].value);
|
||||
user_property_item->key = calloc(1, key_len + 1);
|
||||
ESP_MEM_CHECK(TAG, user_property_item->key, {
|
||||
free(user_property_item);
|
||||
goto err;
|
||||
});
|
||||
memcpy(user_property_item->key, item[i].key, key_len);
|
||||
user_property_item->key[key_len] = '\0';
|
||||
user_property_item->value = calloc(1, value_len + 1);
|
||||
ESP_MEM_CHECK(TAG, user_property_item->value, {
|
||||
free(user_property_item->key);
|
||||
free(user_property_item);
|
||||
goto err;
|
||||
});
|
||||
memcpy(user_property_item->value, item[i].value, value_len);
|
||||
user_property_item->value[value_len] = '\0';
|
||||
STAILQ_INSERT_TAIL(*user_property, user_property_item, next);
|
||||
esp_err_t ret = mqtt5_msg_set_user_property(user_property_list, item[i].key, key_len, item[i].value,
|
||||
value_len);
|
||||
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to set user property");
|
||||
esp_mqtt5_client_delete_user_property(*user_property_list);
|
||||
*user_property_list = NULL;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
err:
|
||||
esp_mqtt5_client_delete_user_property(*user_property);
|
||||
*user_property = NULL;
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
|
||||
esp_err_t esp_mqtt5_client_get_user_property(mqtt5_user_property_handle_t user_property,
|
||||
esp_mqtt5_user_property_item_t *item, uint8_t *item_num)
|
||||
{
|
||||
int i = 0, j = 0;
|
||||
|
||||
if (user_property && item && *item_num) {
|
||||
mqtt5_user_property_item_t user_property_item;
|
||||
uint8_t num = *item_num;
|
||||
STAILQ_FOREACH(user_property_item, user_property, next) {
|
||||
if (i < num) {
|
||||
size_t item_key_len = strlen(user_property_item->key);
|
||||
size_t item_value_len = strlen(user_property_item->value);
|
||||
char *key = calloc(1, item_key_len + 1);
|
||||
ESP_MEM_CHECK(TAG, key, goto err);
|
||||
memcpy(key, user_property_item->key, item_key_len);
|
||||
key[item_key_len] = '\0';
|
||||
char *value = calloc(1, item_value_len + 1);
|
||||
ESP_MEM_CHECK(TAG, value, {
|
||||
free(key);
|
||||
goto err;
|
||||
});
|
||||
memcpy(value, user_property_item->value, item_value_len);
|
||||
value[item_value_len] = '\0';
|
||||
item[i].key = key;
|
||||
item[i].value = value;
|
||||
i ++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
*item_num = i;
|
||||
return ESP_OK;
|
||||
} else {
|
||||
if (!user_property || !item || !item_num || !*item_num) {
|
||||
ESP_LOGE(TAG, "Input value is NULL or item_num is 0");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
err:
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wcast-qual"
|
||||
|
||||
for (j = 0; j < i; j ++) {
|
||||
if (item[j].key) {
|
||||
free((char *)item[j].key);
|
||||
}
|
||||
|
||||
if (item[j].value) {
|
||||
free((char *)item[j].value);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
return ESP_ERR_NO_MEM;
|
||||
return mqtt5_msg_get_user_property(user_property, item, item_num);
|
||||
}
|
||||
|
||||
uint8_t esp_mqtt5_client_get_user_property_count(mqtt5_user_property_handle_t user_property)
|
||||
{
|
||||
uint8_t count = 0;
|
||||
|
||||
if (user_property) {
|
||||
mqtt5_user_property_item_t item;
|
||||
STAILQ_FOREACH(item, user_property, next) {
|
||||
count ++;
|
||||
}
|
||||
if (!user_property) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return count;
|
||||
return mqtt5_msg_get_user_property_count(user_property);
|
||||
}
|
||||
|
||||
void esp_mqtt5_client_delete_user_property(mqtt5_user_property_handle_t user_property)
|
||||
void esp_mqtt5_client_delete_user_property(mqtt5_user_property_handle_t user_property_list)
|
||||
{
|
||||
if (user_property) {
|
||||
mqtt5_user_property_item_t item, tmp;
|
||||
STAILQ_FOREACH_SAFE(item, user_property, next, tmp) {
|
||||
STAILQ_REMOVE(user_property, item, mqtt5_user_property, next);
|
||||
free(item->key);
|
||||
free(item->value);
|
||||
free(item);
|
||||
}
|
||||
}
|
||||
|
||||
free(user_property);
|
||||
mqtt5_msg_delete_user_property(user_property_list);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "esp_log.h"
|
||||
#include "esp_heap_caps.h"
|
||||
#include "esp_transport.h"
|
||||
#include "mqtt_config.h"
|
||||
#include "mqtt_client.h"
|
||||
#include "mqtt_client_priv.h"
|
||||
#include "mqtt_msg.h"
|
||||
|
||||
Reference in New Issue
Block a user