#include "user_http.h"
#include "wifi.h"
#include "ble.h"
+#include "esp_chip_info.h"
static const char *MAIN_TAG = "main";
// MAIN_LOOP
#define MAIN_LOOP_TASK_STACK (2*1024)
Mqtt_Send_Data();
#endif
// 在这里添加每秒执行的代码
- ESP_LOGI(MAIN_TAG, "onesec_timer: %" PRIu32 " bytes",esp_get_free_heap_size());
+ ESP_LOGI(MAIN_TAG, "onesec_timer:ota %d ota_cur_status %d %" PRIu32 " bytes",common_setting.https_ota_cfg.https_ota_start_flag,g_ota_status,esp_get_free_heap_size());
// 例如:检查状态、发送心跳等
}
// esp_log_level_set("outbox", ESP_LOG_VERBOSE);
ESP_LOGI(MAIN_TAG, "[APP] Free memory start: %" PRIu32 " bytes", esp_get_free_heap_size());
+ //chip info
+ esp_chip_info_t chip_info;
+ esp_chip_info(&chip_info);
+ ESP_LOGI(MAIN_TAG, "chip_name: %d chip_info.revision %d", chip_info.model,chip_info.revision);
+
/* Initialize NVS. */
esp_err_t ret;
ret = nvs_flash_init();
#if ENABLE_WIFI_FUNC
Wifi_Sta_Init();
vTaskDelay(1000);
+
+
+ #endif
+
+ #if ENABLE_HTTPS_OTA_FUNC
+ Https_Ota_Handler_Init();
+
#endif
+
+
+ // ESP_LOGI(MAIN_TAG, "chip_id:%s chip_version:%d\n",chip_info.model,chip_info.res);
//等待wifi稳定再去连接wifi
// ESP_LOGI(MAIN_TAG, "[APP] Free memory after wifi: %" PRIu32 " bytes", esp_get_free_heap_size());
#endif
#include "user_mqtt.h"
#if (ENABLE_HTTPS_OTA_FUNC)
-static const char *TAG = "OTA";
+static const char *HTTPS_OTA = "HTTPS_OTA";
#if CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
#include "esp_efuse.h"
#endif
#endif
#include "esp_crt_bundle.h"
+ota_status_t g_ota_status = OTA_STATUS_IDLE; // 全局OTA状态
+static uint8_t retry_ota_num = 0;
+static bool ota_full_failed_flag = false; // 新增:三次失败锁定标记
+#define HTTPS_OTA_RETRY_NUM 3
-#define OTA_URL_SIZE 256
+#define OTA_URL_SIZE 255
#define OTA_HTTP_OTA 0 //是否使用http请求ota固件包
#if OTA_HTTP_OTA
#define HTTPS_OTA_STACK_SIZE (8*1024)
static const char *https_ota_url ="http://pxn-iot.s3.us-east-2.amazonaws.com/iot01/2026/04/11/ssl_mutual_auth.bin";
#else
#define HTTPS_OTA_STACK_SIZE (4*1024)
-static const char *https_ota_url ="https://pxn-iot.s3.us-east-2.amazonaws.com/iot01/2026/04/11/ssl_mutual_auth.bin";
+char https_ota_url[OTA_URL_SIZE] = {0};
#endif
//使用http请求还需要 配置表 ESP_HTTPS_OTA_ALLOW_HTTP = y ESP_TLS_INSECURE=y ESP_TLS_SKIP_SERVER_CERT_VERIFY=y这三个都要打开
/* Event handler for catching system events */
const esp_partition_t *running = esp_ota_get_running_partition();
esp_app_desc_t running_app_info;
if (esp_ota_get_partition_description(running, &running_app_info) == ESP_OK) {
- ESP_LOGI(TAG, "Running firmware version: %s", running_app_info.version);
+ ESP_LOGI(HTTPS_OTA, "Running firmware version: %s", running_app_info.version);
}
- ESP_LOGI(TAG, "Running firmware version: %s new_app_info->version:%s", running_app_info.version,new_app_info->version);
+ ESP_LOGI(HTTPS_OTA, "Running firmware version: %s new_app_info->version:%s", running_app_info.version,new_app_info->version);
#if 1
if (memcmp(new_app_info->version, running_app_info.version, sizeof(new_app_info->version)) == 0) {
- ESP_LOGW(TAG, "Current running version is the same as a new. We will not continue the update.");
+ ESP_LOGW(HTTPS_OTA, "Current running version is the same as a new. We will not continue the update.");
return ESP_FAIL;
}
#endif
*/
const uint32_t hw_sec_version = esp_efuse_read_secure_version();
if (new_app_info->secure_version < hw_sec_version) {
- ESP_LOGW(TAG, "New firmware security version is less than eFuse programmed, %"PRIu32" < %"PRIu32, new_app_info->secure_version, hw_sec_version);
+ ESP_LOGW(HTTPS_OTA, "New firmware security version is less than eFuse programmed, %"PRIu32" < %"PRIu32, new_app_info->secure_version, hw_sec_version);
return ESP_FAIL;
}
#endif
}
//ota升级失败重复升级次数 连续三次都升级不成功不升级了
-static uint8_t retry_ota_num = 0;
-#define HTTPS_OTA_RETRY_NUM 4
+
static void https_ota_task_cb(void *pvParameter)
{
- ESP_LOGI(TAG, "Starting Advanced OTA example");
+ Mqtt_Disconnect(); // 关闭MQTTs
+ // 2. 延迟一下确保资源释放
+ vTaskDelay(200 / portTICK_PERIOD_MS);
+ ESP_LOGI(HTTPS_OTA, "Starting Advanced OTA example:%s\n",https_ota_url);
+ g_ota_status = OTA_STATUS_UPGRADING; // 标记升级开始
esp_err_t ota_finish_err = ESP_OK;
esp_http_client_config_t config = {
.url = https_ota_url,
esp_https_ota_handle_t https_ota_handle = NULL;
esp_err_t err = esp_https_ota_begin(&ota_config, &https_ota_handle);
if (err != ESP_OK) {
- ESP_LOGI(TAG, "ESP HTTPS OTA Begin failed");
- xEventGroupSetBits(common_event_group, COMMON_HTTPS_OTA_BIT);
- vTaskDelete(NULL);
+ ESP_LOGI(HTTPS_OTA, "ESP HTTPS OTA Begin failed");
+ g_ota_status = OTA_STATUS_FAILED; // ←失败
+ goto ota_end;
+ // vTaskDelete(NULL);
}else{
- ESP_LOGI(TAG, "ESP HTTPS OTA Begin success");
+ ESP_LOGI(HTTPS_OTA, "ESP HTTPS OTA Begin success");
}
esp_app_desc_t app_desc;
err = esp_https_ota_get_img_desc(https_ota_handle, &app_desc);
if (err != ESP_OK) {
- ESP_LOGI(TAG, "esp_https_ota_get_img_desc failed");
+ ESP_LOGI(HTTPS_OTA, "esp_https_ota_get_img_desc failed");
+ g_ota_status = OTA_STATUS_FAILED; // ← 失败
goto ota_end;
}
err = validate_image_header(&app_desc);
if (err != ESP_OK) {
- ESP_LOGI(TAG, "image header verification failed");
+ ESP_LOGI(HTTPS_OTA, "image header verification failed");
+ g_ota_status = OTA_STATUS_FAILED; // ← 失败
goto ota_end;
}else{
- ESP_LOGI(TAG, "image header verification success");
+ ESP_LOGI(HTTPS_OTA, "image header verification success");
}
while (1) {
err = esp_https_ota_perform(https_ota_handle);
if (err != ESP_ERR_HTTPS_OTA_IN_PROGRESS) {
- ESP_LOGI(TAG, "Image err: %d",err);
+ ESP_LOGI(HTTPS_OTA, "Image err: %d",err);
break;
}
// esp_https_ota_perform returns after every read operation which gives user the ability to
// monitor the status of OTA upgrade by calling esp_https_ota_get_image_len_read, which gives length of image
// data read so far.
- ESP_LOGI(TAG, "Image bytes read: %d", esp_https_ota_get_image_len_read(https_ota_handle));
+ ESP_LOGI(HTTPS_OTA, "Image bytes read: %d", esp_https_ota_get_image_len_read(https_ota_handle));
}
if (esp_https_ota_is_complete_data_received(https_ota_handle) != true) {
// the OTA image was not completely received and user can customise the response to this situation.
- ESP_LOGI(TAG, "Complete data was not received. continue ota %d",common_setting.wifi_status.wifi_state);
-
- vTaskDelay(50 / portTICK_PERIOD_MS);
- if(common_setting.wifi_status.wifi_state == 0)
- {
- retry_ota_num=0;
- common_setting.https_ota_cfg.https_ota_start_flag=0;
- }else{
- xEventGroupSetBits(common_event_group, COMMON_HTTPS_OTA_BIT);
- }
-
- vTaskDelete(NULL);
+ ESP_LOGI(HTTPS_OTA, "Complete data was not received. continue ota %d",common_setting.wifi_status.wifi_state);
+ g_ota_status = OTA_STATUS_FAILED; // ← 失败
+ // vTaskDelay(50 / portTICK_PERIOD_MS);
+ // if(common_setting.wifi_status.wifi_state == 0)
+ // {
+ // retry_ota_num=0;
+ // common_setting.https_ota_cfg.https_ota_start_flag=0;
+ // }else{
+ // xEventGroupSetBits(common_event_group, COMMON_HTTPS_OTA_BIT);
+ // }
+ goto ota_end;
+ // vTaskDelete(NULL);
} else {
ota_finish_err = esp_https_ota_finish(https_ota_handle);
if ((err == ESP_OK) && (ota_finish_err == ESP_OK)) {
- ESP_LOGI(TAG, "ESP_HTTPS_OTA upgrade successful. Rebooting ...");
- vTaskDelay(1000 / portTICK_PERIOD_MS);
- esp_restart();
+ ESP_LOGI(HTTPS_OTA, "ESP_HTTPS_OTA upgrade successful. Rebooting ...");
+ g_ota_status = OTA_STATUS_SUCCESS; //成功
+
} else {
if (ota_finish_err == ESP_ERR_OTA_VALIDATE_FAILED) {
- ESP_LOGI(TAG, "Image validation failed, image is corrupted");
+ ESP_LOGI(HTTPS_OTA, "Image validation failed, image is corrupted");
}
- ESP_LOGI(TAG, "ESP_HTTPS_OTA upgrade failed 0x%x", ota_finish_err);
- vTaskDelay(50 / portTICK_PERIOD_MS);
- xEventGroupSetBits(common_event_group, COMMON_HTTPS_OTA_BIT);
- vTaskDelete(NULL);
+ ESP_LOGI(HTTPS_OTA, "ESP_HTTPS_OTA upgrade failed 0x%x", ota_finish_err);
+ // vTaskDelay(50 / portTICK_PERIOD_MS);
+ // xEventGroupSetBits(common_event_group, COMMON_HTTPS_OTA_BIT);
+ g_ota_status = OTA_STATUS_FAILED; // ← 失败
+ // vTaskDelete(NULL);
+ goto ota_end;
}
}
ota_end:
- ESP_LOGI(TAG, "ESP_HTTPS_OTA upgrade u11");
- xEventGroupSetBits(common_event_group, COMMON_HTTPS_OTA_BIT);
+ // xEventGroupSetBits(common_event_group, COMMON_HTTPS_OTA_BIT);
+ // esp_https_ota_abort(https_ota_handle);
+ // vTaskDelete(NULL);
+
esp_https_ota_abort(https_ota_handle);
- ESP_LOGI(TAG, "ESP_HTTPS_OTA upgrade failed");
+ //网络断开不在继续升级
+ if (retry_ota_num >= HTTPS_OTA_RETRY_NUM || common_setting.wifi_status.wifi_state == 0) {
+ ota_full_failed_flag = true;
+ common_setting.https_ota_cfg.https_ota_start_flag = 0;
+ ESP_LOGE(HTTPS_OTA, "OTA retry %d failed!", HTTPS_OTA_RETRY_NUM);
+ xEventGroupSetBits(common_event_group, COMMON_MQTT_CONNECT_BIT);//连接mqtt
+ } else {
+ ESP_LOGW(HTTPS_OTA, "OTA faile retry(%d/%d)", retry_ota_num + 1, HTTPS_OTA_RETRY_NUM);
+ xEventGroupSetBits(common_event_group, COMMON_HTTPS_OTA_BIT);
+ }
+
vTaskDelete(NULL);
}
return 1;
}
-static uint8_t https_ota_close_fun_flag = 0; //ota升级的时候之关闭一次ble ,mqtt
void https_ota_start(void)
{
- https_ota_close_fun_flag=0;
+ if(g_ota_status != 0 && common_setting.https_ota_cfg.https_ota_start_flag == 1)
+ {
+ ESP_LOGI(HTTPS_OTA, "ota is started\n");
+ return;
+ }
+ ESP_LOGI(HTTPS_OTA, "ota is start\n");
retry_ota_num=0;
+ ota_full_failed_flag = false; // 新OTA任务,清空三次失败锁
+ common_setting.https_ota_cfg.https_ota_start_flag = 1;
xEventGroupSetBits(common_event_group, COMMON_HTTPS_OTA_BIT);
}
-//https_ota 需要关闭ble mqtt
-void https_ota_close_ble_mqtt(void)
+
+void https_ota_stop(void)
{
- if(https_ota_close_fun_flag == 1)
+ ESP_LOGI(HTTPS_OTA, "ota is stop\n");
+ retry_ota_num=0;
+ ota_full_failed_flag = false; //
+ common_setting.https_ota_cfg.https_ota_start_flag = 0;
+ xEventGroupSetBits(common_event_group, COMMON_MQTT_CONNECT_BIT);
+}
+
+void https_ota_task(void)
+{
+ if(ota_full_failed_flag)
{
+ common_setting.https_ota_cfg.https_ota_start_flag=0;
return;
}
- https_ota_close_fun_flag=1;
- //关闭蓝牙
- xEventGroupSetBits(ble_event_group, BLE_OFF_BIT);
- vTaskDelay(1000);
- //关闭mqtt
- xEventGroupSetBits(common_event_group, COMMON_MQTT_DISCONNECT_BIT);
- vTaskDelay(1000);
-}
-void https_ota_task(void)
-{
retry_ota_num++;
- if(retry_ota_num > HTTPS_OTA_RETRY_NUM){
+ if(retry_ota_num > HTTPS_OTA_RETRY_NUM){ //重试三次ota升级失败后不再升级 后续要重连mqtt
common_setting.https_ota_cfg.https_ota_start_flag=0;
retry_ota_num=0;
+ xEventGroupSetBits(common_event_group, COMMON_MQTT_CONNECT_BIT);//连接mqtt
return;
}
BaseType_t ret = xTaskCreate(&https_ota_task_cb, "https_ota_task", HTTPS_OTA_STACK_SIZE, NULL, 4, NULL);
if(ret !=pdPASS )
{
xEventGroupSetBits(common_event_group, COMMON_HTTPS_OTA_BIT);
- ESP_LOGI(TAG, "ESP_HTTPS_OTA https_ota_task failed\n");
+ ESP_LOGI(HTTPS_OTA, "task failed\n");
}else{
- ESP_LOGI(TAG, "ESP_HTTPS_OTA https_ota_task success\n");
+ ESP_LOGI(HTTPS_OTA, "task success\n");
}
}
+// wifi事件处理函数 断开 连接 获取ip等事件都会进入这个函数
+static void ota_event_handler(void* arg, esp_event_base_t event_base,
+ int32_t event_id, void* event_data)
+{
+ // ESP_LOGE(WIFI_TAG, "event_handler %" PRId32 "\n", event_id);
+ if (event_base == ESP_HTTPS_OTA_EVENT) {
+ switch (event_id) {
+ case ESP_HTTPS_OTA_START:
+ ESP_LOGI(HTTPS_OTA, "OTA started");
+ g_ota_status = OTA_STATUS_UPGRADING;
+ break;
+ case ESP_HTTPS_OTA_CONNECTED:
+ ESP_LOGI(HTTPS_OTA, "Connected to server");
+ break;
+ case ESP_HTTPS_OTA_GET_IMG_DESC:
+ ESP_LOGI(HTTPS_OTA, "Reading Image Description");
+ break;
+ case ESP_HTTPS_OTA_VERIFY_CHIP_ID:
+ ESP_LOGI(HTTPS_OTA, "Verifying chip id of new image: %d", *(esp_chip_id_t *)event_data);
+ break;
+ case ESP_HTTPS_OTA_DECRYPT_CB:
+ ESP_LOGI(HTTPS_OTA, "Callback to decrypt function");
+ break;
+ case ESP_HTTPS_OTA_WRITE_FLASH:
+ // ESP_LOGI(HTTPS_OTA, "Writing to flash: %d written", *(int *)event_data);
+ break;
+ case ESP_HTTPS_OTA_UPDATE_BOOT_PARTITION:
+ ESP_LOGI(HTTPS_OTA, "Boot partition updated. Next Partition: %d", *(esp_partition_subtype_t *)event_data);
+ break;
+ case ESP_HTTPS_OTA_FINISH:
+ g_ota_status = OTA_STATUS_SUCCESS;
+ ESP_LOGI(HTTPS_OTA, "OTA finish");
+ break;
+ case ESP_HTTPS_OTA_ABORT:
+ g_ota_status = OTA_STATUS_FAILED;
+ ESP_LOGI(HTTPS_OTA, "OTA abort");
+ break;
+ }
+ }
+
+}
+
+void Https_Ota_Handler_Init(void)
+{
+ ESP_ERROR_CHECK(esp_event_handler_register(ESP_HTTPS_OTA_EVENT, ESP_EVENT_ANY_ID, &ota_event_handler, NULL));
+}
void Https_Ota_Status_Check(void)
{
if((xEventGroupWaitBits(common_event_group, COMMON_HTTPS_OTA_BIT, pdFALSE, pdFALSE, 0) & COMMON_HTTPS_OTA_BIT) != 0 && common_setting.ble_status.ble_state == 0 \
vTaskDelay(50 / portTICK_PERIOD_MS);
https_ota_task();
}
+ if(g_ota_status == OTA_STATUS_SUCCESS)
+ {
+ esp_restart();
+ }
}
#endif
#ifndef _HTTPS_OTA_H_
#define _HTTPS_OTA_H_
-#define ENABLE_HTTPS_OTA_FUNC 0 //是否开启HTTPS_OTA升级
+#define ENABLE_HTTPS_OTA_FUNC 1 //是否开启HTTPS_OTA升级
#if ENABLE_HTTPS_OTA_FUNC
#include <stdint.h>
#include <stdbool.h>
+
+// OTA 升级状态枚举
+typedef enum {
+ OTA_STATUS_IDLE = 0, // 空闲
+ OTA_STATUS_UPGRADING = 1, // 升级中
+ OTA_STATUS_SUCCESS = 2, // 升级成功
+ OTA_STATUS_FAILED = 3, // 升级失败
+} ota_status_t;
+
+extern ota_status_t g_ota_status;
+
void https_ota_task(void);
void Https_Ota_Status_Check(void);
uint8_t https_ota_version_check(void);
void https_ota_start(void);
void https_ota_close_ble_mqtt(void);
+void Https_Ota_Handler_Init(void);
+void https_ota_stop(void);
+extern char https_ota_url[255];
#endif
#endif
\ No newline at end of file
*chip_len=len;
memcpy(chip_id,chip_name,strlen(chip_name));
// 最终清晰打印
- ESP_LOGI(CHIP_LOG, "chip_name: %s", chip_name);
+ ESP_LOGI(CHIP_LOG, "chip_name: %s chip_info.revision %d", chip_name,chip_info.revision);
+}
+
+void print_chip_info(void)
+{
+ // 定义 + 获取芯片信息
+ esp_chip_info_t chip_info;
+ esp_chip_info(&chip_info);
+
+ // 打印型号(数字 → 转成文字)
+ char *chip_name = "Unknown";
+ switch(chip_info.model) {
+
+ case CHIP_ESP32C2: chip_name = "ESP32-C2"; break;
+ default:
+ break;
+ }
+ ESP_LOGI(CHIP_LOG, "chip_name: %s chip_info.revision %d", chip_name,chip_info.revision);
}
\ No newline at end of file
void network_request_replay(uint8_t status);
void get_chip_info(char *chip_id,uint8_t *chip_len);
-
+void print_chip_info(void);
#endif
//0X04-0X05保留
- COMMON_UART_PROPERTY_SET_CMD = 0x06,//属性上报
- COMMON_UART_PROPERTY_REPORT_CMD = 0x07,//属性设置
+ COMMON_UART_PROPERTY_SET_CMD = 0x06,//属性设置
+ COMMON_UART_PROPERTY_REPORT_CMD = 0x07,// 属性上报
COMMON_UART_PROPERTY_ALL_QUERY_CMD = 0x08,//属性全部查询
COMMON_UART_PROPERTY_BATCH_REPORT_CMD = 0x09,//属性批量查询
COMMON_UART_GET_MAC_ADDR_CMD = 0X0A,//获取模组MAC地址
//寻找分区表
partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, PARA_FLASH_NAME);
assert(partition != NULL);
- User_Erase_Nimble_NetWork_Infor();
+ // User_Erase_Nimble_NetWork_Infor();
//读取flash数据到common_storage
if(User_Flash_Read_Check(UF_OFFSET_USER_CONFIG_INFO_ADDR, UF_OFFSET_USER_CONFIG_INFO_FLAG, &common_storage.net_info, sizeof(NET_INFO_T)) != ESP_OK)
#endif
ESP_LOGI(HTTP_TAG, "download mqtt \n");
common_setting.mqtt_user_cfg.mqtt_start_flag=1;
- #if ENABLE_HTTPS_OTA_FUNC
- xEventGroupSetBits(common_event_group, COMMON_HTTPS_OTA_BIT);
- #endif
xEventGroupSetBits(common_event_group, COMMON_MQTT_CONNECT_BIT);
}else{
//失败
#include "user_mqtt.h"
#include "https_ota.h"
+#include "user_flash.h"
#include "cJSON.h"
+#include "esp_chip_info.h"
#if ENABLE_MQTT_FUNC
static const char *MQTT_TAG = "MQTT";
snprintf(vid_str, sizeof(vid_str), "%04X", common_setting.mcu_info.vid);
// 获取芯片型号
- uint8_t chip_len = 0;
- get_chip_info(wifi_soc, &chip_len);
- if (chip_len == 0) {
- strcpy(wifi_soc, "Unknown");
+ // get_chip_info(wifi_soc, &chip_len);
+ esp_chip_info_t chip_info;
+ esp_chip_info(&chip_info);
+
+ // 打印型号(数字 → 转成文字)
+ char *chip_name = "Unknown";
+ switch(chip_info.model) {
+
+ case CHIP_ESP32C2: chip_name = "ESP32-C2"; break;
+ case CHIP_ESP32 : chip_name = "ESP32"; break;//!< ESP32
+ case CHIP_ESP32S2: chip_name = "ESP32-S2"; break; //!< ESP32-S2
+ case CHIP_ESP32S3: chip_name = "ESP32-S3"; break; //!< ESP32-S3
+ case CHIP_ESP32C3: chip_name = "ESP32-C3"; break; //!< ESP32-C3
+ case CHIP_ESP32C6: chip_name = "ESP32-C6"; break; //!< ESP32-C6
+ case CHIP_ESP32H2 : chip_name = "ESP32-H2"; break; //!< ESP32-H2
+ case CHIP_ESP32P4: chip_name = "ESP32-P4"; break; //!< ESP32-P4
+ case CHIP_ESP32C61: chip_name = "ESP32-C61"; break; //!< ESP32-C61
+ case CHIP_ESP32C5: chip_name = "ESP32-C5"; break; //!< ESP32-C5
+ case CHIP_ESP32H21: chip_name = "ESP32-H21"; break; //!< ESP32-H21
+ case CHIP_ESP32H4: chip_name = "ESP32-H4"; break; //!< ESP32-H4
+ case CHIP_POSIX_LINUX: chip_name = "POSIX_LINUX";break; //!< The code is running on POSIX/Linux simulator
+ default:
+ break;
}
+ strcpy(wifi_soc, chip_name);
+
// 版本号格式化 0x0015 → V0021
char fw_ver[8] = {0}, wifi_ver[8] = {0};
snprintf(fw_ver, sizeof(fw_ver), "%04u", common_setting.mcu_info.fw_version);
snprintf(wifi_ver, sizeof(wifi_ver), "%04u", (unsigned int)FW_VERSION);
if(FW_VERSION > 9999)
{
-
snprintf(wifi_ver, sizeof(wifi_ver), "%s","9999");
}
// ===================== 构建正确的 JSON =====================
}
//断开wifi连接同时断开mqtt连接 释放mqtt资源
-void Mqtt_Force_Stop(void)
+void Mqtt_Disconnect(void)
{
- if(mqtt_init_flag && common_setting.mqtt_client_handle != NULL && (common_setting.mqtt_user_cfg.mqtt_start_flag == 1 || \
+ if(mqtt_init_flag == 1&& common_setting.mqtt_client_handle != NULL && (common_setting.mqtt_user_cfg.mqtt_start_flag == 1 || \
common_setting.wifi_status.connect_mode == 3))
{
ESP_LOGW(MQTT_TAG, "MQTT STOP");
}
}
+// 解析 MQTT 下发的 JSON 数据
+// 是否是纯数字
+bool is_pure_number(const char *str)
+{
+ //
+ if (str == NULL || *str == '\0') {
+ return false;
+ }
+
+ //
+ while (*str != '\0') {
+ if (!isdigit((unsigned char)*str)) {
+ return false;
+ }
+ str++;
+ }
+ return true;
+}
+static void mqtt_parse_recv_data(char *data, int data_len)
+{
+ // 安全判断
+ if (data == NULL || data_len <= 0 || data_len > MQTT_DATA_BUF_SIZE) {
+ ESP_LOGW(MQTT_TAG, "parese too len:%d\n",data_len);
+ return;
+ }
+
+ // ========== cJSON 解析(安全版)==========
+ cJSON *root = cJSON_Parse(data);
+ if (root == NULL) {
+ ESP_LOGW(MQTT_TAG, "JSON error");
+ return;
+ }
+
+ // otareset ====================
+ //{"productId":"A00B","productName":"WGTL方向盘","otareset":1} otareset
+
+ cJSON *productId = cJSON_GetObjectItem(root, "productId");//清除配网标识字符串 int
+ if (productId != NULL && cJSON_IsString(productId)) {
+
+ char cur_pid[6]={0};
+ snprintf(cur_pid,sizeof(cur_pid)-1,"%04X",common_setting.mcu_info.pid);
+ ESP_LOGI(MQTT_TAG, "productId: %s %s\n", productId->valuestring,cur_pid);
+ if (strcasecmp(cur_pid, cur_pid) != 0) {//和当前PID不一致
+ return;
+ }
+
+ }
+
+ // 示例 1:解析字符串类型
+ //===========清除配网指令=========================//
+ cJSON *reset = cJSON_GetObjectItem(root, "otareset");//清除配网标识字符串 int
+ if (reset != NULL && cJSON_IsNumber(reset)) {
+ ESP_LOGI(MQTT_TAG, "otareset: %d", reset->valueint);
+ int otareset = 0;
+ otareset = reset->valueint;
+ if(otareset == 1)
+ {
+ //1.清除flash
+ //2.重启设备
+ User_Erase_Nimble_NetWork_Infor();
+ vTaskDelay(pdMS_TO_TICKS(100));
+ esp_restart();//重启模组
+ }
+ }
+
+ // 示例 2:
+ //ota
+ //{"firmwareId":25,"firmwareName":"wgtl","productId":"A00B","productName":"WGTL方向盘",
+ //"tenantId":1,"tenantName":"13714325636","isLatest":1,"version":1.0,
+ //"filePath":"https://pxn-iot.s3.us-east-2.amazonaws.com/iot01/2026/04/20/69e589eb7a67c1057c3d452e.bin"}
+ //========OTA 升级文件key=====================//
+ cJSON *filePath = cJSON_GetObjectItem(root, "filePath");
+ if (filePath != NULL && cJSON_IsString(filePath)) {
+ //开启ota线程
+ const char *ota_url = filePath->valuestring;
+ // static const char *filePath="https://pxn-iot.s3.us-east-2.amazonaws.com/iot01/2026/04/27/69ef076479113dba3ec8e375.bin";//https://pxn-iot.s3.us-east-2.amazonaws.com/iot01/2026/04/20/69e589eb7a67c1057c3d452e.bin";
+ uint8_t filePath_Len = 0;
+ if(sizeof(ota_url) > sizeof(https_ota_url)-1)
+ {
+ filePath_Len = sizeof(https_ota_url)-1;
+ }
+ else{
+ filePath_Len = strlen(ota_url);
+ }
+ memcpy(https_ota_url,ota_url,filePath_Len);
+ https_ota_url[filePath_Len] = '\0';
+ ESP_LOGI(MQTT_TAG, "ota_url:%s", https_ota_url);
+ https_ota_start();
+
+ }
+
+ //
+ //灯光
+ //{"productId":"A00B","productName":"WGTL方向盘","prot":[{"736":"50"},{"737":"89"},{"738":"90"}]}
+ //for()
+ //payload = 255-4;固定四个字节 其余是dpid数据格式 dpid (2)+type(1)+len(2)+数据()
+ // {
+ // }
+ // 示例 3:设备属性行解析
+ cJSON *prot_array = cJSON_GetObjectItem(root, "prot");
+ if (prot_array != NULL || cJSON_IsArray(prot_array)) {
+
+ int prot_array_size = cJSON_GetArraySize(prot_array);
+ if(prot_array_size == 0)
+ {
+ return;
+ }
+ //
+ uint8_t type = 1;
+ uint16_t total_data_len = 0;
+ uint16_t dpid = 0;
+ int value = 0;
+ int type_len = 0;
+ uint8_t send_data[UART_REPLY_MAX_PAYLOAD];
+ memset(send_data,0,UART_REPLY_MAX_PAYLOAD);
+ ESP_LOGI(MQTT_TAG,"prot_array_size:%d",prot_array_size);
+ for (int i = 0; i < prot_array_size; i++)
+ {
+ // 取数组第i个元素(是一个对象)
+ cJSON *pro_item = cJSON_GetArrayItem(prot_array, i);
+ if (pro_item == NULL || !cJSON_IsObject(pro_item)) {
+ printf("%d不是对象\n", i);
+ continue;
+ }
+ // int dpid = atoi(dpid_str); // 字符串转整数DPID
+ // int value = atoi(key_node->valuestring); // 字符串转数值(如"50"→50)
+ cJSON *item = pro_item->child;
+ if (item == NULL) continue;
+
+ const char *key_str = item->string;
+ dpid=0;
+ type=1;
+ type_len = 1;
+ if(cJSON_IsString(item) && item->valuestring != NULL && key_str != NULL) //如果是字符串是不定长度 长度为
+ {
+ type = 5;
+ type_len= strlen(item->valuestring);
+ if(type_len == 0) //内容是空的
+ {
+ continue;
+ }
+ if (is_pure_number(key_str))
+ {
+ dpid = atoi(key_str);
+ ESP_LOGI(MQTT_TAG,"dpid %u\n",dpid);
+ }else{
+ ESP_LOGI(MQTT_TAG,"dpid is zero\n");
+ continue;
+ }
+
+ }else if(cJSON_IsNumber(item) || (cJSON_IsBool(item)))
+ {
+ type = 1;
+ if(item->string == NULL) //KEY 为空 如果是数字不需要判断value是为空
+ {
+ continue;
+ }
+ // 1. KEY 必须纯数字
+ if (is_pure_number(key_str) ) {
+ value = item->valueint;//atoi(item->valuestring); //item->valueint;
+ dpid = atoi(key_str);
+ if(value <= 0xff)
+ {
+ type = 1;
+ type_len = 1;
+ }else if(value <= 0xffff)
+ {
+ type = 2;
+ type_len = 2;
+ }else if(value <= 0xffffffff)
+ {
+ type = 4;
+ type_len = 4;
+ }
+ ESP_LOGI(MQTT_TAG,"dpid %u value:%u\n",dpid,value);
+ }else{
+ ESP_LOGI(MQTT_TAG,"is number but dpid is zero\n");
+ continue;
+ }
+
+ }
+ if(dpid <= 0)
+ {
+ ESP_LOGI(MQTT_TAG,"dpid is invale\n");
+ continue;
+ }
+ //总的长度加上4+当前数据类型的长度
+ if(total_data_len + 4 + type_len > UART_REPLY_MAX_PAYLOAD-4)
+ {
+ Uart_Reply_Send(COMMON_UART_PROPERTY_SET_CMD,send_data, total_data_len,HOST_TYPE_UART);
+ type_len = 0;
+ total_data_len=0;
+ memset(send_data,0,UART_REPLY_MAX_PAYLOAD);
+
+ }
+ // 737 10 738 50 739 70
+ // total_data_len = 0 0 1 2 3 4 5
+ // total_data_len = 0+5+1=6 6 7 8 9 10 11
+ // total_data_len = 6+6=12 12 13 14 15 16 17
+ // total_data_len =
+ // F1 06 12 00 00 00 00 00 00 00 00 00 00 00 00 E1 02 01 01 00 28 D0
+
+ send_data[total_data_len+0] = dpid & 0xff;
+ send_data[total_data_len+1] = (dpid >> 8 )&0xff;
+ send_data[total_data_len+2] = type;//类型
+ send_data[total_data_len+3] = type_len & 0xff;
+ send_data[total_data_len+4] = (type_len >> 8)& 0xff;
+ if(type != 5) //不是字符串 copy数字
+ {
+ memcpy(&send_data[total_data_len+5],&value,type_len);
+ }else{ //copy字符串
+ snprintf((char *)&send_data[total_data_len+5],type_len,"%s",item->valuestring);
+ // memcpy((char *)&send_data[total_data_len+5],item->valuestring,type_len);
+ }
+
+ total_data_len=total_data_len+5+type_len;
+ ESP_LOGI(MQTT_TAG,"i:%d total_data_len:%d dpid:%u value:%u type:%d type_len:%u\n",i,total_data_len,dpid,value,type,type_len);
+ if(i == prot_array_size - 1)//到最后一个发送
+ {
+ Uart_Reply_Send(COMMON_UART_PROPERTY_SET_CMD,send_data, total_data_len,HOST_TYPE_UART);
+ type_len = 0;
+ total_data_len=0;
+ memset(send_data,0,UART_REPLY_MAX_PAYLOAD);
+ }
+ }
+ }
+ // 释放!!!
+ cJSON_Delete(root);
+}
static void Mqtt_Init_Task_Cb(void *p)
{
mqtt_recv_msg_t recv_msg;
ESP_LOGI(MQTT_TAG, "mqtt recv data");
ESP_LOGI(MQTT_TAG, "主题:%.*s", recv_msg.topic_len, recv_msg.topic);
ESP_LOGI(MQTT_TAG, "数据:%.*s", recv_msg.data_len, recv_msg.data);
-
+ mqtt_parse_recv_data(recv_msg.data,recv_msg.data_len);
// =============================================
// 1. JSON 解析
// MQTT 接收消息结构体
typedef struct {
char topic[MQTT_TOPIC_LEN+1]; // 主题
- uint8_t data[MQTT_DATA_BUF_SIZE+1]; // 数据
+ char data[MQTT_DATA_BUF_SIZE+1]; // 数据
uint8_t topic_len; // 主题长度
uint16_t data_len; // 数据长度
} mqtt_recv_msg_t;
void Mqtt_Send_Data(void);
void Mqtt_Recv_Data(char *topic,int topic_len,char *data,int data_len);
void Mqtt_Init_Task(void);
-void Mqtt_Force_Stop(void);
+void Mqtt_Disconnect(void);
void Mqtt_Get_Key_Led_Color(uint8_t *color_data,uint16_t color_len);
void Mqtt_Send_Mcu_Info(void);
uint8_t Mqtt_Get_Connect_Flag(void);
case WIFI_EVENT_STA_DISCONNECTED:
{
#if ENABLE_MQTT_FUNC
- Mqtt_Force_Stop();
+ Mqtt_Disconnect();
#endif
wifi_event_sta_disconnected_t* disconnected = (wifi_event_sta_disconnected_t*) event_data;
ESP_LOGE(WIFI_TAG, "Disconnect reason : %d", disconnected->reason);
break;
}
}
- else if (event_base == ESP_HTTPS_OTA_EVENT) {
- switch (event_id) {
- case ESP_HTTPS_OTA_START:
- ESP_LOGI(WIFI_TAG, "OTA started");
- break;
- case ESP_HTTPS_OTA_CONNECTED:
- ESP_LOGI(WIFI_TAG, "Connected to server");
- break;
- case ESP_HTTPS_OTA_GET_IMG_DESC:
- ESP_LOGI(WIFI_TAG, "Reading Image Description");
- break;
- case ESP_HTTPS_OTA_VERIFY_CHIP_ID:
- ESP_LOGI(WIFI_TAG, "Verifying chip id of new image: %d", *(esp_chip_id_t *)event_data);
- break;
- case ESP_HTTPS_OTA_DECRYPT_CB:
- ESP_LOGI(WIFI_TAG, "Callback to decrypt function");
- break;
- case ESP_HTTPS_OTA_WRITE_FLASH:
- // ESP_LOGI(WIFI_TAG, "Writing to flash: %d written", *(int *)event_data);
- break;
- case ESP_HTTPS_OTA_UPDATE_BOOT_PARTITION:
- ESP_LOGI(WIFI_TAG, "Boot partition updated. Next Partition: %d", *(esp_partition_subtype_t *)event_data);
- break;
- case ESP_HTTPS_OTA_FINISH:
- ESP_LOGI(WIFI_TAG, "OTA finish");
- break;
- case ESP_HTTPS_OTA_ABORT:
- ESP_LOGI(WIFI_TAG, "OTA abort");
- break;
- }
- }
+
}
void Wifi_Sta_Init(void)
NULL,
&instance_got_ip));
- ESP_ERROR_CHECK(esp_event_handler_register(ESP_HTTPS_OTA_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
+
ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_BSS_RSSI_LOW, &esp_bss_rssi_low_handler, NULL));
#
# Chip revision
#
-CONFIG_ESP32C2_REV_MIN_1=y
+# CONFIG_ESP32C2_REV_MIN_1 is not set
# CONFIG_ESP32C2_REV_MIN_1_1 is not set
-# CONFIG_ESP32C2_REV_MIN_200 is not set
-CONFIG_ESP32C2_REV_MIN_FULL=100
-CONFIG_ESP_REV_MIN_FULL=100
+CONFIG_ESP32C2_REV_MIN_200=y
+CONFIG_ESP32C2_REV_MIN_FULL=200
+CONFIG_ESP_REV_MIN_FULL=200
#
# Maximum Supported ESP32-C2 Revision (Rev v2.99)