1.解析ota报文
authord15521469561 <1731678236@qq.com>
Fri, 5 Jun 2026 02:53:01 +0000 (10:53 +0800)
committerd15521469561 <1731678236@qq.com>
Fri, 5 Jun 2026 02:53:01 +0000 (10:53 +0800)
2.优化ota升级
3.优化mqtt协议

15 files changed:
main/app_main.c
main/https_ota.c
main/https_ota.h
main/iap.c
main/n455_ota.c
main/n455_ota.h
main/project_common.c
main/project_common.h
main/uart.c
main/uart.h
main/user_flash.c
main/user_http.c
main/user_mqtt.c
main/user_mqtt.h
main/wifi.c

index ac1402c..05a8cd5 100644 (file)
@@ -56,24 +56,31 @@ static void onesec_timer_callback(void* arg)
     //     // set_system_time_int_from_utc(1779742628,"-3"); //1,779,753,428=2026-05-26 07:57:08 //转换成东八区是 2026-05-26 15:57:08
     // }
     
-    struct tm local_time = {0};
-    Get_Time(&local_time);
-
+    // struct tm local_time = {0};
+    // Get_Time(&local_time);
     #if ENABLE_HTTP_N455_OTA_FUNC
+    static uint8_t onesec_timer_count = 0;
+    if(onesec_timer_count < 65)
+    {
+        onesec_timer_count++;
+        if(onesec_timer_count == 20){
+            
+            // N455_Ota_Start();
+        }
+        
+    }
+    #endif
+    #if ENABLE_HTTPS_OTA_FUNC
     // static uint8_t onesec_timer_count = 0;
     // if(onesec_timer_count < 65)
     // {
     //     onesec_timer_count++;
-    //     if(onesec_timer_count % 10){
+    //     if(onesec_timer_count == 20){
             
-            // Uart_Reply_Send(COMMON_UART_BLE_CONNECT_STATUS,NULL,0,HOST_TYPE_UART);
-            // Https_Ota_Start();
-            // xEventGroupSetBits(common_event_group, COMMON_HTTPS_N455_OTA_BIT);
+    //         // xEventGroupSetBits(common_event_group, COMMON_HTTPS_OTA_BIT);
     //     }
         
     // }
-    #endif
-    #if ENABLE_HTTPS_OTA_FUNC
     //===========esp32 ota timeout=================//
     Https_Ota_Check_TimeOut();
     #endif
@@ -85,7 +92,7 @@ static void onesec_timer_callback(void* arg)
     //================mqtt is cnnect===========//
     // 在这里添加每秒执行的代码
     #if ENABLE_HTTPS_OTA_FUNC
-    ESP_LOGI(MAIN_TAG, "common_setting.ble_status.ble_state %d ota_cur_status %d %" PRIu32 " bytes",common_setting.ble_status.ble_state,g_ota_status,esp_get_free_heap_size());
+    ESP_LOGI(MAIN_TAG, "ble_state %d ota_cur_status %d %" PRIu32 " bytes",common_setting.ble_status.ble_state,g_ota_status,esp_get_free_heap_size());
     #else
     ESP_LOGI(MAIN_TAG, "onesec_timer:ota %d %" PRIu32 " bytes",common_setting.https_ota_cfg.https_ota_start_flag,esp_get_free_heap_size());
     #endif
index 8fdae04..e74c3f5 100644 (file)
@@ -28,25 +28,27 @@ static const char *HTTPS_OTA = "HTTPS_OTA";
 #endif
 #include "esp_crt_bundle.h"
 
-ota_status_t g_ota_status = OTA_STATUS_IDLE; // 全局OTA状态
+https_ota_status_t g_ota_status = HTTPS_OTA_STATUS_IDLE; // 全局OTA状态
 
-#define HTTPS_OTA_TIMEOUT_TIME  180//单位s
+#define HTTPS_OTA_TIMEOUT_TIME  150//单位s
 
 static volatile uint8_t ota_timeout_req = 0; //超时升级失败
 static volatile uint16_t ota_timeout_count = 0;
 
 static volatile uint16_t ota_faile_count  = 0;
 
+static uint8_t https_update_ota_flag = 0;
+
 static uint8_t https_ota_init = 0;
-#define HTTPS_OTA_RETRY_NUM  0
+#define HTTPS_OTA_RETRY_NUM  3
 
 #define OTA_URL_SIZE 128
 
 #define HTTPS_OTA_STACK_SIZE   (4*1024)
-static char https_ota_url[OTA_URL_SIZE] = "https://pxn-iot.s3.us-east-2.amazonaws.com/iot01/2026/05/22/6a0fb4324db40762648f18b3.bin";
+static char https_ota_url[OTA_URL_SIZE] = "https://pxn-iot.s3-accelerate.amazonaws.com/iot01/2026/06/02/6a1e460abfcb5bab677760e5.bin";//"https://pxn-iot.s3-accelerate.amazonaws.com/iot01/2026/06/02/6a1e460abfcb5bab677760e5.bin";//"https://pxn-iot.s3.us-east-2.amazonaws.com/iot01/2026/05/22/6a0fb4324db40762648f18b3.bin";
 /* Event handler for catching system events */
 /*
-FUNC:sdk原生自动版本校验 未使用
+ *函数功能:sdk原生自动版本校验 未使用
 */
 static esp_err_t validate_image_header(esp_app_desc_t *new_app_info)
 {
@@ -91,12 +93,12 @@ static esp_err_t _http_client_init_cb(esp_http_client_handle_t http_client)
     // err = esp_http_client_set_header(http_client, "Custom-Header", "Value");
     return err;
 }
-
-
+esp_https_ota_handle_t https_ota_handle = NULL;
+#if 0
 /*
 func:OTA升级回调函数
 */
-esp_https_ota_handle_t https_ota_handle = NULL;
+
 static void Https_Ota_Task_Cb(void *pvParameter)
 {
     ota_timeout_count = HTTPS_OTA_TIMEOUT_TIME;
@@ -106,15 +108,16 @@ static void Https_Ota_Task_Cb(void *pvParameter)
 
     https_ota_handle=NULL;
     ESP_LOGI(HTTPS_OTA, "Starting Advanced OTA example:%s\n",https_ota_url);
-    g_ota_status = OTA_STATUS_UPGRADING;  // 标记升级开始
+    g_ota_status = HTTPS_OTA_STATUS_UPGRADING;  // 标记升级开始
     Https_Ota_Report_Status(g_ota_status);
 
     vTaskDelay(100 / portTICK_PERIOD_MS);
     esp_err_t ota_finish_err = ESP_OK;
     esp_http_client_config_t config = {
         .url = https_ota_url,
-        .timeout_ms = 10000,
+        .timeout_ms = 5000,
         .keep_alive_enable = false,
+        
     };
 
     config.crt_bundle_attach = esp_crt_bundle_attach;//需要访问https一定要加这句
@@ -136,13 +139,15 @@ static void Https_Ota_Task_Cb(void *pvParameter)
         if(err == ESP_OK)
         {
             break;
+        }else{
+            ESP_LOGI(HTTPS_OTA, "esp_https_ota_begin failed, attempt %d", i+1);
         }
         vTaskDelay(500 / portTICK_PERIOD_MS);
     }
     if(err != ESP_OK)
     {   
         ESP_LOGI(HTTPS_OTA, "ESP HTTPS OTA Begin failed after 3 attempts");
-        g_ota_status = OTA_STATUS_FAILED;  // 
+        g_ota_status = HTTPS_OTA_STATUS_FAILED;  // 
         vTaskDelay(10 / portTICK_PERIOD_MS);
         goto ota_end;
     }
@@ -152,22 +157,21 @@ static void Https_Ota_Task_Cb(void *pvParameter)
     err = esp_https_ota_get_img_desc(https_ota_handle, &app_desc);
     if (err != ESP_OK) {
         ESP_LOGI(HTTPS_OTA, "esp_https_ota_get_img_desc failed");
-        g_ota_status = OTA_STATUS_FAILED;  // 
+        g_ota_status = HTTPS_OTA_STATUS_FAILED;  // 
         goto ota_end;
     }
     err = ESP_FAIL;
     err = validate_image_header(&app_desc);
     if (err != ESP_OK) {
         ESP_LOGI(HTTPS_OTA, "image header verification failed");
-        g_ota_status = OTA_STATUS_FAILED;  // 
+        g_ota_status = HTTPS_OTA_STATUS_FAILED;  // 
         goto ota_end;
     }else{
         ESP_LOGI(HTTPS_OTA, "image header verification success");
     }
     while (1) {
         if(ota_timeout_req){ //网络不好超时 设置上报状态创建任务失败;还在升级中就退出
-            ota_timeout_req=0;
-            g_ota_status = OTA_STATUS_FAILED;  // 也算是失败了 网络太差了升级超时了
+            g_ota_status = HTTPS_OTA_STATUS_FAILED;  // 也算是失败了 网络太差了升级超时了
             if(ota_timeout_count)
             {
                 ESP_LOGI(HTTPS_OTA, "user stop!!!!");
@@ -180,20 +184,33 @@ static void Https_Ota_Task_Cb(void *pvParameter)
         err = ESP_FAIL;
         err = esp_https_ota_perform(https_ota_handle);
         
-        if (err != ESP_ERR_HTTPS_OTA_IN_PROGRESS) {
-            ESP_LOGI(HTTPS_OTA, "Image err: %d",err);
-            break;
+        if (err == ESP_ERR_HTTPS_OTA_IN_PROGRESS) {
+            ESP_LOGI(HTTPS_OTA, "Image bytes read: %d ota_timeout_req:%d", esp_https_ota_get_image_len_read(https_ota_handle),ota_timeout_req);
+            if(ota_timeout_req){ //网络不好超时 设置上报状态创建任务失败;还在升级中就退出
+                g_ota_status = HTTPS_OTA_STATUS_FAILED;  // 也算是失败了 网络太差了升级超时了
+                if(ota_timeout_count)
+                {
+                    ESP_LOGI(HTTPS_OTA, "user stop!!!!");
+                }else{
+                    ESP_LOGI(HTTPS_OTA, "timeout!!!!");
+                }
+            
+                break;
+            }
+            
+            continue;
         }
+        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(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(HTTPS_OTA, "Complete data was not received. continue ota %d",common_setting.wifi_status.wifi_state);
-        g_ota_status = OTA_STATUS_FAILED;  // ← 失败
+        g_ota_status = HTTPS_OTA_STATUS_FAILED;  // ← 失败
 
         goto ota_end;
         // vTaskDelete(NULL);
@@ -201,15 +218,14 @@ static void Https_Ota_Task_Cb(void *pvParameter)
         ota_finish_err = esp_https_ota_finish(https_ota_handle);
         if ((err == ESP_OK) && (ota_finish_err == ESP_OK)) {
             ESP_LOGI(HTTPS_OTA, "ESP_HTTPS_OTA upgrade successful. Rebooting ...");
-            g_ota_status = OTA_STATUS_SUCCESS;  //成功
+            g_ota_status = HTTPS_OTA_STATUS_SUCCESS;  //成功
             ota_timeout_count=0;
             https_ota_handle = NULL;
             //成功不走下面失败的
             #if (!ENABLE_HTTP_N455_OTA_FUNC) //n455升级成功后上报状态 esp32升级成功后b不需要上报了 因为n455升级成功后会发一个特定的ack 包给esp32 esp32收到这个ack包就知道n455升级成功了 就不需要esp32再发一次mqtt消息上报了
             uint8_t ret = Https_Ota_Report_Status(g_ota_status);
             
-            g_ota_status = OTA_STATUS_IDLE;
-            common_setting.https_ota_cfg.https_ota_start_flag = 0;
+            g_ota_status = HTTPS_OTA_STATUS_IDLE;
             if(!ret)
             {
                 if(common_setting.wifi_status.wifi_state == 1){
@@ -224,7 +240,7 @@ static void Https_Ota_Task_Cb(void *pvParameter)
                 esp_err_t ret = esp_ota_mark_app_invalid_rollback();
                 ESP_LOGI(HTTPS_OTA, "esp32 restart: %d", ret);
                 ESP_LOGI(HTTPS_OTA, "455 task failed to start, rollback esp32");
-                Https_Ota_Report_Status(OTA_STATUS_FAILED); //上报标识 升级失败了
+                Https_Ota_Report_Status(HTTPS_OTA_STATUS_FAILED); //上报标识 升级失败了
                 Https_Ota_Clear_Upgrade_Flag();
                 xEventGroupSetBits(common_event_group, COMMON_MQTT_CONNECT_BIT);//
             }
@@ -235,21 +251,22 @@ static void Https_Ota_Task_Cb(void *pvParameter)
                 ESP_LOGI(HTTPS_OTA, "Image validation failed, image is corrupted");
             }
             ESP_LOGI(HTTPS_OTA, "ESP_HTTPS_OTA upgrade failed 0x%x", ota_finish_err);
-            g_ota_status = OTA_STATUS_FAILED;  // ← 失败
+            g_ota_status = HTTPS_OTA_STATUS_FAILED;  // ← 失败
             goto ota_end;
         }
     }
 
 ota_end:
 
-    if(https_ota_handle != NULL && g_ota_status != OTA_STATUS_SUCCESS){
+    if(https_ota_handle != NULL && g_ota_status != HTTPS_OTA_STATUS_SUCCESS){
         esp_https_ota_abort(https_ota_handle); //一定要在ota任务没有删除的时候调用 否则会死机 升级成功不能调用这个函数
         https_ota_handle = NULL;
     }
+    ota_timeout_req=0;
     ESP_LOGI(HTTPS_OTA, "ESP_HTTPS_OTA upgrade failed");
     ota_timeout_count=0;
      // (失败/超时 都在这里发)
-    Https_Ota_Report_Status(OTA_STATUS_FAILED);
+    Https_Ota_Report_Status(HTTPS_OTA_STATUS_FAILED);
     // 
     Https_Ota_Clear_Upgrade_Flag(); //清除升级标识
     if(common_setting.wifi_status.wifi_state == 1){
@@ -259,25 +276,202 @@ ota_end:
     // 删除
     vTaskDelete(NULL);
 }
+#else
+static void Https_Ota_Task_Cb(void *pvParameter)
+{
+    const int max_retry_times = 500;
+    
+    Mqtt_Disconnect();  // 关闭MQTTs
+    vTaskDelay(200 / portTICK_PERIOD_MS);
+
+    https_ota_handle=NULL;
+    ESP_LOGI(HTTPS_OTA, "Starting Advanced OTA example:%s\n",https_ota_url);
+    g_ota_status = HTTPS_OTA_STATUS_UPGRADING;
+    Https_Ota_Report_Status(g_ota_status);
+
+    vTaskDelay(100 / portTICK_PERIOD_MS);
+    esp_err_t ota_finish_err = ESP_OK;
+    bool ota_success = false;
+    const uint8_t MAX_RETRY = 3;
+    ota_timeout_count = HTTPS_OTA_TIMEOUT_TIME;
+    // for统一3次重试
+    for(uint8_t try_idx = 0; try_idx < MAX_RETRY; try_idx++)
+    {
+        ota_success = false;
+        ESP_LOGI(HTTPS_OTA,"==== OTA try %d/%d ====",try_idx+1,MAX_RETRY);
+        esp_http_client_config_t config = {
+            .url = https_ota_url,
+            .timeout_ms = 5000,
+            .keep_alive_enable = false,
+        };
+        config.crt_bundle_attach = esp_crt_bundle_attach;
+
+        esp_https_ota_config_t ota_config = {
+            .http_config = &config,
+            .http_client_init_cb = _http_client_init_cb,
+        };
+
+        esp_err_t err = ESP_FAIL;
+        // 先释放上一轮句柄
+        if (https_ota_handle != NULL)
+        {
+            esp_https_ota_abort(https_ota_handle);
+            https_ota_handle = NULL;
+        }
+        https_ota_handle = NULL;
+        err = esp_https_ota_begin(&ota_config, &https_ota_handle);
+        if(err != ESP_OK)
+        {
+            ESP_LOGI(HTTPS_OTA, "esp_https_ota_begin failed, try:%d", try_idx+1);
+            vTaskDelay(pdMS_TO_TICKS(max_retry_times));
+            continue;
+        }
+
+        err = ESP_FAIL;
+        esp_app_desc_t app_desc;
+        err = esp_https_ota_get_img_desc(https_ota_handle, &app_desc);
+        if (err != ESP_OK) {
+            ESP_LOGI(HTTPS_OTA, "esp_https_ota_get_img_desc failed");
+            vTaskDelay(pdMS_TO_TICKS(max_retry_times));
+            continue;
+        }
+        err = ESP_FAIL;
+        err = validate_image_header(&app_desc);
+        if (err != ESP_OK) {
+            ESP_LOGI(HTTPS_OTA, "image header verification failed");
+            vTaskDelay(pdMS_TO_TICKS(max_retry_times));
+            continue;
+        }else{
+            ESP_LOGI(HTTPS_OTA, "image header verification success");
+        }
+
+        // 下载循环
+        bool download_abort = false;
+        while (1) {
+            if(ota_timeout_req){
+
+                ESP_LOGI(HTTPS_OTA, "user timeout");
+                download_abort = true;
+                break;
+            }
+            err = esp_https_ota_perform(https_ota_handle);
+            if (err == ESP_ERR_HTTPS_OTA_IN_PROGRESS) {
+                ESP_LOGI(HTTPS_OTA, "Image bytes read: %d ota_timeout_req:%d", esp_https_ota_get_image_len_read(https_ota_handle),ota_timeout_req);
+                if(ota_timeout_req){
+                    ESP_LOGI(HTTPS_OTA, "user stop!!!!timeout!!!!");
+
+                    download_abort = true;
+                    break;
+                }
+                continue;
+            }
+            break;
+        }
+        if(download_abort){
+           break;
+        }
+
+        // 数据没收全
+        if (esp_https_ota_is_complete_data_received(https_ota_handle) != true) {
+            ESP_LOGI(HTTPS_OTA, "Complete data was not received. continue ota %d",common_setting.wifi_status.wifi_state);
+            vTaskDelay(pdMS_TO_TICKS(max_retry_times));
+            continue;
+        }
+
+        // 执行finish
+        ota_finish_err = esp_https_ota_finish(https_ota_handle);
+        if ((err == ESP_OK) && (ota_finish_err == ESP_OK)) {
+            ESP_LOGI(HTTPS_OTA, "ESP_HTTPS_OTA upgrade successful. Rebooting ...");
+            g_ota_status = HTTPS_OTA_STATUS_SUCCESS;
+            ota_timeout_count=0;
+            https_ota_handle = NULL;
+            ota_success = true;
+            break; //升级成功跳出for,不再重试
+        } else {
+            if (ota_finish_err == ESP_ERR_OTA_VALIDATE_FAILED) {
+                ESP_LOGI(HTTPS_OTA, "Image validation failed, image is corrupted");
+            }
+            ESP_LOGI(HTTPS_OTA, "ESP_HTTPS_OTA upgrade failed 0x%x", ota_finish_err);
+            vTaskDelay(pdMS_TO_TICKS(max_retry_times));
+            continue;
+        }
+    }
 
+    // 成功分支
+    if(ota_success)
+    {
+        #if (!ENABLE_HTTP_N455_OTA_FUNC)
+        uint8_t ret = Https_Ota_Report_Status(g_ota_status);
+        Https_Ota_Clear_Upgrade_Flag();
+        if(!ret)
+        {
+            esp_err_t ret = esp_ota_mark_app_invalid_rollback();
+            if(common_setting.wifi_status.wifi_state == 1){
+                xEventGroupSetBits(common_event_group, COMMON_MQTT_CONNECT_BIT);
+            }
+        }
+        #else
+        if(N455_Ota_Get_Update_Flag())
+        {
+            if(N455_Ota_Task() == 1)
+            {
+                esp_err_t ret = esp_ota_mark_app_invalid_rollback();
+                ESP_LOGI(HTTPS_OTA, "esp32 restart: %d", ret);
+                Https_Ota_Report_Status(HTTPS_OTA_STATUS_FAILED);
+                N455_Ota_Clear_Upgrade_Flag();
+                Https_Ota_Clear_Upgrade_Flag();
+                xEventGroupSetBits(common_event_group, COMMON_MQTT_CONNECT_BIT);
+            }
+        }else{
+            //不需要升级455 直接重启
+            g_ota_status = HTTPS_OTA_STATUS_SUCCESS;
+            Https_Ota_Report_Status(HTTPS_OTA_STATUS_SUCCESS);
+            Wifi_Stop();
+            vTaskDelay(10 / portTICK_PERIOD_MS);
+            Https_Ota_Clear_Upgrade_Flag();
+            esp_restart();
+        }
+        
+        #endif
+        vTaskDelete(NULL);
+        return;
+    }else{
+        if(https_ota_handle != NULL && g_ota_status != HTTPS_OTA_STATUS_SUCCESS){
+            esp_https_ota_abort(https_ota_handle);
+            https_ota_handle = NULL;
+        }
+        ota_timeout_req=0;
+        ESP_LOGI(HTTPS_OTA, "ESP_HTTPS_OTA upgrade failed after 3 retry");
+        g_ota_status = HTTPS_OTA_STATUS_FAILED;
+        ota_timeout_count=0;
+        Https_Ota_Report_Status(HTTPS_OTA_STATUS_FAILED);
+        Https_Ota_Clear_Upgrade_Flag();
+        if(common_setting.wifi_status.wifi_state == 1){
+            xEventGroupSetBits(common_event_group, COMMON_MQTT_CONNECT_BIT);
+        }
+        vTaskDelete(NULL);
+    }
+}
+#endif
 //清空升级标识
 void Https_Ota_Clear_Upgrade_Flag(void)
 {
-    g_ota_status = OTA_STATUS_IDLE;
-    common_setting.https_ota_cfg.https_ota_start_flag = 0;
+    g_ota_status = HTTPS_OTA_STATUS_IDLE;
     ota_timeout_count = 0;
     https_ota_init=0;
     ota_timeout_req=0;
+    https_update_ota_flag = 0; //升级标识清除
+    memset(https_ota_url,0,sizeof(https_ota_url));
 }
 
 
-static uint8_t version_check_flag = 0;
+
 // OTA版本检查
 //versin字符串转16进制版本号 0x0103
 // url 升级地址
 uint8_t Https_Ota_Version_Check(char *version,char *url)
 {
-    version_check_flag=0;
+    https_update_ota_flag=0;
     if(version == NULL || url == NULL)
     {
         return 0;
@@ -287,11 +481,11 @@ uint8_t Https_Ota_Version_Check(char *version,char *url)
     ESP_LOGI(HTTPS_OTA, "ver: %s %04x FW_VERSION:%04x", version,new_version,FW_VERSION);
     if(new_version != FW_VERSION && new_version != 0xffff)
     {
-        version_check_flag = 1;
+        https_update_ota_flag = 1;
         strncpy(https_ota_url, url, OTA_URL_SIZE - 1);
         https_ota_url[OTA_URL_SIZE - 1] = '\0'; // 确保字符串以null结尾
         ESP_LOGI(HTTPS_OTA, "need upgrade\n");
-        Https_Ota_Start();
+        
         return 1;
     }else{
         ESP_LOGI(HTTPS_OTA, "no need upgrade\n");
@@ -299,55 +493,71 @@ uint8_t Https_Ota_Version_Check(char *version,char *url)
     return 0;
 }
 
-uint8_t Https_Ota_Version_Flag(void)
+uint8_t Https_Ota_Get_Update_Flag(void)
 {
 
-    return version_check_flag;
+    return https_update_ota_flag;
 
 }
+//
+void Https_Ota_Clear_Update_Flag(void)
+{
+    https_update_ota_flag=0;
+}
 
 
 /*
-func:获取OTA状态
-0:空闲
-1: 正在OTA升级.......
+ *函数功能:获取OTA状态
+ *返回值
+ *0:空闲
+ *1: 正在OTA升级.......
 */
 uint8_t Https_Get_Ota_Status(void)
 {
-    if(g_ota_status != 0 || common_setting.https_ota_cfg.https_ota_start_flag == 1)
+    if(g_ota_status != HTTPS_OTA_STATUS_IDLE)
     {
         return 1;
 
     }
     return 0;
 }
+/*
+函数功能:获取OTA升级结果状态
+返回值
+0:空闲
+1: 升级中
+2: 升级成功
+3: 升级失败
+
+*/
 uint8_t Https_Get_Ota_Success(void)
 {
     return g_ota_status;
 }
 
 /*
-func:OTA开始
+ *函数功能:OTA开始
+ *无返回值
 */
 void Https_Ota_Start(void)
 {
-    if(g_ota_status != 0 || common_setting.https_ota_cfg.https_ota_start_flag == 1)
+    if(g_ota_status != HTTPS_OTA_STATUS_IDLE)
     {
         ESP_LOGI(HTTPS_OTA, "ota is started\n");
         return;
     }
     ESP_LOGI(HTTPS_OTA, "ota is start\n");
-    ota_timeout_count = 0;
-    common_setting.https_ota_cfg.https_ota_start_flag = 1;
+    
     xEventGroupSetBits(common_event_group, COMMON_HTTPS_OTA_BIT);
 
 }
 /*
-func:OTA停止
-*/
+ *函数功能:OTA停止
+ *无返回值
+ */
 void Https_Ota_Stop(void)
 {
-    if(g_ota_status != OTA_STATUS_SUCCESS && g_ota_status > 0 && common_setting.https_ota_cfg.https_ota_start_flag == 1)
+    if(g_ota_status != HTTPS_OTA_STATUS_SUCCESS && g_ota_status > HTTPS_OTA_STATUS_IDLE)
     {
         if(!ota_timeout_req){
             ota_timeout_req = 1;
@@ -358,7 +568,8 @@ void Https_Ota_Stop(void)
 }
 
 /*
-func:OTA任务
+*函数功能:OTA任务
+*无返回值
 */
 
 void Https_Ota_Task(void)
@@ -367,35 +578,39 @@ void Https_Ota_Task(void)
     {
         return;
     }
+    ota_timeout_req = 0;
+    ota_timeout_count = 0;
     https_ota_init=1;
+    g_ota_status = HTTPS_OTA_STATUS_UPGRADING;
     BaseType_t ret = xTaskCreate(Https_Ota_Task_Cb, "https_ota_task", HTTPS_OTA_STACK_SIZE, NULL, 4, NULL);
     if(ret !=pdPASS )
     {
+        https_ota_init=0;
+        ESP_LOGI(HTTPS_OTA, "create https ota task failed\n");
         Https_Ota_Clear_Upgrade_Flag();
-        g_ota_status = OTA_STATUS_IDLE;
+        g_ota_status = HTTPS_OTA_STATUS_IDLE;
     }else{
+
         https_ota_init=1;
-        g_ota_status = OTA_STATUS_UPGRADING;
+        g_ota_status = HTTPS_OTA_STATUS_UPGRADING;
         ESP_LOGI(HTTPS_OTA, "task success\n");
 
     }
 }
 /*
-func:OTA超时检查
-*/
+ *函数功能:OTA超时检查
+ */
 void Https_Ota_Check_TimeOut(void)
 {
-    if(g_ota_status == OTA_STATUS_UPGRADING && g_ota_status > 0 && common_setting.https_ota_cfg.https_ota_start_flag == 1) //一直没有成功
+    if(g_ota_status == HTTPS_OTA_STATUS_UPGRADING) //一直没有成功
     {
         if(ota_timeout_count > 0)
         {
             ota_timeout_count--;
-            
+            ESP_LOGI(HTTPS_OTA, "OTA ota_timeout_count: %d", ota_timeout_count);
             if(ota_timeout_count== 0)
             {
-                if(!ota_timeout_req){
-                    ota_timeout_req=1;
-                }
+                ota_timeout_req=1;
             }
         }
     }else{
@@ -409,11 +624,13 @@ void Https_Ota_Check_TimeOut(void)
             Https_Ota_Start();
 
         }
-
     }
 
 }
-// OTA升级回调事件处理函数
+/*
+ *函数功能:OTA事件回调
+ *无返回值
+ */
 static void ota_event_handler(void* arg, esp_event_base_t event_base,
                                 int32_t event_id, void* event_data)
 {
@@ -422,7 +639,7 @@ static void ota_event_handler(void* arg, esp_event_base_t event_base,
         switch (event_id) {
             case ESP_HTTPS_OTA_START:
                 ESP_LOGI(HTTPS_OTA, "OTA started");
-                g_ota_status = OTA_STATUS_UPGRADING;
+                g_ota_status = HTTPS_OTA_STATUS_UPGRADING;
                 break;
             case ESP_HTTPS_OTA_CONNECTED:
                 ESP_LOGI(HTTPS_OTA, "Connected to server");
@@ -443,11 +660,11 @@ static void ota_event_handler(void* arg, esp_event_base_t event_base,
                 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;
+                g_ota_status = HTTPS_OTA_STATUS_SUCCESS;
                 ESP_LOGI(HTTPS_OTA, "OTA finish");
                 break;
             case ESP_HTTPS_OTA_ABORT:
-                g_ota_status = OTA_STATUS_FAILED;
+                g_ota_status = HTTPS_OTA_STATUS_FAILED;
                 ESP_LOGI(HTTPS_OTA, "OTA abort");
                 break;
         }
@@ -460,8 +677,8 @@ 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));
 }
 /*
-func:https OTA状态检查
-*/
+ *函数功能:https OTA状态检查
+ */
 void Https_Ota_Status_Check(void)
 {
     if((xEventGroupWaitBits(common_event_group, COMMON_HTTPS_OTA_BIT, pdFALSE, pdFALSE, 0) & COMMON_HTTPS_OTA_BIT) != 0)
@@ -514,8 +731,9 @@ static esp_err_t _http_ota_status_event_handler(esp_http_client_event_t *evt)
 }
 
 /*
-FUNC:OTA升级状态上报 http请求
-*/
+ *函数功能:OTA升级状态上报 http请求
+ *返回值: 0表示失败,1表示成功
+ */
 uint8_t Https_Ota_Report_Status(uint8_t ota_status)
 {
     // http://192.168.66.85:8089/iot/firmware/task/detailadd     {
@@ -530,7 +748,7 @@ uint8_t Https_Ota_Report_Status(uint8_t ota_status)
     };
     int result = 0;
     esp_http_client_handle_t http_client = NULL;
-    for(uint8_t retry=0;retry<1;retry++)
+    for(uint8_t retry = 0;retry < 3;retry++)
     {
         result = 0;
         http_client=NULL;
@@ -550,18 +768,18 @@ uint8_t Https_Ota_Report_Status(uint8_t ota_status)
         }      
         cJSON_AddStringToObject(pRoot, "serialNumber", (const char*)common_storage.net_info.serial_number);
         #if (!ENABLE_HTTP_N455_OTA_FUNC)
-        if(ota_status == OTA_STATUS_SUCCESS)
+        if(ota_status == HTTPS_OTA_STATUS_SUCCESS)
         #else
-        if(ota_status == OTA_STATUS_SUCCESS || ota_status == N455_OTA_STATUS_SUCCESS)
+        if(ota_status == HTTPS_OTA_STATUS_SUCCESS || ota_status == N455_OTA_STATUS_SUCCESS)
         #endif
         {
             cJSON_AddNumberToObject(pRoot,"upgradeStatus", 3);
             cJSON_AddStringToObject(pRoot, "detailMsg", "升级成功");
         }
         #if (!ENABLE_HTTP_N455_OTA_FUNC)
-        else if(ota_status == OTA_STATUS_UPGRADING)
+        else if(ota_status == HTTPS_OTA_STATUS_UPGRADING)
         #else
-        else if(ota_status == OTA_STATUS_UPGRADING || ota_status == N455_OTA_STATUS_UPGRADING)
+        else if(ota_status == HTTPS_OTA_STATUS_UPGRADING || ota_status == N455_OTA_STATUS_UPGRADING)
         #endif
         {
             cJSON_AddStringToObject(pRoot, "detailMsg", "升级中");
@@ -580,7 +798,6 @@ uint8_t Https_Ota_Report_Status(uint8_t ota_status)
             vTaskDelay(50);
             continue; 
         }
-        ESP_LOGI(HTTPS_OTA, "put data:%s\n", post_data);
         ESP_LOGI(HTTPS_OTA, "http_config.url = %s", http_config.url);
         
         http_client = esp_http_client_init(&http_config);
@@ -599,9 +816,26 @@ uint8_t Https_Ota_Report_Status(uint8_t ota_status)
         esp_http_client_set_header(http_client, "Content-Type", "application/json");
 
         esp_http_client_set_post_field(http_client, post_data, strlen(post_data));
-        esp_err_t err = esp_http_client_perform(http_client);
+        esp_err_t err = esp_http_client_open(http_client, 0);
         if (err == ESP_OK)
         {
+            
+            int header_ret = esp_http_client_fetch_headers(http_client);//获取HTTP响应头,返回值为响应头的总长度,如果返回值小于0表示获取响应头失败
+            if(header_ret < 0)
+            {
+                ESP_LOGE(HTTPS_OTA, "Failed to fetch headers");
+                result =  0;
+                cJSON_free(post_data);
+                cJSON_Delete(pRoot);
+                if(http_client != NULL)
+                {   
+                    esp_http_client_close(http_client);
+                    esp_http_client_cleanup(http_client);
+                    http_client=NULL;
+                }
+                vTaskDelay(50);
+                continue;
+            }
             int status_code = esp_http_client_get_status_code(http_client);
             int read_len = esp_http_client_get_content_length(http_client);
             if(status_code == 200)
@@ -638,13 +872,14 @@ uint8_t Https_Ota_Report_Status(uint8_t ota_status)
     }
 
     #if (!ENABLE_HTTP_N455_OTA_FUNC)
-    if(ota_status == OTA_STATUS_SUCCESS)
+    if(ota_status == HTTPS_OTA_STATUS_SUCCESS)
     #else
-    if(ota_status == OTA_STATUS_SUCCESS  || ota_status == N455_OTA_STATUS_SUCCESS)
+    if(ota_status == HTTPS_OTA_STATUS_SUCCESS  || ota_status == N455_OTA_STATUS_SUCCESS)
     #endif
     {
-        Wifi_Stop();//断开wifi
-        esp_restart();
+        // Wifi_Stop();//断开wifi
+        // vTaskDelay(50);
+        // esp_restart();
         return 1;
     }
     return 0;
index d46b88d..346e9c4 100644 (file)
@@ -7,16 +7,18 @@
 
 // OTA 升级状态枚举
 typedef enum {
-    OTA_STATUS_IDLE = 0,        // 空闲
-    OTA_STATUS_UPGRADING = 1,   // 升级中
-    OTA_STATUS_SUCCESS = 2,     // 升级成功
-    OTA_STATUS_FAILED = 3,      // 升级失败
-} ota_status_t;
+    HTTPS_OTA_STATUS_IDLE = 0,        // 空闲
+    HTTPS_OTA_STATUS_UPGRADING = 1,   // 升级中
+    HTTPS_OTA_STATUS_SUCCESS = 2,     // 升级成功
+    HTTPS_OTA_STATUS_FAILED = 3,      // 升级失败
+} https_ota_status_t;
 
-extern ota_status_t g_ota_status;
+extern https_ota_status_t g_ota_status;
 
 void Https_Ota_Task(void);//ota升级任务
 void Https_Ota_Status_Check(void);//是否需要ota升级状态
+void Https_Ota_Clear_Update_Flag(void);
+uint8_t Https_Ota_Get_Update_Flag(void);//版本检查结果标识
 /*
 ota版本检查
 */
@@ -25,11 +27,11 @@ uint8_t Https_Ota_Version_Check(char *version,char *url);
 void Https_Ota_Start(void); //开始ota升级
 void Https_Ota_Stop(void);
 void Https_Ota_Handler_Init(void); //ota注册回调
-uint8_t Https_Ota_Report_Status(uint8_t ota_status);//report_ota_status(uint8_t ota_status);
+uint8_t Https_Ota_Report_Status(uint8_t ota_status);//report_ota_status(https_ota_status_t ota_status);
 void Https_Ota_Check_TimeOut(void); //ota超时检查
 uint8_t Https_Get_Ota_Status(void);
 void Https_Ota_Clear_Upgrade_Flag(void);//清除升级标识
 uint8_t Https_Get_Ota_Success(void);//是否升级成功
-uint8_t Https_Ota_Version_Flag(void);//版本检查结果标识
+
 #endif
 #endif
\ No newline at end of file
index f33445a..a26cf3a 100644 (file)
@@ -1,5 +1,6 @@
 #include "project_common.h"
-
+#include "n455_ota.h"
+#include "https_ota.h"
 static const char *IAP_TAG = "IAP";
 
 static const esp_partition_t *update_partition = NULL;
@@ -168,6 +169,16 @@ uint8_t Iap_Write_Cache(uint32_t addr, uint16_t cache_size)
 
 void Iap_Process(uint8_t* data, uint8_t len)
 {
+       #if (ENABLE_HTTP_N455_OTA_FUNC && ENABLE_HTTPS_OTA_FUNC)
+       if(Https_Get_Ota_Status() != HTTPS_OTA_STATUS_IDLE || N455_Get_Ota_Status() != N455_OTA_STATUS_IDLE)
+       #elif ENABLE_HTTPS_OTA_FUNC 
+       if(Https_Get_Ota_Status() != HTTPS_OTA_STATUS_IDLE)
+       #elif ENABLE_HTTP_N455_OTA_FUNC
+       if(N455_Get_Ota_Status() != N455_OTA_STATUS_IDLE)
+       #endif
+       {
+               return;
+       }
        memset(iap_reply.other.buf, 0xFF, sizeof(IAP_CMD_REPLY_T));
        memcpy(iap_cmd.other.buf, data, len);
        memcpy(iap_reply.other.buf, iap_cmd.other.buf, 3);
@@ -302,7 +313,7 @@ void Iap_Process(uint8_t* data, uint8_t len)
 
                 uint8_t result = 0;
                                uint32_t crc_result = Iap_Check(start_addr, iap_cmd.check.size, &result);
-                               ESP_LOGI(IAP_TAG, "CRC32_Update:%08x %08x\n", (unsigned int)crc_result, (unsigned int)iap_cmd.check.crc32);
+                               // ESP_LOGI(IAP_TAG, "CRC32_Update:%08x %08x\n", (unsigned int)crc_result, (unsigned int)iap_cmd.check.crc32);
                                if(crc_result == iap_cmd.check.crc32)
                                {
                     if(result == 0)
@@ -387,7 +398,6 @@ void Iap_Process(uint8_t* data, uint8_t len)
                // 01 b1 01 0C 57 47 54 4C 5F 45 53 50 33 32 43 32
                ESP_LOGI(IAP_TAG, "unauth\n");
        }
-       
        Uart_Reply_Send(iap_reply.cmd.cmd1, iap_reply.other.buf, sizeof(iap_reply.other.buf), HOST_TYPE_UART);
 }
 
index 3d30d2e..79858a2 100644 (file)
@@ -31,9 +31,9 @@ static const char *N455_OTA = "455_OTA";
 N455_ota_status_t n455_g_ota_status = N455_OTA_STATUS_IDLE; // 
 #define OTA_URL_MAX_LEN 128
 #define OAT_CONNECT_RETRY_NUM  3 //重连服务器次数 3
-#define OTA_TOTAL_TIMEOUT_S 30 //总超时时间 单位s
-#define HTTPS_OTA_STACK_SIZE   (4*1024)
-static char n455_ota_url[OTA_URL_MAX_LEN] = "https://pxn-iot.s3.us-east-2.amazonaws.com/iot01/2026/05/19/6a0c013d7911aa4f1c76a42e.lsuf";
+#define OTA_TOTAL_TIMEOUT_S 60 //总超时时间 单位s
+#define N455_OTA_STACK_SIZE   (4*1024)
+static char n455_ota_url[OTA_URL_MAX_LEN] = "https://pxn-iot.s3-accelerate.amazonaws.com/iot01/2026/06/03/6a1f95e5bfcb3c271127dd8b.bin";
 
 
 // BIN 文件头
@@ -42,10 +42,17 @@ static char n455_ota_url[OTA_URL_MAX_LEN] = "https://pxn-iot.s3.us-east-2.amazon
 // 全局升级应答
 static volatile bool  uart_ack_received = false; // UART应答的 1 标识uart收到回复 
 static volatile uint8_t uart_ack = 0xFF; //UART应答的 1 成功 2 失败 0xFF未收到应答 0表示收到但失败
+
+//task 标识
 static  uint8_t n455_ota_init = 0;
 static volatile uint8_t n455_ota_stop = 0;
 static volatile uint16_t n455_ota_timeout = 0;
-// 捕获455升级应答(给uart.c调用)
+static uint8_t n455_ota_update_flag = 0; //ota是否需要升级
+/*
+ *函数功能:接收升级应答
+ *cmd:命令类型
+ *ack:应答结果 1成功 2失败
+ */ 
 void N455_Ota_Capture_Ack(uint8_t cmd, uint8_t ack)
 {
     if(cmd == CMD1_N455)
@@ -55,7 +62,11 @@ void N455_Ota_Capture_Ack(uint8_t cmd, uint8_t ack)
     }
 }
 
-// 等待应答
+/*
+ *函数功能:等待应答
+ *返回值: true表示成功收到应答且结果是成功,false表示超时或收到应答但结果是失败
+ *expect_cmd2:期望的命令类型,用于区分不同命令的应答超时时间
+*/ 
 static bool ota_wait_ack(uint8_t expect_cmd2)
 {
     uart_ack_received = false;
@@ -98,7 +109,13 @@ static bool ota_wait_ack(uint8_t expect_cmd2)
     }
 }
 
-// 带3次重发机制发送
+/* 
+ *函数功能:带3次重发机制发送
+ *cmd2:命令类型
+ *data:命令数据指针
+ *len:命令数据长度
+ *返回值: true表示发送成功并收到成功应答,false表示发送失败或未收到成功应答 
+*/
 static bool ota_send_with_retry(uint8_t cmd2, uint8_t *data, uint8_t len)
 {
     uint8_t retry = 0;
@@ -175,12 +192,15 @@ static bool ota_send_with_retry(uint8_t cmd2, uint8_t *data, uint8_t len)
                 return false;
             }
             retry++;
-            ESP_LOGW(N455_OTA, "RETRY:%d", MAX_RETRY_TIMES - retry);
+            ESP_LOGE(N455_OTA, "RETRY:%d", MAX_RETRY_TIMES - retry);
             vTaskDelay(pdMS_TO_TICKS(10));
         }
     }
     return ok;
 }
+/*
+函数功能:http OTA事件回调
+*/
 static esp_err_t _http_ota_event_handler(esp_http_client_event_t *evt)
 {
     switch (evt->event_id) {
@@ -215,17 +235,23 @@ static esp_err_t _http_ota_event_handler(esp_http_client_event_t *evt)
 
 
 /*
-FUNC:N455 OTA升级状态上报 http请求
+ *函数功能:N455 ota升级任务
+ *返回值: 无
 */
+#if 0
 void N455_Ota_Task_Cb(void *param)
 {
     esp_http_client_config_t config = {
         .url = n455_ota_url,
         .crt_bundle_attach = esp_crt_bundle_attach,//需要访问https一定要加这句
         .event_handler = _http_ota_event_handler,
-        .timeout_ms = 10000,
+        .timeout_ms = 5000,
         .keep_alive_enable = true,
     };
+    esp_http_client_handle_t client = NULL;
+    n455_ota_timeout = OTA_TOTAL_TIMEOUT_S;
+    n455_g_ota_status = N455_OTA_STATUS_UPGRADING;
+
     uint8_t buf[MAX_PACKET_CONTENT];
     uint32_t real_write_len = 0;
     CRC32_CTX_T crc_ctx;
@@ -235,9 +261,7 @@ void N455_Ota_Task_Cb(void *param)
     int wlen = 0;
 
     
-    esp_http_client_handle_t client = NULL;
-    n455_ota_timeout = OTA_TOTAL_TIMEOUT_S;
-    n455_g_ota_status = N455_OTA_STATUS_UPGRADING;
+   
     for (size_t i = 0; i < OAT_CONNECT_RETRY_NUM; i++)
     {
         if(n455_ota_stop)
@@ -513,7 +537,7 @@ ota_end:
     n455_g_ota_status = N455_OTA_STATUS_FAILED;
     n455_ota_stop = 0;
     //如果32ota成功了 455升级失败了 清除32的升级标识 回滚固件
-    if(Https_Get_Ota_Success() == OTA_STATUS_SUCCESS)
+    if(Https_Get_Ota_Success() == HTTPS_OTA_STATUS_SUCCESS)
     {
         
         // 标记 ESP32 新固件无效,不重启
@@ -530,37 +554,256 @@ ota_end:
     xEventGroupSetBits(common_event_group, COMMON_MQTT_CONNECT_BIT); // 清除MQTT连接位,触发重连机制
     vTaskDelete(NULL);
 }
-
+#else
 /*
-func:OTA任务
+ *函数功能:N455 ota升级任务
+ *返回值: 无
 */
 
-uint8_t N455_Ota_Task(void)
+void N455_Ota_Task_Cb(void *param)
 {
-    if(n455_ota_init)
+    esp_http_client_config_t config = {
+        .url = n455_ota_url,
+        .crt_bundle_attach = esp_crt_bundle_attach,
+        .event_handler = _http_ota_event_handler,
+        .timeout_ms = 5000,
+        .keep_alive_enable = false,
+    };
+    /*
+        *模组不需要升级的时候需要上报状态 模组升级了不需要再次上报升级中的状态
+    */
+    if(!Https_Ota_Get_Update_Flag())
     {
-        ESP_LOGI(N455_OTA, "N455 OTA running\n");
-        return 2;
+        Mqtt_Disconnect();  // 关闭MQTTs
+        vTaskDelay(200 / portTICK_PERIOD_MS);
+        n455_g_ota_status = N455_OTA_STATUS_UPGRADING;
+        Https_Ota_Report_Status(g_ota_status);
     }
-    n455_ota_init=1;
-    BaseType_t ret = xTaskCreate(N455_Ota_Task_Cb, "https_n455_ota_task", HTTPS_OTA_STACK_SIZE, NULL, 6, NULL);
-    if(ret !=pdPASS )
+    ///////////////////////
+    vTaskDelay(50 / portTICK_PERIOD_MS);
+    const int MAX_OTA_RETRY = 3;  // 整个OTA只试3次
+
+    uint8_t buf[MAX_PACKET_CONTENT];
+    uint32_t real_write_len = 0;
+    CRC32_CTX_T crc_ctx;
+    CRC32_Init(&crc_ctx);
+    uint32_t offset_size = 0;
+    // uint8_t write_data[MAX_PACKET_CONTENT+6] = {0};
+    int wlen = 0;
+    esp_http_client_handle_t client = NULL;
+    bool failed = false;
+    n455_ota_timeout = OTA_TOTAL_TIMEOUT_S;
+    uint8_t write_data[sizeof(FW_FILE_HEADER_T)] = {0};
+    // ======================
+    // 只循环3次 → 每次都完整重新下载(正确)
+    // ======================
+    for (int retry = 0; retry < MAX_OTA_RETRY; retry++)
     {
-        ESP_LOGI(N455_OTA, "task err\n");
-        n455_ota_init=0;
-        //升级失败了也可以选择重启让设备回到正常状态
-        //esp32回滚固件
-        n455_g_ota_status = N455_OTA_STATUS_IDLE;
-        return 1;
-    }else{
+        ESP_LOGI(N455_OTA, "===== OTA 第 %d/%d 次 =====", retry+1, MAX_OTA_RETRY);
+        if(n455_ota_stop)
+        {
+            n455_ota_stop = 0;
+            if (client) {
+                esp_http_client_close(client);
+                esp_http_client_cleanup(client);
+                client = NULL;
+            }
+            break;
+        }
+        memset(buf, 0, sizeof(buf));
+        real_write_len = 0;
+        CRC32_Init(&crc_ctx);
+        offset_size = 0;
+        memset(write_data, 0, sizeof(write_data));
+        
+        // memset(header_buf,0,sizeof(header_buf));
+        wlen = 0;
+        //防止没有关闭http连接就进入下一次重试,导致资源泄露
+        if(client)
+        {
+            esp_http_client_close(client);
+            esp_http_client_cleanup(client);
+        }
+        client = NULL;
+        failed = false;
+
+
+        n455_ota_stop = 0;
+        uart_ack_received = false;
+        uart_ack = 0xFF;
         n455_g_ota_status = N455_OTA_STATUS_UPGRADING;
-        //成功创建任务后在回调函数里根据升级结果来决定是否重启或者上报mqtt消息等后续操作
-        ESP_LOGI(N455_OTA, "task success\n");
-        return 0;
+
+        // --------------------
+        // 1. HTTP 下载(每次重试都必须重新下载)
+        // --------------------
+        client = esp_http_client_init(&config);
+        if (!client) {
+            ESP_LOGW(N455_OTA, "HTTP init fail");
+            failed = true;
+        }
+
+        if (!failed && esp_http_client_open(client, 0) != ESP_OK) {
+            ESP_LOGW(N455_OTA, "HTTP connect fail");
+            failed = true;
+        }
+        int ret =  esp_http_client_fetch_headers(client);
+        int code = esp_http_client_get_status_code(client);
+        if (!failed && (code != 200 || ret < 0)) {
+            ESP_LOGW(N455_OTA, "HTTP code error");
+            failed = true;
+        }
+
+        int64_t total_len = esp_http_client_get_content_length(client);
+        if (!failed && total_len <= 0) {
+            ESP_LOGW(N455_OTA, "File length error");
+            failed = true;
+        }
+
+        // 读头部256字节
+        
+        if (!failed) {
+            
+            int r = esp_http_client_read(client, (char *)write_data, sizeof(FW_FILE_HEADER_T));
+            if (r < sizeof(FW_FILE_HEADER_T) ||
+                write_data[0] != 0xFE || write_data[1] != 0xCA ||
+                write_data[2] != 0x00 || write_data[3] != 0xEE ||
+                write_data[4] != 0xFF || write_data[5] != 0xC0 ||
+                write_data[6] != 0xD0 || write_data[7] != 0xBA)
+            {
+                ESP_LOGE(N455_OTA, "Header check fail");
+                failed = true;
+            }
+        }
+        memset(write_data,0,sizeof(write_data));
+        // --------------------
+        // 2. 升级流程
+        // --------------------
+        if (!failed && !ota_send_with_retry(CMD2_READY, NULL, 0))  failed = true;
+        if (!failed && !ota_send_with_retry(CMD2_ERASE, NULL, 0)) failed = true;
+
+        if (!failed) {
+            while (1) {
+                if (n455_ota_stop) { failed = true; break; }
+                int r = esp_http_client_read(client, (char *)buf, MAX_PACKET_CONTENT);
+                if (r <= 0) break;
+
+                wlen = 0;
+                CRC32_Update(&crc_ctx, buf, r);
+                write_data[wlen++] = offset_size & 0xFF;
+                write_data[wlen++] = (offset_size >> 8) & 0xFF;
+                write_data[wlen++] = (offset_size >> 16) & 0xFF;
+                write_data[wlen++] = (offset_size >> 24) & 0xFF;
+                write_data[wlen++] = r & 0xFF;
+                write_data[wlen++] = (r >> 8) & 0xFF;
+                memcpy(&write_data[wlen], buf, r);
+                wlen += r;
+
+                if (!ota_send_with_retry(CMD2_WRITE, write_data, wlen)) {
+                    failed = true;
+                    break;
+                }
+                
+                offset_size += r;
+                real_write_len += r;
+            }
+            ESP_LOGE(N455_OTA, "WRITE END:%d",real_write_len);
+            //超时退出不再继续ota升级
+            if(n455_ota_stop)
+            {
+                n455_ota_stop = 0;
+                if (client) {
+                    esp_http_client_close(client);
+                    esp_http_client_cleanup(client);
+                    client = NULL;
+                }
+                break;
+            }
+        }
+
+        if (!failed && (total_len - 256) != real_write_len) {
+            ESP_LOGW(N455_OTA, "Length mismatch");
+            failed = true;
+        }
+
+        if (!failed && !ota_send_with_retry(CMD2_WRITE_END, NULL, 0)) 
+        {
+            failed = true;
+        }
+
+        if(!failed)
+        {
+            uint32_t crc = CRC32_Final(&crc_ctx);
+            uint8_t crc_data[8] = {0};
+            memcpy(crc_data, &real_write_len, 4);
+            memcpy(crc_data+4, &crc, 4);
+
+            if (!failed && !ota_send_with_retry(CMD2_CRC_CHECK, crc_data, 8)) 
+            {
+                failed = true;
+            }
+            
+        }
+        if (!failed && !ota_send_with_retry(CMD2_MOVE, NULL, 0))  
+        {
+            failed = true;
+        }
+        if (!failed && !ota_send_with_retry(CMD2_FINISH, NULL, 0)) 
+        {
+            failed = true;
+        }
+
+        
+
+        // 清理HTTP
+        if (client) {
+            esp_http_client_close(client);
+            esp_http_client_cleanup(client);
+            client = NULL;
+        }
+
+        // 成功
+        if (!failed) {
+            
+            n455_g_ota_status = N455_OTA_STATUS_SUCCESS;
+            Https_Ota_Report_Status(n455_g_ota_status);
+            Wifi_Stop();
+            vTaskDelay(10 / portTICK_PERIOD_MS);
+            Https_Ota_Clear_Upgrade_Flag();
+            N455_Ota_Clear_Upgrade_Flag();
+            
+            esp_restart();
+            vTaskDelete(NULL);
+            return;
+        }
+
+        // 失败,等3秒进入下一次重试
+        ESP_LOGI(N455_OTA, "重试");
+        vTaskDelay(pdMS_TO_TICKS(1000));
+    }
+    n455_ota_timeout=0;
+    n455_ota_stop=0;
+    // 3次全部失败
+    ESP_LOGI(N455_OTA, "全部失败");
+    n455_g_ota_status = N455_OTA_STATUS_FAILED;
+
+    if (Https_Get_Ota_Success() == HTTPS_OTA_STATUS_SUCCESS) {
+        esp_ota_mark_app_invalid_rollback();
     }
+
+    Https_Ota_Clear_Upgrade_Flag();
+    Https_Ota_Report_Status(N455_OTA_STATUS_FAILED);
+    N455_Ota_Clear_Upgrade_Flag();
+    xEventGroupSetBits(common_event_group, COMMON_MQTT_CONNECT_BIT);
+    vTaskDelete(NULL);
 }
+#endif
+/*
+函数功能:OTA任务开始函数
+*/
+
+
 /*
-func:OTA超时检查
+ *函数功能:OTA超时检查
 */
 void N455_Ota_Check_TimeOut(void)
 {
@@ -572,23 +815,22 @@ void N455_Ota_Check_TimeOut(void)
             if(n455_ota_timeout == 0)
             {
                 ESP_LOGI(N455_OTA, "ota timeout");
-                if(!n455_ota_stop)
-                {
-                    n455_ota_stop = 1;
-                }
+                n455_ota_stop = 1;
             }
         }
     }else{
         n455_ota_timeout=0;
     }   
 }
-static uint8_t n455_version_check_flag = 0;
-// OTA版本检查
-//versin字符串转16进制版本号 0x0103
-// url 升级地址
+
+/*
+ *函数功能: OTA版本检查 
+ *参数: version 版本字符串,url 升级地址 versin字符串转16进制版本号 0x0103
+ *返回值: 1需要升级 0不需要升级
+*/ 
 uint8_t N455_Ota_Version_Check(char *version,char *url)
 {
-    n455_version_check_flag=0;
+    n455_ota_update_flag=0;
     if(version == NULL || url == NULL)
     {
         return 0;
@@ -598,7 +840,7 @@ uint8_t N455_Ota_Version_Check(char *version,char *url)
     ESP_LOGI(N455_OTA, "ver: %s %04x FW_VERSION:%04x", version,new_version,FW_VERSION);
     if(new_version != FW_VERSION && new_version != 0xffff)
     {
-        n455_version_check_flag = 1;
+        n455_ota_update_flag = 1;
         strncpy(n455_ota_url, url, OTA_URL_MAX_LEN - 1);
         n455_ota_url[OTA_URL_MAX_LEN - 1] = '\0'; // 确保字符串以null结尾
         ESP_LOGI(N455_OTA, "need upgrade\n");
@@ -608,31 +850,80 @@ uint8_t N455_Ota_Version_Check(char *version,char *url)
     }
     return 0;
 }
-
-uint8_t N455_Ota_Version_Flag(void)
+/*
+ *函数功能: 获取455升级标识
+ *返回值: 1需要升级 0不需要升级
+*/
+uint8_t N455_Ota_Get_Update_Flag(void)
 {
+    return n455_ota_update_flag;
+}
 
-    return n455_version_check_flag;
-
+void N455_Ota_Clear_Update_Flag(void)
+{
+    n455_ota_update_flag=0;
 }
-//455升级失败清空32升级标识
+/*
+ *函数功能: 455升级失败清空32升级标识
+ */
 void N455_Ota_Clear_Upgrade_Flag(void)
 {
     n455_g_ota_status = N455_OTA_STATUS_IDLE; // 状态重置为空闲
     n455_ota_init=0; //升级初始化标志清零
     n455_ota_timeout =0; //升级超时标志清零
     n455_ota_stop = 0;//升级停止标志清零
-
+    n455_ota_update_flag=0; //升级标识清除
+    memset(n455_ota_url,0,sizeof(n455_ota_url));
 }
-
+/**
+ *函数功能: 获取455升级状态
+ *返回值: 升级状态
+ */
 uint8_t N455_Get_Ota_Status(void)
 {
     return n455_g_ota_status;
 }
+uint8_t N455_Ota_Task(void)
+{
+    if(n455_ota_init)
+    {
+        ESP_LOGI(N455_OTA, "N455 OTA running\n");
+        return 2;
+    }
+    n455_ota_init=1; //升级初始化标志清零
+    n455_ota_timeout =0; //升级超时标志清零
+    n455_ota_stop = 0;//升级停止标志清零
+    n455_g_ota_status = N455_OTA_STATUS_UPGRADING;
+    BaseType_t ret = xTaskCreate(N455_Ota_Task_Cb, "n455_ota_task", N455_OTA_STACK_SIZE, NULL, 6, NULL);
+    if(ret !=pdPASS )
+    {
+        ESP_LOGI(N455_OTA, "task err\n");
+        n455_ota_init=0;
+        n455_g_ota_status = N455_OTA_STATUS_IDLE;
+        N455_Ota_Clear_Upgrade_Flag();
+        return 1;
+    }else{
+        n455_g_ota_status = N455_OTA_STATUS_UPGRADING;
+        //成功创建任务后在回调函数里根据升级结果来决定是否重启或者上报mqtt消息等后续操作
+        ESP_LOGI(N455_OTA, "task success\n");
+        return 0;
+    }
+}
+void N455_Ota_Start(void)
+{
+    if(n455_g_ota_status != N455_OTA_STATUS_IDLE)
+    {
+        ESP_LOGI(N455_OTA, "455 ota is started\n");
+        return;
+    }
+    ESP_LOGI(N455_OTA, "455 ota is start\n");
+    xEventGroupSetBits(common_event_group, COMMON_HTTPS_N455_OTA_BIT);
+
+}
 
 /*
-func:455 OTA状态检查
-*/
+ *函数功能:455 OTA状态检查
+ */
 void N455_Ota_Status_Check(void)
 {
     if((xEventGroupWaitBits(common_event_group, COMMON_HTTPS_N455_OTA_BIT, pdFALSE, pdFALSE, 0) & COMMON_HTTPS_N455_OTA_BIT) != 0)
index cb31c4a..743f3ef 100644 (file)
@@ -19,7 +19,7 @@ func:OTA停止
 */
 // ====================模组 uart升级 455 升级协议 ====================
 #define CMD1_N455               COMMON_UART_MCU_FIRMWARE_UPDATE_CMD    // 盘面:0xE0,基座:0xB0,582:0xB2
-#define MAX_PACKET_CONTENT      64     // 协议规定最大64字节 测试建议值
+#define MAX_PACKET_CONTENT      64     // 协议规定最大64字节 测试建议值 可以根据实际情况调整 过大可能导致重试率增加 过小可能导致升级慢
 #define OTA_TIMEOUT_MS          2000
 #define MAX_RETRY_TIMES         3
 
@@ -105,10 +105,12 @@ extern N455_ota_status_t n455_g_ota_status;
 uint8_t N455_Ota_Task(void); //n455 ota升级任务
 void N455_Ota_Status_Check(void); //455 ota升级状态检查
 void N455_Ota_Capture_Ack(uint8_t cmd, uint8_t ack); //捕获455升级ack
-uint8_t N455_Ota_Version_Flag(void); //版本检查结果标识
+uint8_t N455_Ota_Get_Update_Flag(void); //版本检查结果标识
 uint8_t N455_Ota_Version_Check(char *version,char *url); //版本检查
 void N455_Ota_Clear_Upgrade_Flag(void); //清除升级标识
 void N455_Ota_Check_TimeOut(void); //ota超时检查
 uint8_t N455_Get_Ota_Status(void);
+void N455_Ota_Clear_Update_Flag(void);
+void N455_Ota_Start(void);
 #endif
 #endif
\ No newline at end of file
index a0e8505..c182eab 100644 (file)
@@ -9,8 +9,7 @@ typedef struct {
     uint16_t pid;
     uint16_t vid;
 } __attribute__((packed)) user_custom_version_header_t;
-
-const __attribute__((section(".rodata_desc"), used, retain))
+const __attribute__((section(".rodata_custom_desc"), used, retain))
 user_custom_version_header_t esp_user_app_custom_desc = {
     .fw_version = FW_VERSION,
     .pid = DEVICE_PID,
@@ -111,12 +110,12 @@ void Check_Host_Type(uint8_t cmd, uint8_t* pbuf, uint16_t len, uint8_t host_type
 
 
 /*
-函数功能:ble replay
-cmd:协议指令
-pbuf:发送的数据
-len:数据长度
-host_type:预留
-*/
+ *函数功能:ble replay
+ *cmd:协议指令
+ *pbuf:发送的数据
+ *len:数据长度
+ *host_type:预留
+ */
 void Ble_Pairing_Reply(uint8_t cmd, uint8_t* pbuf, uint16_t len, uint8_t host_type)
 {
     if(common_setting.ble_status.ble_state == 0) //只有蓝牙开启才允许发送蓝牙数据
@@ -142,24 +141,24 @@ void Ble_Pairing_Reply(uint8_t cmd, uint8_t* pbuf, uint16_t len, uint8_t host_ty
     }
     uint8_t crc = Crc8_ROHC_Cal(&net_pairing_reply.buffer[1], len + 3);
     net_pairing_reply.buffer[len + 4] = crc;
-    ESP_LOGI(COMMON_TAG, "Ble_Pairing_Reply crc %02x len %u", crc, len);
+    ESP_LOGI(COMMON_TAG, "Reply crc %02x len %u", crc, len);
     // ESP_LOG_BUFFER_HEX(COMMON_TAG, net_pairing_reply.buffer, net_pairing_reply.size);
     #if ENABLE_BLE_FUNC
     xQueueSend(ble_notify_queue_handle, &net_pairing_reply, 0);
     #endif
 }
 /*
-功能函数: ble protocol
-data:原数据
-len:数据长度
-host_type:预留
-*/
+ *功能函数: ble protocol
+ *data:原数据
+ *len:数据长度
+ *host_type:预留
+ */
 void Ble_Pairing_Handle(uint8_t *data ,uint16_t len, uint8_t host_type)
 {
     //APP-ESP PROTUCOL协议指令解析 ble接收的数据不需要做数据长度判断 app层处理即可
     if(len >= 4 && len <= sizeof(BLE_SEND_REPLY_T) && data[0] == FRAMEHEAD_APP_TO_ESP && Crc8_ROHC_Cal(&data[1], len-2) == data[len-1] && host_type == HOST_TYPE_BLE)
     {
-        ESP_LOGI(COMMON_TAG, "ble recv %d bytes:cmd %0x\n", len, data[1]);
+        ESP_LOGI(COMMON_TAG, "recv %d bytes:cmd %0x\n", len, data[1]);
         // ESP_LOG_BUFFER_HEX(COMMON_TAG, data, len);
         static BLE_SEND_REPLY_T net_pairing_reply = {0};
         memset(&net_pairing_reply, 0x00, sizeof(BLE_SEND_REPLY_T));
@@ -951,16 +950,6 @@ void Ble_Pairing_Handle(uint8_t *data ,uint16_t len, uint8_t host_type)
                 }
             }
             break;
-            //清除配网信息
-            case COMMON_BLE_CLEAR_NETWORK_INFOR_CMD: 
-            {
-                Wifi_Stop();
-                Mqtt_Disconnect();
-                User_Erase_NotReset();
-                common_setting.ble_status.nimble_flag=0;
-                xEventGroupSetBits(ble_event_group, BLE_ON_BIT);
-            }
-            break;
             // 欺骗编译器,勿删
             case COMMON_BLE_END_CMD:
             {
@@ -1066,8 +1055,8 @@ void Ble_Pairing_Handle(uint8_t *data ,uint16_t len, uint8_t host_type)
 }
 
 /*
-配网状态回复
-*/
+ *函数功能:配网状态回复
+ */
 void network_request_replay(uint8_t status)
 {
     //失败
@@ -1076,23 +1065,15 @@ void network_request_replay(uint8_t status)
         ESP_LOGI(COMMON_TAG, "network_request_replay is not connect\n");
         return;
     }
-    
-
-    // static BLE_SEND_REPLY_T wifi_pairing_reply={0};
-    // wifi_pairing_reply.send_flag = 1;
-    // wifi_pairing_reply.cmd = COMMON_BLE_NETWORK_STATUS_REPLAY_CMD;
-    // wifi_pairing_reply.len = 1;
-    // wifi_pairing_reply.content[0] = status;//下载证书失败
     uint8_t replay_buff[1]={0};
     memset(replay_buff,0,sizeof(replay_buff));
     replay_buff[0] = status;
     Ble_Pairing_Reply(COMMON_BLE_NETWORK_STATUS_REPLAY_CMD, replay_buff, 1, HOST_TYPE_BLE);
-    // Check_Host_Type(wifi_pairing_reply.cmd, wifi_pairing_reply.content, wifi_pairing_reply.len, HOST_TYPE_BLE);
 }
 
 #include "esp_chip_info.h"
 /*
-获取模组的芯片型号
+ *函数功能: 获取模组的芯片型号
 */
 static const char *CHIP_LOG = "CHIP_TAG";
 void get_chip_info(char *chip_id,uint8_t *chip_len)
@@ -1292,7 +1273,7 @@ void set_system_time_int_from_utc(int64_t utc_timestamp_sec,const char *zone)
     int32_t time_s = parse_utc_offset_min(zone)*60;
     Time_Zone = parse_utc_offset_2(zone);
     Time_Stamp = utc_timestamp_sec-time_s;//utc_timestamp_sec加了时区的时间戳 需要减去相对于的时区分钟数
-    ESP_LOGI("TIME","zone:%s utc_timestamp_sec:%ld TIME_ZONE=%ld Time_Zone:%d Time_Stamp=%ld",zone,(uint32_t)utc_timestamp_sec,time_s,Time_Zone,(uint32_t)Time_Stamp);
+    ESP_LOGI(COMMON_TAG,"zone:%s utc_timestamp_sec:%ld TIME_ZONE=%ld Time_Zone:%d Time_Stamp=%ld",zone,(uint32_t)utc_timestamp_sec,time_s,Time_Zone,(uint32_t)Time_Stamp);
     struct timeval tv;
     tv.tv_sec = utc_timestamp_sec;
     tv.tv_usec = 0;
@@ -1313,7 +1294,7 @@ void Get_Time(struct tm *time_out)
     time_t local = now + TIME_DEFAULT_ZONE_STAMP;
     localtime_r(&local,time_out);
     #if 1
-    ESP_LOGI("TIME", "time_out:%04d-%02d-%02d %02d:%02d:%02d", 
+    ESP_LOGI(COMMON_TAG, "time_out:%04d-%02d-%02d %02d:%02d:%02d", 
         time_out->tm_year+1900, \
         time_out->tm_mon+1,\
         time_out->tm_mday,\
@@ -1432,6 +1413,7 @@ void Esp32_Factory_Reset(void)
             {
                 //断开wifi
                 Wifi_Stop();
+                vTaskDelay(50 / portTICK_PERIOD_MS);
                 //断开mqtt释放资源
                 Mqtt_Disconnect();
                 vTaskDelay(50 / portTICK_PERIOD_MS);
index 9cbb50e..7835ea7 100644 (file)
 // 定义原始版本
 #define FW_VERSION_B        0x0101
 
+#define VERSION_MAX         9999
+#define VERSION_MAX_HEX     0x270F
 // 安全检查:如果大于 9999,强制改为 0x270F
-#if (FW_VERSION_B > 9999)
+#if (FW_VERSION_B >  VERSION_MAX_HEX)
 #undef  FW_VERSION_B
-#define FW_VERSION_B        0x270F
+#define FW_VERSION_B        VERSION_MAX_HEX
 #endif
 
 // 最终对外版本
-#define FW_VERSION                             (FW_VERSION_B)          // 固件版本 //10.22         // 固件版本 //10.22         // 固件版本 //10.22         // 固件版本 //0A00 10.00 10.21
+#define FW_VERSION                             (FW_VERSION_B >  VERSION_MAX_HEX ?  VERSION_MAX_HEX:FW_VERSION_B)               // 固件版本 //10.22         // 固件版本 //10.22         // 固件版本 //10.22         // 固件版本 //0A00 10.00 10.21
 #define BUILD_VERSION                  (0x000C)        // 编译测试版本
 #define DEVICE_VID                  (0x36E6)        // 设备厂商代码
 #define DEVICE_PID                  (0xEC01)        // 设备型号代码
@@ -472,7 +474,7 @@ typedef struct
     uint16_t pid_boot;
     uint8_t reserved3[8];
     
-    uint16_t fw_version;
+    uint16_t fw_version;//112
     uint16_t build_version;
     uint8_t reserved4[12];
     
index abfb236..2ab7923 100644 (file)
@@ -62,7 +62,6 @@ void Uart_Tx_Queue_Process(void)
     }
 }
 #define  RX_CACHE_MAX_LEN  1024
-//uart接收数据
 
 static uint8_t  rx_cache[RX_CACHE_MAX_LEN] = {0};
 static uint32_t rx_cache_len = 0;
@@ -356,7 +355,7 @@ void Uart_Pairing_Handle(uint8_t *data ,uint16_t len, uint8_t host_type)
                 {
                     common_setting.mcu_info.vid = *(uint16_t*)&data[3];
                     #if 1
-                    common_setting.mcu_info.pid = 0xA00D;//
+                    common_setting.mcu_info.pid = 0xA00D;//S
                     #else
                     common_setting.mcu_info.pid = *(uint16_t*)&data[5];
                     #endif
@@ -452,8 +451,6 @@ void Uart_Pairing_Handle(uint8_t *data ,uint16_t len, uint8_t host_type)
                 // data = data[3];
                 
                 uart_send_iot_data(data[1],&data[3],data[2]);
-                
-                
 
             }
             break;
@@ -660,7 +657,7 @@ int Uart_Reply_Send(uint8_t cmd, uint8_t* pbuf, uint8_t len, uint8_t host_type)
         ESP_LOGI(UART_SEND, "false\n");
         return 0;
     }else{
-        ESP_LOGI(UART_SEND, "true\n");
+        // ESP_LOGI(UART_SEND, "true\n");
         return 1;
     }
    
index 0babe3f..60fa3ff 100644 (file)
@@ -110,7 +110,8 @@ extern StaticQueue_t uart_tx_queue_buffer;
 // extern QueueHandle_t uart_rx_queue_handle;
 // extern StaticQueue_t uart_rx_queue_buffer;
 
-#define UART_TASK_STACK                 (1024+256)
+//不能改小 或者会影响usb 串口升级升级失败
+#define UART_TASK_STACK                 (2*1024)
 extern TaskHandle_t uart_task_handler;
 extern StackType_t uart_task_stack[UART_TASK_STACK];
 extern StaticTask_t uart_task_tcb;
index 25efb5e..197922a 100644 (file)
@@ -9,7 +9,10 @@ SemaphoreHandle_t user_flash_mutex;
 // static uint32_t user_flash_write[FLASH_SEC_SIZE/4] = {0};
 // static uint32_t user_flash_read[FLASH_SEC_SIZE/4] = {0};
 static uint32_t user_flash_data[FLASH_SEC_SIZE/sizeof(uint32_t)] = {0};
-
+/*
+ * 函数功能: 检查用户flash数据
+ */
+//a00f PXN1A8O0D45XD6
 void User_Flash_Check(void)
 {
        //寻找分区表
@@ -71,26 +74,9 @@ void User_Flash_Check(void)
 // struct timeval now;
 // gettimeofday(&now, NULL);
 
-// flash_time_t time_data;
-// time_data.utc_timestamp = now.tv_sec;
-// time_data.timezone_sec = timezone_hour * 3600; // 自动转秒
-
-
-// struct timeval tv = {
-//     .tv_sec = time_data.utc_timestamp,
-//     .tv_usec = 0
-// };
-// settimeofday(&tv, NULL);
-
-// // ==============================
-// // 关键:自动根据时区秒数设置时区
-// // ==============================
-// long tz_hour = (long)(time_data.timezone_sec/3600);
-// char tz_str[32];
-// sprintf(tz_str, "UTC%+ld", -tz_hour);
-// setenv("TZ", tz_str, 1);
-// tzset();
-//清除配网信息
+/*
+函数功能: 清除配网信息
+*/
 void User_Erase_Nimble_NetWork_Infor(void)
 {
        //清除配网信息
@@ -102,7 +88,9 @@ void User_Erase_Nimble_NetWork_Infor(void)
        User_Flash_Erase(UF_OFFSET_CERT_SERVER_CRT_ADDR,FLASH_SEC_SIZE);
 }
 
-//清除信息不需要重启设备
+/*
+函数功能: 清除信息不需要重启设备
+*/
 void User_Erase_NotReset(void)
 {
        ESP_LOGI(FLASH_TAG,"User_Erase_NotReset");
index 05e788b..b472a1c 100644 (file)
@@ -6,9 +6,9 @@
 #define CLOSE_HTTP_LOG  0
 static const char *HTTP_TAG = "http";
 /*
-func:http请求回调函数
-
-*/
+ * 函数功能: http请求回调函数
+ *
+ */
 static esp_err_t _http_event_handler(esp_http_client_event_t *evt)
 {
     switch (evt->event_id) {
@@ -65,48 +65,9 @@ static char http_download_cache[MAX_HTTP_OUTPUT_BUFFER+1] = {0};
 HTTP_GET_CERT_TASK_PARAM_T http_get_cert_task_param;
 static const char *HTTP_DOWNLOAD_TASK_TAG = "http_download_task";
 const esp_partition_t *s_ota_partition = NULL;
-esp_ota_handle_t s_ota_handle = 0;
-// 超轻量校验证书是否合法(只检查格式,几乎不占FLASH)
-bool is_valid_certificate(const char *cert)
-{
-    if (cert == NULL || strlen(cert) < 200) {
-        return false;
-    }
-
-    // 必须包含开头和结尾
-    if (strstr(cert, "-----BEGIN CERTIFICATE-----") == NULL) {
-        ESP_LOGI(HTTP_TAG,"HTTP CER ERR");
-        return false;
-    }
-    if (strstr(cert, "-----END CERTIFICATE-----") == NULL) {
-        ESP_LOGI(HTTP_TAG,"HTTP CER ERR");
-        return false;
-    }
-
-    return true;
-}
-
-// // 超轻量校验私钥是否合法
-// bool is_valid_private_key(const char *key)
-// {
-//     if (key == NULL || strlen(key) < 200) {
-//         return false;
-//     }
-
-//     if (strstr(key, "-----BEGIN RSA PRIVATE KEY-----") == NULL)
-//     {
-//         ESP_LOGI(HTTP_TAG,"HTTP KEY ERR");
-//         return false;
-//     }
-
-//     if (strstr(key, "-----END RSA PRIVATE KEY-----") == NULL)
-//     {
-//         ESP_LOGI(HTTP_TAG,"HTTP KEY ERR");
-//         return false;
-//     }
-
-//     return true;
-// }
+/*
+函数功能: https下载证书task回调函数
+*/
 static void Http_Download_Task_Cb(void *pvParameters)
 {
     if(common_setting.net_pairing_info.http_url_flag == 0 || common_setting.net_pairing_info.http_token_flag == 0 || common_setting.net_pairing_info.serial_number_flag == 0)
@@ -288,9 +249,8 @@ void Http_Download_Task(void){
 }
 
 /*
-
-func:获取绑定结果
-*/
+ * 函数功能: 获取绑定结果task回调函数
+ */
 static uint8_t get_bind_flag = 0;
 void Http_Get_Bind_Result(void *pvParameters)
 {
@@ -333,20 +293,30 @@ void Http_Get_Bind_Result(void *pvParameters)
         esp_http_client_set_header(http_client, "Authorization", (const char*)common_setting.net_pairing_info.http_token);
         esp_http_client_set_method(http_client, HTTP_METHOD_POST);
 
-        esp_err_t err = esp_http_client_perform(http_client);
+        esp_err_t err = esp_http_client_open(http_client, 0);
         if (err == ESP_OK)
         {
-            status_code = esp_http_client_get_status_code(http_client);
-            int read_len = esp_http_client_get_content_length(http_client);
-            if(status_code == 200)
+            
+            int header_ret = esp_http_client_fetch_headers(http_client);//获取HTTP响应头,返回值为响应头的总长度,如果返回值小于0表示获取响应头失败
+            if(header_ret >= 0)
             {
-                result =  1;
+                status_code = esp_http_client_get_status_code(http_client);
+                int read_len = esp_http_client_get_content_length(http_client);
+                if(status_code == 200)
+                {
+                    result =  1;
+                }
+                else
+                {
+                    result =  2;
+                }
+                ESP_LOGI(HTTP_TAG, "post bind %d", status_code, read_len);
             }
             else
             {
-                result =  2;
+                result = 2;
+                ESP_LOGE(HTTP_TAG, "post bind fetch header err: %s", esp_err_to_name(err));
             }
-            ESP_LOGI(HTTP_TAG, "post bind %d", status_code, read_len);
         }
         else
         {
@@ -376,7 +346,9 @@ void Http_Get_Bind_Result(void *pvParameters)
     vTaskDelete(NULL);
     
 }
-//获取绑定结果
+/*
+ * 函数功能: 获取绑定结果 task入口函数
+ */
 void Http_Get_Bing_Result_Task(void){
     ESP_LOGI(HTTP_TAG,"BIND TASK init\n");
     BaseType_t ret = xTaskCreate(Http_Get_Bind_Result, "http_get_bing_result_task", 2*1024, NULL, 2, NULL);
@@ -392,8 +364,8 @@ void Http_Get_Bing_Result_Task(void){
 #define HTTP_CHUNK_SIZE     512
 
 /*
-func:请求下发serialNumber 上传设备信息
-*/
+ * 函数功能: 请求下发serialNumber 上传设备信息
+ */
 static void Http_Get_Url_Task_Cb(void *pvParameters)
 {
     if(common_setting.net_pairing_info.http_url_flag == 0 || common_setting.net_pairing_info.http_token_flag == 0 || common_setting.net_pairing_info.user_id_flag == 0 || common_setting.mcu_info_got_flag == 0 || common_setting.net_pairing_info.http_url_length == 0 || common_setting.net_pairing_info.http_token_length == 0 || common_setting.net_pairing_info.http_url_length > HTTP_URL_MAX_LEN || common_setting.net_pairing_info.http_token_length > HTTP_TOKEN_MAX_LEN)
@@ -974,7 +946,9 @@ static void Http_Get_Url_Task_Cb(void *pvParameters)
     return;
 }
 
-//获取设备信息
+/*
+ * 函数功能: 获取设备信息 task入口函数
+ */
 void Http_Get_Url_Task(void){
     xTaskCreate(Http_Get_Url_Task_Cb, "http_get_url_task", HTTP_GET_URL_TASK_STACK, NULL, 2, NULL);
 }
@@ -982,8 +956,8 @@ void Http_Get_Url_Task(void){
 
 
 /*
-func:http请求状态检查
-*/
+ * 函数功能: http请求状态检查
+ */
 void Http_Download_Status_Check(void)
 {
     EventBits_t http_bits = xEventGroupWaitBits(common_event_group, COMMON_HTTP_DOWNLOAD_BIT | COMMON_HTTP_BIND_BIT |COMMON_HTTP_GET_URL_BIT, pdTRUE, pdFALSE, 0);
index cfa2979..26aabef 100644 (file)
@@ -44,6 +44,8 @@ static uint8_t mqtt_send_data_count = 0;
 static uint8_t mqtt_init_flag = 0;
 static char cloud_msgID[64]="cloud_0196415f3b1f7e2ab7f72c4e8f91c0a2";  //应答需要用云端下发的msgID
 static uint8_t mqtt_check_connect = 0;
+static uint32_t recv_time = 0;
+static uint32_t get_time = 0;
 static void log_error_if_nonzero(const char *message, int error_code)
 {
     if (error_code != 0) {
@@ -72,6 +74,7 @@ static void log_error_if_nonzero(const char *message, int error_code)
      TOPIC_PROPERTY_REPORT:设备上报
      TOPIC_SERVICE_POST:云端服务下发
      TOPIC_SERVICE_REPLY:设备服务应答
+     TOPIC_SERVICE_OTA_UPDATE:升级topic topic/PXN13BA1IJ7MB9/0xA00D/firmware/upgrade
 */ 
 char* get_publish_topic(TOPIC_TYPE type)
 {
@@ -81,23 +84,25 @@ char* get_publish_topic(TOPIC_TYPE type)
 
     const char *suffix = NULL;
     switch (type) {
-        case TOPIC_PROPERTY_ACK_POST:   suffix = "/ack/post" ;     break; //设备回复的·ack/post
-        case TOPIC_PROPERTY_SET:   suffix = "/property/set" ;     break; //云端下发
+        case TOPIC_PROPERTY_ACK_POST:   suffix = "property/post" ;     break; //设备回复的·ack/post
+        case TOPIC_PROPERTY_SET:   suffix = "property/set" ;     break; //云端下发
 
-        case TOPIC_PROPERTY_REPLY:   suffix = "/property/reply";    break; //设备回复
-        case TOPIC_PROPERTY_REPORT:  suffix = "/property/report";   break; //设备上报
-        case TOPIC_SERVICE_POST:     suffix = "/service/post";      break; //云端服务下发
-        case TOPIC_SERVICE_REPLY:    suffix = "/service/reply";     break; //设备服务应答
+        case TOPIC_PROPERTY_REPLY:   suffix = "property/reply";    break; //设备回复
+        case TOPIC_PROPERTY_REPORT:  suffix = "property/report";   break; //设备上报
+        case TOPIC_SERVICE_POST:     suffix = "service/post";      break; //云端服务下发
+        case TOPIC_SERVICE_REPLY:    suffix = "service/reply";     break; //设备服务应答
 
+
+        case TOPIC_FIRMWARE_OTA_UPGRADE:    suffix = "firmware/upgrade";     break; //ota报文
         default: return NULL;
     }
     #if PID_A00D
-    snprintf(pub_topic, sizeof(pub_topic)-1, "topic/%s/0x%04X%s",
+    snprintf(pub_topic, sizeof(pub_topic)-1, "topic/%s/0x%04X/%s",
         (char *)common_storage.net_info.serial_number,
         common_setting.mcu_info.pid,
         suffix);
     #else
-     snprintf(pub_topic, sizeof(pub_topic)-1, "topic/%s/%04X%s",
+     snprintf(pub_topic, sizeof(pub_topic)-1, "topic/%s/%04X/%s",
         (char *)common_storage.net_info.serial_number,
         common_setting.mcu_info.pid,
         suffix);
@@ -158,7 +163,7 @@ const char *get_methon(uint8_t methon_mode)
 #define MQTT_USER_DEFAULT_TOPIC     0
 static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data)
 {
-    ESP_LOGI(MQTT_TAG, "Event dispatched from event loop base=%s, event_id=%" PRIi32, base, event_id);
+    ESP_LOGI(MQTT_TAG, "base=%s, event_id=%" PRIi32, base, event_id);
     esp_mqtt_event_handle_t event = event_data;
     esp_mqtt_client_handle_t mqtt_client = event->client;
     int msg_id;
@@ -170,7 +175,7 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
         mqtt_send_data_count=0;
         common_setting.mqtt_user_cfg.mqtt_sub_flag = 0;
         common_setting.mqtt_user_cfg.mqtt_connect_flag = 1;
-        ESP_LOGI(MQTT_TAG, "send subscribe topic=%s  common_setting.mqtt_user_cfg.mqtt_start_flag=%d",get_publish_topic(TOPIC_PROPERTY_SET),common_setting.mqtt_user_cfg.mqtt_start_flag);
+        ESP_LOGI(MQTT_TAG, "set topic=%s",get_publish_topic(TOPIC_PROPERTY_SET));
         ESP_LOGI(MQTT_TAG, "MQTT_EVENT_CONNECTED");
         // /{pid}/{serialNumber}/property/post  
         #if MQTT_USER_DEFAULT_TOPIC
@@ -179,9 +184,9 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
         #else
         ESP_LOGI(MQTT_TAG, "subscribe topic=set");
         msg_id = esp_mqtt_client_subscribe(mqtt_client,get_publish_topic(TOPIC_PROPERTY_SET), 0);
-        ESP_LOGI(MQTT_TAG, "subscribe topic=post");
-        ESP_LOGI(MQTT_TAG, "send subscribe topic=%s  common_setting.mqtt_user_cfg.mqtt_start_flag=%d",get_publish_topic(TOPIC_PROPERTY_ACK_POST),common_setting.mqtt_user_cfg.mqtt_start_flag);
-        // msg_id = esp_mqtt_client_subscribe(mqtt_client,get_publish_topic(TOPIC_PROPERTY_ACK_POST), 0);
+        
+        ESP_LOGI(MQTT_TAG, "upgarde topic=%s",get_publish_topic(TOPIC_FIRMWARE_OTA_UPGRADE));
+        msg_id = esp_mqtt_client_subscribe(mqtt_client,get_publish_topic(TOPIC_FIRMWARE_OTA_UPGRADE), 0);
 
         if(common_setting.ble_status.is_bind == 1) // 连接mqtt请求一次http绑定接口做绑定 绑定失败配网失败 绑定成功配网成功
         {
@@ -218,8 +223,9 @@ static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_
         break;
 
     case MQTT_EVENT_DATA:
-        ESP_LOGI(MQTT_TAG, "TOPIC=%.*s\r\n", event->topic_len, event->topic);
-        ESP_LOGI(MQTT_TAG, "DATA=%.*s\r\n", event->data_len, event->data);
+        // ESP_LOGI(MQTT_TAG, "TOPIC=%.*s\r\n", event->topic_len, event->topic);
+        // ESP_LOGI(MQTT_TAG, "DATA=%.*s\r\n", event->data_len, event->data);
+        ESP_LOGI(MQTT_TAG, "DATA=%d %d\r\n", event->data_len, event->topic_len);
         Mqtt_Recv_Data(event->topic,event->topic_len,event->data,event->data_len);
         break;
 
@@ -375,7 +381,7 @@ static esp_err_t Mqtt_App_Init(void)
     mqtt_cfg.credentials.client_id = (const char *)common_storage.net_info.serial_number;
     #endif
     ESP_LOGI(MQTT_TAG, "Mqtt init %s",pid_str);
-    mqtt_cfg.task.priority = 1;
+    mqtt_cfg.task.priority = 4;
     mqtt_client_handle = esp_mqtt_client_init(&mqtt_cfg);
     if(mqtt_client_handle == NULL){
         ESP_LOGI(MQTT_TAG, "client_handle null\n");
@@ -566,18 +572,18 @@ void Mqtt_Recv_Data(char *topic, int topic_len, char *data, int data_len)
     msg.data_len = data_len;
     // ESP_LOGI(MQTT_TAG, "topic=%s data=%s\n",topic,data);
     if(mqtt_recv_queue_handle){
-        UBaseType_t queue_size = uxQueueMessagesWaiting(mqtt_recv_queue_handle);   // 当前已有几条消息
-        UBaseType_t queue_free = uxQueueSpacesAvailable(mqtt_recv_queue_handle);    // 剩余空间
+        // UBaseType_t queue_size = uxQueueMessagesWaiting(mqtt_recv_queue_handle);   // 当前已有几条消息
+        // UBaseType_t queue_free = uxQueueSpacesAvailable(mqtt_recv_queue_handle);    // 剩余空间
 
-        ESP_LOGW(MQTT_TAG, "queuremain = %d |  remain=%d", queue_size, queue_free);
+        // ESP_LOGW(MQTT_TAG, "queuremain = %d |  remain=%d", queue_size, queue_free);
         if (xQueueSend(mqtt_recv_queue_handle, &msg, 0) != pdPASS) {
-            ESP_LOGE(MQTT_TAG, "mqtt mqtt_recv_queue_handle queue is full \n");
+            ESP_LOGE(MQTT_TAG, "queue is full \n");
         }
         else{
-            ESP_LOGI(MQTT_TAG,"mqtt recv ok");
+            // ESP_LOGI(MQTT_TAG,"mqtt recv ok");
         }
     }else{
-        ESP_LOGI(MQTT_TAG,"mqtt_recv_queue_handle is null");
+        ESP_LOGI(MQTT_TAG,"mqtt is null");
     }
 }
 
@@ -590,10 +596,10 @@ void Mqtt_Connect_Status_Check(void)
     static uint8_t mqtt_init = 0;
     #if (!ENABLE_HTTP_N455_OTA_FUNC)
     if((xEventGroupWaitBits(common_event_group, COMMON_MQTT_CONNECT_BIT, pdFALSE, pdFALSE, 0) & COMMON_MQTT_CONNECT_BIT) != 0 && common_setting.ble_status.ble_state == 0\
-    &&(Https_Get_Ota_Status() == OTA_STATUS_IDLE))
+    &&(Https_Get_Ota_Status() == HTTPS_OTA_STATUS_IDLE))
     #else
     if((xEventGroupWaitBits(common_event_group, COMMON_MQTT_CONNECT_BIT, pdFALSE, pdFALSE, 0) & COMMON_MQTT_CONNECT_BIT) != 0 && common_setting.ble_status.ble_state == 0\
-    &&(Https_Get_Ota_Status() == OTA_STATUS_IDLE || N455_Get_Ota_Status() == N455_OTA_STATUS_IDLE))
+    &&(Https_Get_Ota_Status() == HTTPS_OTA_STATUS_IDLE || N455_Get_Ota_Status() == N455_OTA_STATUS_IDLE))
     #endif
     {
         xEventGroupClearBits(common_event_group, COMMON_MQTT_CONNECT_BIT);
@@ -653,6 +659,7 @@ void Mqtt_Connect_Status_Check(void)
         
         //断开wifi
         Wifi_Stop();
+        vTaskDelay(50 / portTICK_PERIOD_MS);
         //断开mqtt释放资源
         Mqtt_Disconnect();
         vTaskDelay(50 / portTICK_PERIOD_MS);
@@ -996,6 +1003,107 @@ char *get_test_json(void)
     cJSON_Delete(root);
     return out;
 }
+/*
+ *函数功能: ota报文解析
+ *参数array:数组[{},{}]
+*/
+void mqtt_ota_data_parse(const cJSON *array)
+{
+
+    //array
+    if(array == NULL || !cJSON_IsArray(array))
+    {
+        return;
+    }
+    uint16_t array_size = cJSON_GetArraySize(array);
+    if(array_size <= 0 || array_size <= 1)
+    {
+        ESP_LOGI(MQTT_TAG,"not arrary szie:%d",array_size);
+        return;
+    }
+    #if ENABLE_HTTPS_OTA_FUNC
+    Https_Ota_Clear_Update_Flag();
+    #endif
+    #if ENABLE_HTTP_N455_OTA_FUNC
+    N455_Ota_Clear_Update_Flag();
+    #endif
+    //只要有一个pid不对就不需要升级
+    uint8_t pid_check_flag = 0;
+    for (uint16_t i = 0; i < array_size; i++) //0-65535
+    {
+        pid_check_flag=0;
+        cJSON *item = cJSON_GetArrayItem(array, i);
+        if (item == NULL || !cJSON_IsObject(item)) {
+            ESP_LOGI(MQTT_TAG,"%d not object\n", i);
+            
+            continue;
+        }
+        cJSON *version = cJSON_GetObjectItem(item, "version");//
+        if(version == NULL || version->valuestring == NULL || !cJSON_IsString(version))
+        {
+            continue;
+        }
+        cJSON *filePath = cJSON_GetObjectItem(item, "filePath");//
+        if(filePath == NULL || filePath->valuestring == NULL || !cJSON_IsString(filePath))
+        {
+            continue;
+        }
+
+        cJSON *mcuCode = cJSON_GetObjectItem(item, "mcuCode");//
+        if(mcuCode == NULL || mcuCode->valuestring == NULL || !cJSON_IsString(mcuCode))
+        {
+            continue;
+        }
+        char mcu_pid[8] = {0};
+        snprintf(mcu_pid,sizeof(mcu_pid)-1,"0x%04X",common_setting.mcu_info.pid);
+
+        char esp_pid[8] = {0};
+        snprintf(esp_pid,sizeof(esp_pid)-1,"0x%04X",DEVICE_PID);
+        //主控的pid
+        if(strcmp(mcu_pid,mcuCode->valuestring) == 0)
+        {
+            pid_check_flag=1;
+            #if ENABLE_HTTPS_OTA_FUNC
+            Https_Ota_Version_Check(version->valuestring,filePath->valuestring);
+            #endif
+        }
+        //esp32 pid
+        else if(strcmp(esp_pid,mcuCode->valuestring) == 0)
+        {
+            pid_check_flag=1;
+            #if ENABLE_HTTP_N455_OTA_FUNC
+            N455_Ota_Version_Check(version->valuestring,filePath->valuestring);
+            #endif
+        }else{
+            //和本地一个都不匹配就视为无效的报文
+            break;
+        }
+        
+    }
+    if(pid_check_flag){
+        //先检查模组是否需要升级 不需要就检查主控是否需要升级
+        #if ENABLE_HTTPS_OTA_FUNC
+        if(Https_Ota_Get_Update_Flag())
+        {
+            //开始升级模组
+            Https_Ota_Start();
+            return;
+        }
+        #endif
+
+        #if ENABLE_HTTP_N455_OTA_FUNC
+        if(N455_Ota_Get_Update_Flag())
+        {
+            N455_Ota_Start();
+            return;
+        }
+        #endif
+    }else
+    {
+        ESP_LOGI(MQTT_TAG,"pid is null\n");
+    }
+    
+}
 /*
  * 函数功能:解析mqtt服务下发的原始数据
  * data:数据
@@ -1018,7 +1126,7 @@ void mqtt_parse_recv_data(char *topic, int topic_len,char *data, int data_len)
     }
     //请求方式
     
-    //===========清除配网指令=========================//
+    //1.===========清除配网指令=========================//
     cJSON *reset = cJSON_GetObjectItem(root , "otareset");//清除配网标识字符串 int
     if (reset != NULL && cJSON_IsNumber(reset)) {
         ESP_LOGI(MQTT_TAG, "otareset: %d", reset->valueint);
@@ -1036,6 +1144,7 @@ void mqtt_parse_recv_data(char *topic, int topic_len,char *data, int data_len)
             return;
         }
     }
+    //2.ota
     if (1) {
         //OTA升级
         cJSON *filePath = cJSON_GetObjectItem(root , "filePath");
@@ -1049,6 +1158,12 @@ void mqtt_parse_recv_data(char *topic, int topic_len,char *data, int data_len)
                     cJSON_Delete(root);
                     root=NULL;
                 }
+                if(Https_Ota_Get_Update_Flag())
+                {
+                    //开始升级模组
+                    Https_Ota_Start();
+                    return;
+                }
                 return;
                 
             }else{
@@ -1058,12 +1173,13 @@ void mqtt_parse_recv_data(char *topic, int topic_len,char *data, int data_len)
 
         }
     }
-
+    
     
     cJSON *payload_root  = cJSON_GetObjectItem(root, "data");//
     if (payload_root == NULL && !cJSON_IsObject(payload_root )) {
         ESP_LOGI(MQTT_TAG, "payload_root: ");
         cJSON_Delete(root);
+        root = NULL;
         return;
     }
     // {
@@ -1083,17 +1199,14 @@ void mqtt_parse_recv_data(char *topic, int topic_len,char *data, int data_len)
     //     }
     // }
     //
-    //灯光
-    //{"productId":"A00B","productName":"WGTL方向盘","prot":[{"736":"50"},{"737":"89"},{"738":"90"}]}
-    
-    // 示例 3:设备属性设置下行解析
+    //3:设备属性设置下行解析
     //解析 Topic
     
     //解析payload
     cJSON *payload = cJSON_GetObjectItem(payload_root, "payload");//
     if(payload == NULL || !cJSON_IsObject(payload))
     {
-        ESP_LOGI(MQTT_TAG, "payloa: ");
+        ESP_LOGI(MQTT_TAG, "payload: ");
         cJSON_Delete(root);
         root = NULL;
         return;
@@ -1117,28 +1230,29 @@ void mqtt_parse_recv_data(char *topic, int topic_len,char *data, int data_len)
         root = NULL;
         return;
     }
-
-    cJSON *productId = cJSON_GetObjectItem(payload, "productId");//
-    if (productId == NULL || !cJSON_IsString(productId) || productId->valuestring == NULL) {
+    
+    
+    // cJSON *productId = cJSON_GetObjectItem(payload, "productId");//
+    // if (productId == NULL || !cJSON_IsString(productId) || productId->valuestring == NULL) {
         
-        pid_serialNumber_replay_json(msgId->valuestring,NULL,method->valuestring,ERR_PID_SERIALNUMBER_ERR_CODE);
-        cJSON_Delete(root);
-        root = NULL;
-        ESP_LOGI(MQTT_TAG, "productId: ");
-        return;
-    }
-    else{
-        char pid_str[8] = {0};
-        snprintf(pid_str,sizeof(pid_str)-1,"%04X",common_setting.mcu_info.pid);
-        if(strcmp(pid_str,productId->valuestring) != 0)
-        {
-            pid_serialNumber_replay_json(msgId->valuestring,NULL,method->valuestring,ERR_PID_SERIALNUMBER_ERR_CODE);
-            cJSON_Delete(root);
-            root = NULL;
-            ESP_LOGI(MQTT_TAG, "productId 11: ");
-            return;
-        }
-    }
+    //     pid_serialNumber_replay_json(msgId->valuestring,NULL,method->valuestring,ERR_PID_SERIALNUMBER_ERR_CODE);
+    //     cJSON_Delete(root);
+    //     root = NULL;
+    //     ESP_LOGI(MQTT_TAG, "productId: ");
+    //     return;
+    // }
+    // else{
+    //     char pid_str[8] = {0};
+    //     snprintf(pid_str,sizeof(pid_str)-1,"%04X",common_setting.mcu_info.pid);
+    //     if(strcmp(pid_str,productId->valuestring) != 0)
+    //     {
+    //         pid_serialNumber_replay_json(msgId->valuestring,NULL,method->valuestring,ERR_PID_SERIALNUMBER_ERR_CODE);
+    //         cJSON_Delete(root);
+    //         root = NULL;
+    //         ESP_LOGI(MQTT_TAG, "productId 11: ");
+    //         return;
+    //     }
+    // }
 
     cJSON *serialNumber = cJSON_GetObjectItem(payload, "serialNumber");//
     if (serialNumber == NULL || !cJSON_IsString(serialNumber) || serialNumber->valuestring == NULL) {
@@ -1170,6 +1284,69 @@ void mqtt_parse_recv_data(char *topic, int topic_len,char *data, int data_len)
         }
     }
 
+    //topic/PAXN1LJ1QUR0781/A00B/property/update 升级topic
+    // {
+        
+    //     "data": {
+    //         "productId": 140,
+    //         "mqttProductId": "0xA00D",
+    //         "topic": "topic/PXN13BA1IJ7MB9/0xA00D/property/post",
+    //         "payload": {
+    //             "productId": "0xA00D",
+    //             "serialNumber": "PXN13BA1IJ7MB9",
+    //             "firmwareList": [
+    //                 {
+    //                     "firmwareId": 34,
+    //                     "firmwareName": "wgtl方向盘-N32G455VE",
+    //                     "firmwareNo": null,
+    //                     "productId": "0xA00D",
+    //                     "productName": "WGTL方向盘",
+    //                     "tenantId": 1,
+    //                     "tenantName": "13714325636",
+    //                     "isLatest": 0,
+    //                     "version": "1.05",
+    //                     "filePath": "https://pxn-iot.s3-accelerate.amazonaws.com/iot01/2026/06/03/6a1f95e5bfcb3c271127dd8b.bin",
+    //                     "mcuCode": "0xA00D",
+    //                     "mcuMain": 1,
+    //                     "serialNumber": "PXN13BA1IJ7MB9"
+    //                 },
+    //                 {
+    //                     "firmwareId": 25,
+    //                     "firmwareName": "wgtl方向盘-esp32",
+    //                     "firmwareNo": null,
+    //                     "productId": "0xEC01",
+    //                     "productName": "WGTL方向盘",
+    //                     "tenantId": 1,
+    //                     "tenantName": "13714325636",
+    //                     "isLatest": 1,
+    //                     "version": "1.04",
+    //                     "filePath": "https://pxn-iot.s3-accelerate.amazonaws.com/iot01/2026/05/08/69fdc1e57911f9a8d41169b4.bin",
+    //                     "mcuCode": "0xEC01",
+    //                     "mcuMain": 0,
+    //                     "serialNumber": "PXN13BA1IJ7MB9"
+    //                 }
+    //             ]
+    //         },
+    //         "taskDetailRows": 1,
+    //         "taskDetailId": 300
+    //     }
+
+    // }
+    if(strcmp(get_publish_topic(TOPIC_FIRMWARE_OTA_UPGRADE),topic) == 0)
+    {
+        cJSON *firmwareList = cJSON_GetObjectItem(payload, "firmwareList");//
+        if (firmwareList == NULL || !cJSON_IsArray(firmwareList)) {
+            
+            cJSON_Delete(root);
+            root = NULL;
+            return;
+        }
+        mqtt_ota_data_parse(firmwareList);
+        cJSON_Delete(root);
+        root = NULL;
+        return;
+    }
+    // get_publish_topic(TOPIC_PROPERTY_ACK_POST,topic_buf,sizeof(topic_buf)); 属性设置
     //topic/PAXN1LJ1QUR0781/A00B/property/post
     // data:{
     //     "msgId": "cloud_0196415f3b1f7e2ab7f72c4e8f91c0a1",
@@ -1179,13 +1356,10 @@ void mqtt_parse_recv_data(char *topic, int topic_len,char *data, int data_len)
     //     "productId": "A00B",
     //     "params": [{"8": 1,},{"735": 80}]
     // }
-
-    // get_publish_topic(TOPIC_PROPERTY_ACK_POST,topic_buf,sizeof(topic_buf)); 属性设置
-    if(strcmp(get_publish_topic(TOPIC_PROPERTY_SET),topic) == 0)
+    else if(strcmp(get_publish_topic(TOPIC_PROPERTY_SET),topic) == 0)
     {
         if(strcmp(get_methon(METHON_SERVICE_PROPERTY_SET),method->valuestring) == 0) //"thing.service.property.set" 服务下发属性设备参数
         {
-            ESP_LOGI(MQTT_TAG, "SET: ");
             if(strlen(msgId->valuestring) != 0)
             {
                 
@@ -1208,9 +1382,11 @@ void mqtt_parse_recv_data(char *topic, int topic_len,char *data, int data_len)
                 //     "message": "ok",
                     
                 // }
+                int code = ERR_CODE_OK;
+                
                
+                recv_time =  xTaskGetTickCount();
                 int ret = mqtt_set_dev_property(params);
-                int code = ERR_CODE_OK;
                 if(ret == 0)
                 {
                     code=ERR_UART_SEND_ERR_CODE;
@@ -1222,11 +1398,13 @@ void mqtt_parse_recv_data(char *topic, int topic_len,char *data, int data_len)
                     cJSON_Delete(replay_root);
                     replay_root = NULL;
                 }
+                cJSON_Delete(root);
+                root = NULL;
+                return;
             }
         }
         else if(strcmp(get_methon(METHON_SERVICE_PROPERTY_GET),method->valuestring) == 0) //"thing.service.property.set" 服务下发属性设备参数
         {
-            ESP_LOGI(MQTT_TAG, "GET: ");
             if(strlen(msgId->valuestring) != 0)
             {
                 
@@ -1240,6 +1418,9 @@ void mqtt_parse_recv_data(char *topic, int topic_len,char *data, int data_len)
                 }
                 mqtt_get_dev_property(params);
             }
+            cJSON_Delete(root);
+            root = NULL;
+            return;
         }
     }
     // {
@@ -1298,11 +1479,11 @@ void mqtt_parse_recv_data(char *topic, int topic_len,char *data, int data_len)
                     replay_root = NULL;
                 }
             }
+            cJSON_Delete(root);
+            root = NULL;
+            return;
         }
     }
-    // mqtt_get_dev_test(test_dpid,20);
-    //示例 4:设备属性上报下行解析
-    // mqtt_get_dev_property(root);
     // 释放
     
     if(root != NULL)
@@ -1313,10 +1494,12 @@ void mqtt_parse_recv_data(char *topic, int topic_len,char *data, int data_len)
     
 }
 
+
+
 /*
-func:云端下发设置设备属性值
-array:数组 [{"key":value},{"key":value},{"key":value}.............]
-*/
+ * 函数功能: 云端下发设置设备属性值
+ * array:数组 [{"key":value},{"key":value},{"key":value}.............]
+ */
 int mqtt_set_dev_property(const cJSON *array)
 {
 
@@ -1412,7 +1595,6 @@ int mqtt_set_dev_property(const cJSON *array)
         //总的长度加上4+当前数据类型的长度
         if(total_data_len + 5 + type_len > UART_REPLY_MAX_PAYLOAD_MQTT) //去掉header+cmd+len+crc
         {
-            vTaskDelay(5); 
             ret = Uart_Reply_Send(COMMON_UART_PROPERTY_SET_CMD,send_data, total_data_len,HOST_TYPE_UART);
             ESP_LOGI(MQTT_TAG,"set ret %d",ret);
             total_data_len=0;
@@ -1442,7 +1624,7 @@ int mqtt_set_dev_property(const cJSON *array)
     }
     if(total_data_len > 0)//发送最后一包
     {
-        vTaskDelay(5); 
+        
         ret = Uart_Reply_Send(COMMON_UART_PROPERTY_SET_CMD,send_data, total_data_len,HOST_TYPE_UART);
         ESP_LOGI(MQTT_TAG,"send ok:%d\n",ret);
         return ret;
@@ -1464,7 +1646,7 @@ int mqtt_get_dev_property(const cJSON *array)
     uint16_t array_size = cJSON_GetArraySize(array);
     if (array_size <= 0) return 0;
         // 取数组第i个元素(是一字符串数字)
-    ESP_LOGI(MQTT_TAG, "get array_size:%d",array_size);
+    
     if(array_size > 0)
     {
         uint8_t send_data[UART_REPLY_MAX_PAYLOAD_MQTT]={0};
@@ -1485,7 +1667,7 @@ int mqtt_get_dev_property(const cJSON *array)
             cJSON *item = cJSON_GetArrayItem(array, i);
             // ESP_LOGI(MQTT_TAG, " %d =%d | =%s",i,item ? item->type : -1,item ? item->valuestring : "null");
             if (item == NULL || !cJSON_IsString(item) || item->valuestring == NULL) {
-                ESP_LOGI(MQTT_TAG, "%d",i);
+                // ESP_LOGI(MQTT_TAG, "%d",i);
                 continue;
             }
             if(!is_pure_number(item->valuestring)) continue;
@@ -1503,11 +1685,10 @@ int mqtt_get_dev_property(const cJSON *array)
             }
             if(send_len+sizeof(uint16_t) > UART_REPLY_MAX_PAYLOAD_MQTT)
             {
-                vTaskDelay(5);
+                
                 ret = Uart_Reply_Send(COMMON_UART_PROPERTY_BATCH_REPORT_CMD,send_data, send_len,HOST_TYPE_UART);
                 send_len=0;
                 memset(send_data,0,UART_REPLY_MAX_PAYLOAD_MQTT);
-                ESP_LOGI(MQTT_TAG,"ret %d\n",ret);
                 if(ret == 0)
                 {
                     break;
@@ -1523,7 +1704,7 @@ int mqtt_get_dev_property(const cJSON *array)
         }
         if(send_len > 0)
         {
-            vTaskDelay(5);
+            
             ret = Uart_Reply_Send(COMMON_UART_PROPERTY_BATCH_REPORT_CMD,send_data, send_len,HOST_TYPE_UART);
             ESP_LOGI(MQTT_TAG,"end ret %d\n",ret);
             return ret;
@@ -1533,6 +1714,7 @@ int mqtt_get_dev_property(const cJSON *array)
             return 0;
         }
     }else{
+        ESP_LOGI(MQTT_TAG, "get array_size:%d",array_size);
         return 0;
     }
 }
@@ -1602,7 +1784,7 @@ uint8_t mqtt_send_publish_json(TOPIC_TYPE topic_type,cJSON *root)
 
     // memcpy(data_buf,json_str,strlen(json_str));
     // data_buf[strlen(json_str)]='\0';
-    ESP_LOGI(MQTT_TAG, "ack CJSON:%s %d topic=%s", json_str,strlen(json_str),topic);
+    ESP_LOGI(MQTT_TAG, "ack:%d topic=%s",strlen(json_str),topic);
     
 
     // memcpy(send_msg.topic,topic,strlen(topic));
@@ -1614,7 +1796,7 @@ uint8_t mqtt_send_publish_json(TOPIC_TYPE topic_type,cJSON *root)
     int js_len = strlen(json_str);
     if(js_len > MQTT_SEND_RECV_DATA_BUF_SIZE)
     {
-        ESP_LOGI(MQTT_TAG, "json_str too long:%d\n",js_len);
+        ESP_LOGI(MQTT_TAG, "too long:%d\n",js_len);
         free(json_str);
         json_str = NULL;
         return 0;
@@ -1624,11 +1806,11 @@ uint8_t mqtt_send_publish_json(TOPIC_TYPE topic_type,cJSON *root)
     json_str = NULL;
     if(ret == -1)
     {   
-        ESP_LOGI(MQTT_TAG, "publish faile \n");
+        ESP_LOGI(MQTT_TAG, "faile \n");
         return 0;
     }else{
         return 1;
-        ESP_LOGI(MQTT_TAG, "publish OK\n");
+        ESP_LOGI(MQTT_TAG, "OK\n");
     }
     
 }
@@ -1834,40 +2016,50 @@ uint8_t dev_report_property(uint8_t cmd,uint8_t *data,uint16_t len)
         return 0;
     }
     uint16_t offset = 0;
+    uint8_t creat_item = 0;
 
     cJSON *root = NULL;
-    switch (mode)
+    cJSON *prot_array = NULL;
+
+     if(root == NULL)
     {
-        case MODE_ACK:
-            root = create_publish_ack_json(publish_data.msgid,NULL,get_methon(METHON_SERVICE_PROPERTY_GET_REPLAY),ERR_CODE_OK);
-            /* code */
-            break;
-        case MODE_REPORT:
+        switch (mode)
+        {
+            case MODE_ACK:
+                root = create_publish_ack_json(publish_data.msgid,NULL,get_methon(METHON_SERVICE_PROPERTY_GET_REPLAY),ERR_CODE_OK);
+                /* code */
+                break;
+            case MODE_REPORT:
 
-            root = create_publish_post_json((const char *)get_devMsgId(),NULL,get_methon(METHON_EVENT_PROPERTY_POST));
-            break;
+                root = create_publish_post_json((const char *)get_devMsgId(),NULL,get_methon(METHON_EVENT_PROPERTY_POST));
+                break;
+            
+            default:
+                break;
+        }
         
-        default:
-            break;
-    }
-    
-    if (root == NULL) return 0;
-    
-    cJSON *prot_array = cJSON_CreateArray();
-    if(prot_array == NULL)
-    {
-        cJSON_Delete(root);
-        return 0;
+        if (root == NULL) return 0;
+        
+        prot_array = cJSON_CreateArray();
+        if(prot_array == NULL)
+        {
+            cJSON_Delete(root);
+            return 0;
+        }
+        cJSON_AddItemToObject(root, "params", prot_array);
     }
-    cJSON_AddItemToObject(root, "params", prot_array);
-    ESP_LOGI(MQTT_TAG,"offset+5=%d, len=%d\n",offset+5,len);
+    // ESP_LOGI(MQTT_TAG,"offset+5=%d, len=%d\n",offset+5,len);
     while (1)
     {
+        creat_item = 0;
                if(offset+5 > len)
                {
                        // ESP_LOGI(MQTT_TAG,"offset+5=%d, len=%d\n",offset+5,len);
                        break;
                }
+       
+            
+    
         // 1. 取 DPID (2个字节) //
         uint16_t dpid = 0;
         memcpy(&dpid, &data[offset], sizeof(uint16_t));
@@ -1895,7 +2087,6 @@ uint8_t dev_report_property(uint8_t cmd,uint8_t *data,uint16_t len)
                if (current_json_len + expect_add_len >= 512)
         {
             // 发送旧包
-            // ESP_LOGI(MQTT_TAG,"current_json_len=%d, expect_add_len=%d\n",current_json_len,expect_add_len);
             switch (mode)
             {
                 case MODE_ACK:
@@ -1910,10 +2101,10 @@ uint8_t dev_report_property(uint8_t cmd,uint8_t *data,uint16_t len)
                     break;
             }
             
-            vTaskDelay(5);
             // 销毁旧包,建新包
             cJSON_Delete(root);
             root = NULL;
+            uint32_t old = 0;
             switch (mode)
             {
                 case MODE_ACK:
@@ -1928,7 +2119,6 @@ uint8_t dev_report_property(uint8_t cmd,uint8_t *data,uint16_t len)
                     break;
             }
             
-    
             if (root == NULL) return 0;
             
             prot_array = cJSON_CreateArray();
@@ -1944,6 +2134,7 @@ uint8_t dev_report_property(uint8_t cmd,uint8_t *data,uint16_t len)
         cJSON *item = cJSON_CreateObject();
         if(item == NULL)
         {
+            creat_item=1;
             break;
         }
         if(dpid == 6) //dpid==6是模组的serialNumber 不使用传参的value 使用本地的数据添加json
@@ -1974,22 +2165,27 @@ uint8_t dev_report_property(uint8_t cmd,uint8_t *data,uint16_t len)
     // 发送最后一包
     if (root != NULL)
     {
-       switch (mode)
+        if(!creat_item) //如果创建item失败就不必要发送了 以防发送空的数组
         {
-            case MODE_ACK:
-                mqtt_send_publish_json(TOPIC_PROPERTY_ACK_POST,root);
-                /* code */
-                break;
-            case MODE_REPORT:
-                mqtt_send_publish_json(TOPIC_PROPERTY_REPORT,root);
-                break;
-            
-            default:
-                break;
-        } 
+            switch (mode)
+            {
+                case MODE_ACK:
+                    mqtt_send_publish_json(TOPIC_PROPERTY_ACK_POST,root);
+                    /* code */
+                    break;
+                case MODE_REPORT:
+                    mqtt_send_publish_json(TOPIC_PROPERTY_REPORT,root);
+                    break;
+                
+                default:
+                    break;
+            } 
+        }
         cJSON_Delete(root);
+        root=NULL;
     }
-   
+    
+    get_time = 0;
     root=NULL;
     return 1;
 }
@@ -2003,7 +2199,7 @@ uint8_t dev_report_property(uint8_t cmd,uint8_t *data,uint16_t len)
  */
 uint8_t uart_send_iot_data(uint8_t cmd,uint8_t *data,uint16_t len)
 {
-    ESP_LOGI(MQTT_TAG, "uart_send_iot_data cmd: %d\n",cmd);
+    // ESP_LOGI(MQTT_TAG, "uart_send_iot_data cmd: %d\n",cmd);
     if(data == NULL || len == 0 || mqtt_dev_report_queue_handle == NULL)
     {
         return 0;
@@ -2031,7 +2227,6 @@ int user_esp_mqtt_client_publish(char *data,uint16_t data_len,char *topic)
     }
     int ret = esp_mqtt_client_publish(mqtt_client_handle,topic,\
     data,data_len,0, 0 );
-    ESP_LOGI(MQTT_TAG, "esp_mqtt_client_publish ret :%d\n",ret);
     return ret;
 
 }
@@ -2040,23 +2235,19 @@ int user_esp_mqtt_client_publish(char *data,uint16_t data_len,char *topic)
 */
 static void Mqtt_Init_Task_Cb(void *p)
 {
-    static mqtt_recv_msg_t recv_msg;
-    static mqtt_dev_report_msg_t send_msg;
+    static mqtt_recv_msg_t recv_msg={0};
+    static mqtt_dev_report_msg_t send_msg={0};
     while (1)
     {
         if(mqtt_recv_queue_handle != NULL){
             if(xQueueReceive(mqtt_recv_queue_handle, &recv_msg, 0) == pdTRUE)
             {
-                // ESP_LOGI(MQTT_TAG, "mqtt recv data");
                 // ESP_LOGI(MQTT_TAG, "主题:%d", recv_msg.topic_len);
                 // ESP_LOGI(MQTT_TAG, "数据:%d", recv_msg.data_len);
                 mqtt_parse_recv_data(recv_msg.topic,recv_msg.topic_len,recv_msg.data,recv_msg.data_len);
-                // =============================================
-
-                // 1. JSON 解析
             }
         }
-        //设备上报
+        //设备属性上报 包含属性获取
         if(mqtt_dev_report_queue_handle != NULL){
             if (xQueueReceive(mqtt_dev_report_queue_handle, &send_msg, 0) == pdTRUE) {
                 if (Mqtt_Get_Connect_Flag()) 
@@ -2074,7 +2265,7 @@ static void Mqtt_Init_Task_Cb(void *p)
                 }
             }
         }
-        vTaskDelay(2/ portTICK_PERIOD_MS);
+        vTaskDelay(1/ portTICK_PERIOD_MS);
     }
 }
 
@@ -2091,7 +2282,7 @@ void Mqtt_Init_Task(void)
     mqtt_recv_queue_handle = xQueueCreateStatic(MQTT_RECV_QUEUE_LENGTH, MQTT_RECV_QUEUE_ITEM_SIZE, mqtt_recv_queue_storage, &mqtt_recv_queue_buffer);
     mqtt_dev_report_queue_handle = xQueueCreateStatic(MQTT_SEND_QUEUE_LENGTH, MQTT_SEND_QUEUE_ITEM_SIZE, mqtt_dev_report_queue_storage, &mqtt_dev_report_queue_buffer);
     
-    mqtt_connect_task_handler = xTaskCreateStatic(Mqtt_Init_Task_Cb, "mqtt_task", MQTT_CONNECT_TASK_STACK, NULL, 1, mqtt_connect_task_stack, &mqtt_connect_task_tcb);
+    mqtt_connect_task_handler = xTaskCreateStatic(Mqtt_Init_Task_Cb, "mqtt_task", MQTT_CONNECT_TASK_STACK, NULL, 4, mqtt_connect_task_stack, &mqtt_connect_task_tcb);
 }
 
 
index 6492f5f..5cf81e6 100644 (file)
@@ -28,7 +28,8 @@ typedef enum {
     TOPIC_PROPERTY_REPORT,   // 主动上报
     
     TOPIC_SERVICE_POST,        //服务下发
-    TOPIC_SERVICE_REPLY      // 服务应答
+    TOPIC_SERVICE_REPLY,      // 服务应答
+    TOPIC_FIRMWARE_OTA_UPGRADE    //ota报文
 } TOPIC_TYPE;
 
 
@@ -114,5 +115,6 @@ cJSON* pid_serialNumber_replay_json(const char* msgId,const char* service_id, co
 uint8_t mqtt_send_publish_json(TOPIC_TYPE topic_type,cJSON *root);
 void mqtt_parse_recv_data(char *topic, int topic_len,char *data, int data_len);
 void mqtt_check_isconnect(void);
+void mqtt_ota_data_parse(const cJSON *array);
 #endif
 #endif
\ No newline at end of file
index f0a11c3..4f8695e 100644 (file)
@@ -55,6 +55,7 @@ esp_netif_t *wifi_sta_netif = NULL;
 #define WIFI_FAIL_BIT           BIT1
 #define WIFI_AP_NOT_FOUND_BIT   BIT2
 #define WIFI_PWD_FAIL_BIT       BIT3
+#define WIFI_CONNECT_TIMEOUT_BIT BIT4
 
 static const char *WIFI_TAG = "wifi station";
 
@@ -62,8 +63,10 @@ static int s_retry_num = 0;
 static uint32_t wifi_connect_retry_max = 0xFFFFFFFF;//EXAMPLE_ESP_MAXIMUM_RETRY;
 
 SemaphoreHandle_t wifi_scan_mutex;
-
-//获取wifi的rssi事件处理函数
+static volatile uint8_t wifi_connect_timeout_flag = 0;  // 1=超时
+/*
+ * 函数功能: 获取wifi的rssi事件处理函数
+*/
 static void esp_bss_rssi_low_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
 {
     wifi_event_bss_rssi_low_t *event = event_data;
@@ -72,7 +75,9 @@ static void esp_bss_rssi_low_handler(void* arg, esp_event_base_t event_base, int
     common_setting.wifi_status.rssi = event->rssi;
 }
 
-// wifi事件处理函数 断开 连接 获取ip等事件都会进入这个函数
+/*
+ * 函数功能: wifi事件处理函数 断开 连接 获取ip等事件都会进入这个函数
+ */
 static void event_handler(void* arg, esp_event_base_t event_base,
                                 int32_t event_id, void* event_data)
 {
@@ -136,7 +141,6 @@ static void event_handler(void* arg, esp_event_base_t event_base,
                         xEventGroupSetBits(s_wifi_event_group, WIFI_PWD_FAIL_BIT);
                     }
                     xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
-                    
                 }
                 ESP_LOGI(WIFI_TAG,"connect to the AP fail");
                 common_setting.wifi_status.wifi_state = 0;
@@ -150,11 +154,13 @@ static void event_handler(void* arg, esp_event_base_t event_base,
         {
             case IP_EVENT_STA_GOT_IP://连接路由成功获取ip地址事件
             {
+                
                 ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
                 ESP_LOGI(WIFI_TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
                 s_retry_num = 0;
                 common_setting.wifi_status.wifi_state = 1;
                 Wifi_Connect_Timerout_Stop();//连接成功了就关闭定时器
+                wifi_connect_timeout_flag = 0;//连接成功了就把超时标志清零
                 #define USER_TMP 0
                 #if USER_TMP
 
@@ -208,7 +214,11 @@ static void event_handler(void* arg, esp_event_base_t event_base,
     }
     
 }
-
+/*
+ * 函数功能: wifi初始化函数
+ * 该函数负责初始化WiFi模块,包括创建事件组、初始化网络接口、注册事件处理函数等。它还会设置WiFi的工作模式和配置,并启动WiFi连接。通过调用该函数,设备将能够连接到指定的WiFi网络,并处理相关的事件,如连接成功、连接失败、获取IP地址等。
+ * 在函数中,首先创建了一个事件组用于管理WiFi连接状态。然后初始化了默认的WiFi站点网络接口,并配置了WiFi的初始化参数。接下来,注册了WiFi事件和IP事件的处理函数,以便在发生相关事件时能够正确地处理。最后,设置了WiFi的工作模式和配置,并启动了WiFi连接。
+*/
 void Wifi_Sta_Init(void)
 {
     s_wifi_event_group = xEventGroupCreate();
@@ -242,34 +252,21 @@ void Wifi_Sta_Init(void)
 }
 
 #define SEC_TO_US(sec)   ((sec) * 1000000ULL)
-static void Wifi_connect_timerout_callback(void* arg)
-{
-    // ESP_LOGI(WIFI_TAG, "One-time timer triggered after 80 s");
-    // xEventGroupSetBits(ble_event_group, BLE_OFF_BIT);//超时了就关闭ble,停止配网,除非重启设备或者app下发wifi信息重新配网
-    network_request_replay(NETWORK_CONECT_WIFI_TIMEOUT_REPLAY);
-}
+/*
+ * 函数功能: wifi连接超时回调函数
+ * 该函数是一个定时器回调函数,当WiFi连接超时时会被调用。在函数中,可以执行一些操作来处理连接超时的情况,例如发送网络连接超时的消息、重置WiFi连接状态等。通过调用该函数,可以实现对WiFi连接超时事件的处理,以便在连接失败时能够及时做出响应。
+*/
+
 static esp_timer_handle_t wifi_one_timer_handle;//创建定时器handle
 static uint8_t wifi_one_timer_flag = 0;//0:未创建  1:已创建
-void Wifi_Connect_Timerout_Start(void)
+void Wifi_Connect_Set_Flag(void)
 {
     if(common_setting.wifi_status.connect_mode != 2)//只有用户配网才开启定时器
     {
         return;
     }
     #if (1)
-    if(common_setting.wifi_status.connect_mode == 2)
-    {
-        // Create and start one-time timer for 80 ms
     
-        const esp_timer_create_args_t one_time_timer_args = {
-            .callback = &Wifi_connect_timerout_callback,
-            .arg = NULL,
-            .name = "one_time_timer"
-        };
-        esp_timer_create(&one_time_timer_args, &wifi_one_timer_handle);
-        esp_timer_start_once(wifi_one_timer_handle, SEC_TO_US(80)); // 80 s in microseconds 根据客户自定义修改超时时间
-        wifi_one_timer_flag = 1;
-    }
     
     #endif
 }
@@ -307,7 +304,14 @@ void Wifi_Start(void)
     ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
     ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &common_setting.wifi_config));
     s_retry_num = 0;
-    Wifi_Connect_Timerout_Start();
+   if(common_setting.wifi_status.connect_mode == 2)
+    {
+        // Create and start one-time timer for 80 ms
+        if(common_setting.ble_status.ble_adv_flag > 0) //蓝牙开启说明在配网状态 如果在设定的时间内没有连上就发送超时蓝牙指令
+        {
+            wifi_connect_timeout_flag = 1;
+        }
+    }
     ESP_ERROR_CHECK(esp_wifi_start());
     common_setting.wifi_status.wifi_mode = 2;
     
@@ -456,6 +460,11 @@ typedef struct
 
 #define WIFI_SCAN_PACKET_WIFI_NUM        6
 #define DEFAULT_SCAN_LIST_SIZE          24
+/*
+ * 函数功能: wifi扫描任务
+ * 
+ *
+*/
 void Wifi_Scan_Task(void *pvParameters)
 {
     static BLE_SEND_REPLY_T wifi_scan_reply = {0};
@@ -602,6 +611,14 @@ void Wifi_Scan_Task(void *pvParameters)
     vTaskDelete(NULL);
 }
 
+/*
+ *函数功能: wifi事件发送函数
+ *该函数将wifi事件相关的信息(如连接状态、加密配置等) 通过队列发送给Wifi_Enable_Status_Check函数进行处理。根据传入的参数,函数会将相应的信息写入队列,并触发Wifi_Enable_Status_Check函数中的事件处理逻辑,以便执行相应的操作,如启动或停止wifi连接、发送蓝牙数据等。
+ *参数说明:
+ * @param host: 事件来源
+ * @param enable: 事件使能标志
+ * @param net_pair_encrypt_profile: 网络配对加密配置
+ */
 void Wifi_Queue_Send(uint8_t host, uint8_t enable, uint8_t net_pair_encrypt_profile)
 {
     ESP_LOGI(WIFI_TAG, "Wifi_Queue_Send %d %d %d\n",host,enable,net_pair_encrypt_profile);
@@ -611,6 +628,15 @@ void Wifi_Queue_Send(uint8_t host, uint8_t enable, uint8_t net_pair_encrypt_prof
     xQueueSend(wifi_queue_handle, wifi_queue_write, 0);
 }
 
+/*
+ *  函数功能: wifi连接状态检查和处理函数
+ * 处理wifi连接成功、连接失败、扫描wifi列表等事件,并根据事件类型执行相应的操作,如启动或停止wifi连接、发送蓝牙数据等。
+ * 该函数还会监听wifi事件组中的连接状态位,并在状态变化时执行相应的处理逻辑。
+ * 
+ *
+*/
+
+#define WIFI_CONNECT_TIMEOUT_CNT  18 //用于配网相当于5s重连一次 总共是18*5 = 80s 现在wifi重连机制时间是5s重连一次
 void Wifi_Enable_Status_Check(void)
 {
     static uint8_t wifi_queue_read[WIFI_QUEUE_ITEM_SIZE] = {0}; // byte0:0:本地   2:串口   3:蓝牙     byte1:1:厂测连接   2:用户配网   3:正常连接   4:扫描wifi列表   0xFF:关闭
@@ -650,7 +676,7 @@ void Wifi_Enable_Status_Check(void)
             {
                 common_setting.wifi_status.connect_mode = 2;
                 common_setting.wifi_status.net_pair_encrypt_profile = wifi_queue_read[2];
-                wifi_connect_retry_max = EXAMPLE_ESP_MAXIMUM_RETRY;
+                wifi_connect_retry_max = WIFI_CONNECT_TIMEOUT_CNT;//3 18*5 = 80s
                 Wifi_Start();
             }
         }
@@ -684,6 +710,7 @@ void Wifi_Enable_Status_Check(void)
         {
             xEventGroupClearBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
             ESP_LOGI(WIFI_TAG, "wifi connected %d\n",common_setting.wifi_status.connect_mode);
+            wifi_connect_timeout_flag=0;
             Wifi_Connect_Timerout_Stop();//关闭定时器
             #if (1)
             if((common_setting.wifi_status.connect_mode == 1 || common_setting.wifi_status.connect_mode == 2))
@@ -744,7 +771,7 @@ void Wifi_Enable_Status_Check(void)
         else if (bits & WIFI_FAIL_BIT)
         {
             
-            ESP_LOGI(WIFI_TAG, "wifi connect fail\n");
+            ESP_LOGI(WIFI_TAG, "wifi connect fail %d\n",wifi_connect_timeout_flag);
             Wifi_Connect_Timerout_Stop();//连接失败了就关闭定时器
             if((common_setting.wifi_status.connect_mode == 1 || common_setting.wifi_status.connect_mode == 2))
             {
@@ -775,6 +802,17 @@ void Wifi_Enable_Status_Check(void)
                 replay_buff[1] = common_setting.wifi_status.connect_mode-1;
                 replay_buff[2] = common_setting.wifi_status.net_pair_encrypt_profile;
                 Ble_Pairing_Reply(0x15, replay_buff, 3, HOST_TYPE_BLE);
+
+                if(common_setting.ble_status.ble_adv_flag > 0) //蓝牙开启说明在配网状态 如果在设定的时间内没有连上就发送超时蓝牙指令
+                {
+                    if(wifi_connect_timeout_flag && common_setting.wifi_status.connect_mode == 2) //2是用户配网模式
+                    {
+                        wifi_connect_timeout_flag=0;
+                        network_request_replay(NETWORK_CONECT_WIFI_TIMEOUT_REPLAY);
+                        common_setting.wifi_status.connect_mode = 0;
+                        Wifi_Stop();
+                    }
+                }
             }
         }
         else
@@ -782,7 +820,6 @@ void Wifi_Enable_Status_Check(void)
             ESP_LOGI(WIFI_TAG, "wifi stop\n");
         }
     }
-
     if(common_setting.wifi_status.wifi_state == 1)
     {
         static uint32_t rssi_tick = 0;