-
Notifications
You must be signed in to change notification settings - Fork 7.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MQTT unsubscribe function with subscribe function of problem (IDFGH-13427) #14333
Comments
I created a new project and ported the code over and found that when I send a publish message on a subscribe event it reproduces the issue 100%, as long as I don't publish the message there is no problem. https://github.com/espressif/esp-idf/blob/master/examples/protocols/mqtt/tcp/main/app_main.c As soon as the comment switch is turned on, the above problem is reproduced/*
* @brief Event handler registered to receive MQTT events
*
* This function is called by the MQTT client event loop.
*
* @param handler_args user data registered to the event.
* @param base Event base for the handler(always MQTT Base in this example).
* @param event_id The id for the received event.
* @param event_data The data for the event, esp_mqtt_event_handle_t.
*/
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%" PRIi32 "", base, event_id);
esp_mqtt_event_handle_t event = event_data;
esp_mqtt_client_handle_t client = event->client;
int msg_id = 0;
char devInfo[128] = {0};
switch ((esp_mqtt_event_id_t)event_id)
{
case MQTT_EVENT_CONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
// 连接后先解除订阅貌似会导致一些预料以外的结果
msg_id = esp_mqtt_client_unsubscribe(client, TITLE_UPDATA_REPLY);
msg_id = esp_mqtt_client_unsubscribe(client, UART_TFT_STRINGS_SUB);
msg_id = esp_mqtt_client_subscribe(client, TITLE_UPDATA_REPLY, 2);
msg_id = esp_mqtt_client_subscribe(client, UART_TFT_STRINGS_SUB, 2);
break;
case MQTT_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
break;
case MQTT_EVENT_SUBSCRIBED:
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
#if 0
msg_id = esp_mqtt_client_publish(client,
TITLE_UPDATA,
sub_deviceTiltlePadding(devInfo, sizeof(devInfo),
NULL, 0),
0,
2,
0);
printf("sent: %s\r\n", devInfo);
printf("--1--\r\n");
#if 0
msg_id = esp_mqtt_client_publish(client,
UART_TFT_STRINGS_PUB,
"\"hello\"",
0,
2,
0);
#endif
#if 0
printf("--2--\r\n");
msg_id = esp_mqtt_client_publish(client,
USER_UPDATE_PUB,
" ",
0,
2,
0);
printf("--3--\r\n");
#endif
#endif
break;
case MQTT_EVENT_UNSUBSCRIBED:
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_PUBLISHED:
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_DATA:
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
printf("--5--\r\n");
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
printf("DATA=%.*s\r\n", event->data_len, event->data);
printf("--6--\r\n");
memset(MQTT_topicRecive, 0, sizeof(MQTT_topicRecive));
UserStrcat(MQTT_topicRecive, event->topic, event->topic_len, 0U);
printf("--7--\r\n");
memset(MQTT_dataRecive, 0, sizeof(MQTT_dataRecive));
UserStrcat(MQTT_dataRecive, event->data, event->data_len, 0U);
printf("--8--\r\n");
break;
case MQTT_EVENT_ERROR:
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT)
{
log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);
log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);
log_error_if_nonzero("captured as transport's socket errno", event->error_handle->esp_transport_sock_errno);
ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));
}
break;
case MQTT_EVENT_BEFORE_CONNECT:
ESP_LOGI(TAG, "MQTT_EVENT_BEFORE_CONNECT");
break;
default:
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
break;
}
printf("--4--\r\n");
} |
Used an unexpected way to solve the problem, but still wanted an explanation. static void mqttSUB_task(void *arg)
{
int msg_id = 0;
char devInfo[128] = {0};
vTaskDelay(1);
#if 1
msg_id = esp_mqtt_client_publish((esp_mqtt_client_handle_t)arg,
TITLE_UPDATA,
sub_deviceTiltlePadding(devInfo, sizeof(devInfo),
NULL, 0),
0,
2,
0);
printf("sent: %s\r\n", devInfo);
printf("--1--\r\n");
#if 0
msg_id = esp_mqtt_client_publish(client,
UART_TFT_STRINGS_PUB,
"\"hello\"",
0,
2,
0);
#endif
#if 1
printf("--2--\r\n");
msg_id = esp_mqtt_client_publish((esp_mqtt_client_handle_t)arg,
USER_UPDATE_PUB,
" ",
0,
2,
0);
printf("--3--\r\n");
#endif
#endif
vTaskDelete(NULL);
}
/*
* @brief Event handler registered to receive MQTT events
*
* This function is called by the MQTT client event loop.
*
* @param handler_args user data registered to the event.
* @param base Event base for the handler(always MQTT Base in this example).
* @param event_id The id for the received event.
* @param event_data The data for the event, esp_mqtt_event_handle_t.
*/
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%" PRIi32 "", base, event_id);
esp_mqtt_event_handle_t event = event_data;
esp_mqtt_client_handle_t client = event->client;
int msg_id = 0;
switch ((esp_mqtt_event_id_t)event_id)
{
case MQTT_EVENT_CONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
// 连接后先解除订阅貌似会导致一些预料以外的结果
msg_id = esp_mqtt_client_unsubscribe(client, TITLE_UPDATA_REPLY);
msg_id = esp_mqtt_client_unsubscribe(client, UART_TFT_STRINGS_SUB);
msg_id = esp_mqtt_client_subscribe(client, TITLE_UPDATA_REPLY, 2);
msg_id = esp_mqtt_client_subscribe(client, UART_TFT_STRINGS_SUB, 2);
break;
case MQTT_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
break;
case MQTT_EVENT_SUBSCRIBED:
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
#if 1 // 不能直接在触发订阅主题的事件里发布多个topic消息, 故此创建了任务延时发布
xTaskCreatePinnedToCore(mqttSUB_task,
"main_task",
1024 * 2,
client,
configMAX_PRIORITIES - 10,
NULL,
0);
#endif
#if 0
msg_id = esp_mqtt_client_publish(client,
TITLE_UPDATA,
sub_deviceTiltlePadding(devInfo, sizeof(devInfo),
NULL, 0),
0,
2,
0);
printf("sent: %s\r\n", devInfo);
printf("--1--\r\n");
#if 0
msg_id = esp_mqtt_client_publish(client,
UART_TFT_STRINGS_PUB,
"\"hello\"",
0,
2,
0);
#endif
#if 0
printf("--2--\r\n");
msg_id = esp_mqtt_client_publish(client,
USER_UPDATE_PUB,
" ",
0,
2,
0);
printf("--3--\r\n");
#endif
#endif
break;
case MQTT_EVENT_UNSUBSCRIBED:
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_PUBLISHED:
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_DATA:
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
// 只有在接收的时候topic才不为空
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
printf("DATA=%.*s\r\n", event->data_len, event->data);
memset(MQTT_topicRecive, 0, sizeof(MQTT_topicRecive));
UserStrcat(MQTT_topicRecive, event->topic, event->topic_len, 0U);
memset(MQTT_dataRecive, 0, sizeof(MQTT_dataRecive));
UserStrcat(MQTT_dataRecive, event->data, event->data_len, 0U);
break;
case MQTT_EVENT_ERROR:
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT)
{
log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);
log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);
log_error_if_nonzero("captured as transport's socket errno", event->error_handle->esp_transport_sock_errno);
ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));
}
break;
case MQTT_EVENT_BEFORE_CONNECT:
ESP_LOGI(TAG, "MQTT_EVENT_BEFORE_CONNECT");
break;
default:
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
break;
}
printf("--4--\r\n");
} |
Maybe you're using too much of |
A double exception is an exception that happens while handling a previous exception. I've had that happen to me once, and the issue was a buffer overrun of a global array that turned out to have been sized insufficiently. I suggest you look into that, considering you decided to roll out your own JSON construction and strcat implementations. |
@PING020903 thanks for reporting. I've run the steps you suggested using the mqtt client example and the fixed topic and publish data, and it works just fine. From the logs the problem is not in unsubscribe/subscribe, but in the handling of the SUBSCRIBED event in the publish call. If you can provide a topic + data that reproduces it, I will be glad to give it a try to identify if we have some issue in the mqtt client. |
Here is my code, thanks. |
Hi @PING020903 thanks for the code. |
You just need to enable the commented code to reproduce the problem without using the task of |
@PING020903 I understand that. But I need to have code that does not use your function |
I know, as you can see in my picture, I just used a personal topic and the fixed strings. |
From the shared code, I was only able to reproduce the issue when the function |
I don't think there's anything wrong with my function. #include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "esp_event.h"
#include "mqtt_client.h"
#include "User_string.h"
#include "User_SNTP.h"
#include "TestMQTT.h"
#define CONFIG_BROKER_URL_FROM_STDIN 0
#define MQTTS_PROTOCOL "mqtts://"
#define MQTT_PROTOCOL "mqtt://"
#define TIME_STR_MAX_LEN (32)
/* MQTT Base Topic (基础通信) */
#define DEVICE_NAME "WJP_esp32"
#define PRODUCT_KEY "k1mopgbwe56"
#define DEVICE_TITLE "/" PRODUCT_KEY "/" DEVICE_NAME "/thing/deviceinfo" // 设备标签信息
#define TITLE_UPDATA "/sys" DEVICE_TITLE "/update" // 设备标签更新
#define TITLE_UPDATA_REPLY "/sys" DEVICE_TITLE "/update_reply" // 设备标签更新订阅
#define TITLE_DELETE "" DEVICE_TITLE "/delete"
#define TITLE_DELETE_REPLY "" DEVICE_TITLE "/delete_reply"
#define TITLE_ID "\"id\":"
#define TITLE_ID_LEN (5)
#define TITLE_VERSION "\"version\":"
#define TITLE_VERSION_LEN (10)
#define TITLE_SYS "\"sys\":"
#define TITLE_SYS_LEN (6)
#define DEVICE_STATUS "/as/mqtt/status/" PRODUCT_KEY "/" DEVICE_NAME ""
#define UART_TFT_STRINGS_SUB "/" PRODUCT_KEY "/" DEVICE_NAME "/user/uartTFTsringsSUB"
#define UART_TFT_STRINGS_PUB "/" PRODUCT_KEY "/" DEVICE_NAME "/user/uartTFTsringsPUB"
#define USER_UPDATE_PUB "/" PRODUCT_KEY "/" DEVICE_NAME "/user/update"
#define INFO_STATUS "\"status\""
#define INFO_STATUS_LEN (8)
#define INFO_IOTID "\"iotid\""
#define INFO_IOTID_LEN (7)
#define INFO_PRODUCTKEY "\"productKey\""
#define INFO_PRODUCTKEY_LEN (12)
#define INFO_DEVICENAME "\"deviceName\""
#define INFO_DEVICENAME_LEN (12)
#define INFO_TIME "\"time\""
#define INFO_TIME_LEN (6)
#define INFO_UTCTIME "\"utcTime\""
#define INFO_UTCTIME_LEN (9)
#define INFO_LASTTIME "\"lastTime\""
#define INFO_LASTTIME_LEN (10)
#define INFO_UTCLASTTIME "\"utcLastTime\""
#define INFO_UTCLASTTIME_LEN (13)
#define INFO_CLIENTIP "\"clientIp\""
#define INFO_CLIENTIP_LEN (10)
#define DATA_NULL "\r\n"
#define DATA_NULL_LEN (2)
#define ONLINE_STATUS "\"online\""
#define ONLINE_STATUS_LEN (8)
#define OFFLINE_STATUS "\"offline\""
#define OFFLINE_STATUS_LEN (9)
static const char *TAG = "TestMQTT";
static char *localIp = "120.230.164.69"; // 公网出口IP
static char MQTT_topicRecive[128] = {0}; // DATA_EVENT topic接收
static char MQTT_dataRecive[1024] = {0}; // DATA_EVENT data接收
static char devInfo[128] = {0};
/// @brief 获取设备信息数据格式的长度
/// @param
/// @return LEN:获取到的数据长度
size_t AllInfoLen_online(void)
{
char time[] = "\"2018-08-31 15:32:28.195\"";
char utctime[] = "\"2018-08-31T07:32:28.195Z\"";
char iotID[] = "\"4z819VQHk6VSLmmBJfrf00107e****\"";
char clientIP[] = "\"192.168.111.111\"";
size_t semicolons = 0, double_quote = 0;
size_t len = strlen(INFO_STATUS);
len += strlen(ONLINE_STATUS);
semicolons++;
len += strlen(INFO_IOTID);
len += strlen(iotID);
semicolons++;
len += strlen(INFO_PRODUCTKEY);
len += strlen(PRODUCT_KEY);
double_quote += 2;
semicolons++;
len += strlen(INFO_DEVICENAME);
len += strlen(DEVICE_NAME);
double_quote += 2;
semicolons++;
len += strlen(INFO_TIME);
len += strlen(INFO_UTCTIME);
semicolons++;
len += strlen(INFO_LASTTIME);
len += strlen(INFO_UTCLASTTIME);
semicolons++;
len += (strlen(time) * 2);
len += (strlen(utctime) * 2);
len += strlen(INFO_CLIENTIP);
len += strlen(clientIP);
return len + semicolons + double_quote;
}
/// @brief 设备信息填充
/// @param mqttDeviceInfo 要被填充的字符串
/// @param len 字符串长度
/// @return STRINGS:填充后的字符串
/// @note 不可将标准POSIX函数strcat频繁调用, 需用自定义的strcat
char *deviceInfoPadding(char *mqttDeviceInfo, const size_t len)
{
size_t pos = 0, ch_len = 0;
ch_len = AllInfoLen_online();
if (mqttDeviceInfo == NULL || len < ch_len)
{
return NULL;
}
char timeStr[TIME_STR_MAX_LEN] = {0};
wait_time:
if (!getTimeData_ready()) // 等待SNTP更新时间
{
vTaskDelay(1);
goto wait_time;
}
mqttDeviceInfo[pos++] = '{';
UserStrcat(mqttDeviceInfo, INFO_STATUS, INFO_STATUS_LEN, pos);
pos += INFO_STATUS_LEN;
mqttDeviceInfo[pos++] = ':';
UserStrcat(mqttDeviceInfo, ONLINE_STATUS, ONLINE_STATUS_LEN, pos);
pos += ONLINE_STATUS_LEN;
mqttDeviceInfo[pos++] = ',';
UserStrcat(mqttDeviceInfo, INFO_IOTID, INFO_IOTID_LEN, pos);
pos += INFO_IOTID_LEN;
mqttDeviceInfo[pos++] = ':';
UserStrcat(mqttDeviceInfo, DATA_NULL, DATA_NULL_LEN, pos);
pos += DATA_NULL_LEN;
mqttDeviceInfo[pos++] = ',';
UserStrcat(mqttDeviceInfo, INFO_PRODUCTKEY, INFO_PRODUCTKEY_LEN, pos);
pos += INFO_PRODUCTKEY_LEN;
mqttDeviceInfo[pos++] = ':';
mqttDeviceInfo[pos++] = '\"';
UserStrcat(mqttDeviceInfo, PRODUCT_KEY, strlen(PRODUCT_KEY), pos);
pos += strlen(PRODUCT_KEY);
mqttDeviceInfo[pos++] = '\"';
mqttDeviceInfo[pos++] = ',';
UserStrcat(mqttDeviceInfo, INFO_DEVICENAME, INFO_DEVICENAME_LEN, pos);
pos += INFO_DEVICENAME_LEN;
mqttDeviceInfo[pos++] = ':';
mqttDeviceInfo[pos++] = '\"';
UserStrcat(mqttDeviceInfo, DEVICE_NAME, strlen(DEVICE_NAME), pos);
pos += strlen(DEVICE_NAME);
mqttDeviceInfo[pos++] = '\"';
mqttDeviceInfo[pos++] = ',';
UserStrcat(mqttDeviceInfo, INFO_TIME, INFO_TIME_LEN, pos);
pos += INFO_TIME_LEN;
mqttDeviceInfo[pos++] = ':';
UserStrcat(mqttDeviceInfo,
User_tmToStrings(8, timeStr, TIME_STR_MAX_LEN),
TIME_STR_MAX_LEN,
pos);
pos += strlen(timeStr);
mqttDeviceInfo[pos++] = ',';
UserStrcat(mqttDeviceInfo, INFO_UTCTIME, INFO_UTCTIME_LEN, pos);
pos += INFO_UTCTIME_LEN;
mqttDeviceInfo[pos++] = ':';
UserStrcat(mqttDeviceInfo,
User_tmToStrings(0, timeStr, TIME_STR_MAX_LEN),
TIME_STR_MAX_LEN,
pos);
pos += strlen(timeStr);
mqttDeviceInfo[pos++] = ',';
UserStrcat(mqttDeviceInfo, INFO_CLIENTIP, INFO_CLIENTIP_LEN, pos);
pos += INFO_CLIENTIP_LEN;
mqttDeviceInfo[pos++] = ':';
mqttDeviceInfo[pos++] = '\"';
UserStrcat(mqttDeviceInfo, localIp, strlen(localIp), pos);
pos += strlen(localIp);
mqttDeviceInfo[pos++] = '\"';
mqttDeviceInfo[pos++] = '}';
return mqttDeviceInfo;
}
/// @brief 订阅设备标签字符串填充
/// @param str 传入字符串指针
/// @param len 字符串长度( 没有上传的data时应不少于128bytes, 否则会越界访问 )
/// @param upLoadData 要上传的data
/// @param dataLen 要上传的data长度
/// @return STRINGS:填充好的字符串
char *sub_deviceTiltlePadding(char *str, size_t len, char *upLoadData, size_t dataLen)
{
if (str == NULL || len == 0)
{
ESP_LOGE(TAG, "%s Incorrect pointer or length (add)%p (len)%u", __func__, str, len);
return str;
}
char time_str[TIME_STR_MAX_LEN] = {0};
size_t pos = 0;
str[pos++] = '{';
UserStrcat(str, TITLE_ID, TITLE_ID_LEN, pos);
pos += TITLE_ID_LEN;
UserStrcat(str, "\"111\"", strlen("\"111\""), pos);
pos += strlen("\"111\"");
str[pos++] = ',';
UserStrcat(str, TITLE_VERSION, TITLE_VERSION_LEN, pos);
pos += TITLE_VERSION_LEN;
UserStrcat(str, "\"1.0\"", strlen("\"1.0\""), pos);
pos += strlen("\"1.0\"");
str[pos++] = ',';
UserStrcat(str, TITLE_SYS, TITLE_SYS_LEN, pos);
pos += TITLE_SYS_LEN;
str[pos++] = '{';
// 此处放置要上传的数据
UserStrcat(str, "\"ack\"", strlen("\"ack\""), pos);
pos += strlen("\"ack\"");
str[pos++] = ':';
str[pos++] = '0';
str[pos++] = '}';
str[pos++] = ',';
UserStrcat(str, "\"params\":", strlen("\"params\":"), pos);
pos += strlen("\"params\":");
str[pos++] = '[';
str[pos++] = '{';
UserStrcat(str, "\"attrKey\":", strlen("\"attrKey\":"), pos);
pos += strlen("\"attrKey\":");
UserStrcat(str, "\"localTime\"", strlen("\"localTime\""), pos);
pos += strlen("\"localTime\""); // "attrKey": "localTime"
UserStrcat(str, "\"attrValue\":", strlen("\"attrValue\":"), pos);
pos += strlen("\"attrValue\":");
UserStrcat(str, User_tmToStrings(8, time_str, sizeof(time_str)), strlen(time_str), pos);
pos += strlen(time_str); // "attrValue": "yyyy-mm-dd hh:mm:ss.ms"
str[pos++] = '}';
str[pos++] = ']';
str[pos++] = ',';
UserStrcat(str, "\"method\":", strlen("\"method\":"), pos);
pos += strlen("\"method\":");
UserStrcat(str, "\"thing.deviceinfo.update\":", strlen("\"thing.deviceinfo.update\":"), pos);
pos += strlen("\"thing.deviceinfo.update\"");
str[pos++] = '}';
return str;
}
static void log_error_if_nonzero(const char *message, int error_code)
{
if (error_code != 0)
{
ESP_LOGE(TAG, "Last error %s: 0x%x", message, error_code);
}
}
#if 0
static void mqttSUB_task(void *arg)
{
int msg_id = 0;
char devInfo[128] = {0};
vTaskDelay(1);
#if 1
msg_id = esp_mqtt_client_publish((esp_mqtt_client_handle_t)arg,
TITLE_UPDATA,
sub_deviceTiltlePadding(devInfo, sizeof(devInfo),
NULL, 0),
0,
2,
0);
printf("sent: %s\r\n", devInfo);
printf("--1--\r\n");
#if 0
msg_id = esp_mqtt_client_publish(client,
UART_TFT_STRINGS_PUB,
"\"hello\"",
0,
2,
0);
#endif
#if 1
printf("--2--\r\n");
msg_id = esp_mqtt_client_publish((esp_mqtt_client_handle_t)arg,
USER_UPDATE_PUB,
" ",
0,
2,
0);
printf("--3--\r\n");
#endif
#endif
vTaskDelete(NULL);
}
#endif
/*
* @brief Event handler registered to receive MQTT events
*
* This function is called by the MQTT client event loop.
*
* @param handler_args user data registered to the event.
* @param base Event base for the handler(always MQTT Base in this example).
* @param event_id The id for the received event.
* @param event_data The data for the event, esp_mqtt_event_handle_t.
*/
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
{
ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%" PRIi32 "", base, event_id);
esp_mqtt_event_handle_t event = event_data;
esp_mqtt_client_handle_t client = event->client;
int msg_id = 0;
memset(devInfo, 0, sizeof(devInfo));
sub_deviceTiltlePadding(devInfo, sizeof(devInfo), NULL, 0);
printf("%s\r\n", devInfo);
switch ((esp_mqtt_event_id_t)event_id)
{
case MQTT_EVENT_CONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
// 连接后先解除订阅貌似会导致一些预料以外的结果
msg_id = esp_mqtt_client_unsubscribe(client, TITLE_UPDATA_REPLY);
msg_id = esp_mqtt_client_unsubscribe(client, UART_TFT_STRINGS_SUB);
msg_id = esp_mqtt_client_subscribe(client, TITLE_UPDATA_REPLY, 2);
msg_id = esp_mqtt_client_subscribe(client, UART_TFT_STRINGS_SUB, 2);
break;
case MQTT_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
break;
case MQTT_EVENT_SUBSCRIBED:
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
#if 0 // 不能直接在触发订阅主题的事件里订阅多个topic, 故此创建了任务延时发布
xTaskCreatePinnedToCore(mqttSUB_task,
"main_task",
1024 * 2,
client,
configMAX_PRIORITIES - 10,
NULL,
0);
#endif
#if 1
msg_id = esp_mqtt_client_publish(client,
TITLE_UPDATA,
devInfo,
0,
2,
0);
printf("sent: %s\r\n", devInfo);
printf("--1--\r\n");
#endif
#if 0
msg_id = esp_mqtt_client_publish(client,
UART_TFT_STRINGS_PUB,
"\"hello\"",
0,
2,
0);
#endif
#if 0
printf("--2--\r\n");
msg_id = esp_mqtt_client_publish(client,
USER_UPDATE_PUB,
" ",
0,
2,
0);
printf("--3--\r\n");
#endif
break;
case MQTT_EVENT_UNSUBSCRIBED:
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_PUBLISHED:
ESP_LOGI(TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_DATA:
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
// 只有在接收的时候topic才不为空
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
printf("DATA=%.*s\r\n", event->data_len, event->data);
memset(MQTT_topicRecive, 0, sizeof(MQTT_topicRecive));
UserStrcat(MQTT_topicRecive, event->topic, event->topic_len, 0U);
memset(MQTT_dataRecive, 0, sizeof(MQTT_dataRecive));
UserStrcat(MQTT_dataRecive, event->data, event->data_len, 0U);
break;
case MQTT_EVENT_ERROR:
ESP_LOGI(TAG, "MQTT_EVENT_ERROR");
if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT)
{
log_error_if_nonzero("reported from esp-tls", event->error_handle->esp_tls_last_esp_err);
log_error_if_nonzero("reported from tls stack", event->error_handle->esp_tls_stack_err);
log_error_if_nonzero("captured as transport's socket errno", event->error_handle->esp_transport_sock_errno);
ESP_LOGI(TAG, "Last errno string (%s)", strerror(event->error_handle->esp_transport_sock_errno));
}
break;
case MQTT_EVENT_BEFORE_CONNECT:
ESP_LOGI(TAG, "MQTT_EVENT_BEFORE_CONNECT");
break;
default:
ESP_LOGI(TAG, "Other event id:%d", event->event_id);
break;
}
printf("--4--\r\n");
}
/// @brief MQTT客户端初始化
/// @param
void mqtt_client_init(void)
{
/*
{"
{"clientId":"k1mopgbwe56.WJP_esp32|securemode=2,signmethod=hmacsha256,timestamp=1722877509058|",
"username":"WJP_esp32&k1mopgbwe56",
"mqttHostUrl":"iot-06z00doqpm9whvw.mqtt.iothub.aliyuncs.com",
"passwd":"0002f264787d9e8766f4a65d413c51add4324324d46bf05953e0b9c725d6b2b6",
"port":1883}
*/
// ps: 每次在服务器web端点击"MQTT连接参数"都会导致password&clientId改变,所以每次都需要重新初始化
esp_mqtt_client_config_t mqtt_cfg = {
.broker.verification.use_global_ca_store = 0,
.broker.verification.skip_cert_common_name_check = 0,
.broker.address.uri = "" MQTT_PROTOCOL "iot-06z00doqpm9whvw.mqtt.iothub.aliyuncs.com",
.broker.address.port = 1883,
.credentials.username = "WJP_esp32&k1mopgbwe56",
.credentials.client_id = "k1mopgbwe56.WJP_esp32|securemode=2,signmethod=hmacsha256,timestamp=1722877509058|",
.credentials.authentication.use_secure_element = 0,
.credentials.authentication.password = "0002f264787d9e8766f4a65d413c51add4324324d46bf05953e0b9c725d6b2b6",
.session.disable_keepalive = 0,
.session.disable_clean_session = 0,
};
#if CONFIG_BROKER_URL_FROM_STDIN
char line[128];
if (strcmp(mqtt_cfg.broker.address.uri, "FROM_STDIN") == 0)
{
int count = 0;
printf("Please enter url of mqtt broker\n");
while (count < 128)
{
int c = fgetc(stdin);
if (c == '\n')
{
line[count] = '\0';
break;
}
else if (c > 0 && c < 127)
{
line[count] = c;
++count;
}
vTaskDelay(10 / portTICK_PERIOD_MS);
}
mqtt_cfg.broker.address.uri = line;
printf("Broker url: %s\n", line);
}
else
{
ESP_LOGE(TAG, "Configuration mismatch: wrong broker url");
abort();
}
#endif /* CONFIG_BROKER_URL_FROM_STDIN */
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
/* The last argument may be used to pass data to the event handler, in this example mqtt_event_handler */
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL);
size_t ret = esp_mqtt_client_start(client);
if (ret == ESP_FAIL)
return;
// char tempStr[512] = {0};
// ESP_LOGI(TAG, "deviceInfo:\n%s", deviceInfoPadding(tempStr, sizeof(tempStr)));
}
/// @brief topic对比处理
/// @param
/// @return 返回topic所对应的值
/// @return ZERO: 0, null
/// @return ONE: 1, TITLE_UPDATA_REPLY
/// @return THREE: 2, UART_TFT_STRINGS_SUB
int topic_handle(void)
{
char *ret_point = NULL;
ret_point = strstr(MQTT_topicRecive, TITLE_UPDATA_REPLY);
if (ret_point != NULL)
return 1;
ret_point = strstr(MQTT_topicRecive, UART_TFT_STRINGS_SUB);
if (ret_point != NULL)
return 2;
return 0;
}
#if 0
/// @brief 根据topic列表值选择不同方式的数据处理
/// @param select topic列表中的值
/// @return
dataInfo_fromMQTT dataParse(const int select)
{
switch (select)
{
case 0:
return;
}
}
#endif
/// @brief 释放dataInfo_fromMQTT的字符串
/// @param data
/// @return OK:0
/// @return FAIL:
int free_userStr(dataInfo_fromMQTT data)
{
free(data.userStr);
return 0;
} Could it be that I created a variable that exceeded the default stack size? here is log
|
@PING020903 I'm closing this one, since I couldn't reproduce it showing that it is a problem in the MQTT client. |
Okay, thank you for your work.( ̄︶ ̄)↗ |
Answers checklist.
IDF version.
esp-idf-v5.1.2
Espressif SoC revision.
ESP-WROOM-32
Operating System used.
Windows
How did you build your project?
VS Code IDE
If you are using Windows, please specify command line type.
PowerShell
Development Kit.
ESP-WROVER-KIT 3.3V
Power Supply used.
USB
What is the expected behavior?
system will no reset, and Successful subscription.
What is the actual behavior?
It's still the same after many attempts
Until I commented out the functions
esp_mqtt_client_subscribe
andesp_mqtt_client_unsubscribe
I've tried building the project after clearing the files, but it doesn't work...
Steps to reproduce.
Debug Logs.
More Information.
there is my code of "mqtt_event_handle"
The text was updated successfully, but these errors were encountered: