espressif / esp-mesh-lite

A lite version Wi-Fi Mesh, each node can access the network over the IP layer.
135 stars 24 forks source link

Ota conformation on how to deploy.... (AEGHB-682) #95

Open ThatBigPrint opened 5 months ago

ThatBigPrint commented 5 months ago

hi guys I'm back this is my function for the OTA but i don't think its working it is downloading and deploying on the root but i think im missing something for the non root nodes ?


{
    ESP_LOGI(TAG, "Starting Advanced OTA example");

    esp_err_t ota_finish_err = ESP_OK;
    esp_http_client_config_t config = {
        .url = "",
        .method = HTTP_METHOD_GET,
        .crt_bundle_attach = esp_crt_bundle_attach,
        .event_handler = _http_event_handler,
        .keep_alive_enable = true,
    };

    esp_https_ota_config_t ota_config = {
        .http_config = &config,
        .http_client_init_cb = _http_client_init_cb, // Register a callback to be invoked after esp_http_client is initialized
    };

    esp_https_ota_handle_t https_ota_handle = NULL;
    esp_err_t err = esp_https_ota_begin(&ota_config, &https_ota_handle);
    if (err != ESP_OK)
    {
        ESP_LOGE(TAG, "ESP HTTPS OTA Begin failed");
        vTaskDelete(NULL);
    }

    esp_app_desc_t app_desc;
    err = esp_https_ota_get_img_desc(https_ota_handle, &app_desc);
    if (err != ESP_OK)
    {
        ESP_LOGE(TAG, "esp_https_ota_read_img_desc failed");
        goto ota_end;
    }
    err = validate_image_header(&app_desc);
    if (err != ESP_OK)
    {
        ESP_LOGE(TAG, "image header verification failed");
        goto ota_end;
    }

    // Root node, start the OTA process
    if (esp_mesh_lite_get_level() >= 1)
    {

        while (1)
        {
            if (esp_mesh_lite_wait_ota_allow() != ESP_OK)
            {
                err = ESP_FAIL;
                break;
            }
            err = esp_https_ota_perform(https_ota_handle);
            if (err != ESP_ERR_HTTPS_OTA_IN_PROGRESS)
            {
                break;
            }

            // Report OTA progress to Firebase
            int image_len_read = esp_https_ota_get_image_len_read(https_ota_handle);
            int total_size = esp_https_ota_get_image_size(https_ota_handle);
            float progress = (float)image_len_read / total_size * 100;
            ESP_LOGI(TAG, "OTA Progress: %.2f%%", progress);
            // 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_LOGD(TAG, "Image bytes read: %d", esp_https_ota_get_image_len_read(https_ota_handle));
        }

        ESP_LOGE(TAG, "root node, start the OTA process");
        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_LOGE(TAG, "Complete data was not received.");
        }
        else
        {
            ota_finish_err = esp_https_ota_finish(https_ota_handle);
            if ((err == ESP_OK) && (ota_finish_err == ESP_OK))
            {
                ESP_LOGI(TAG, "ESP_HTTPS_OTA upgrade successful. Rebooting ...");

                // Get the size of the updated firmware
                int filesize = esp_https_ota_get_image_size(https_ota_handle);

                // Propagate the update to child nodes
                esp_mesh_lite_file_transmit_config_t transmit_config = {
                    .type = ESP_MESH_LITE_OTA_TRANSMIT_FIRMWARE,
                    .size = filesize,
                    .extern_url_ota_cb = https_ota_handle,
                };
                memcpy(transmit_config.fw_version, app_desc.version, sizeof(transmit_config.fw_version));
                esp_mesh_lite_transmit_file_start(&transmit_config);

                vTaskDelay(1000 / portTICK_PERIOD_MS);
                esp_restart();
            }
            else
            {
                if (ota_finish_err == ESP_ERR_OTA_VALIDATE_FAILED)
                {
                    ESP_LOGE(TAG, "Image validation failed, image is corrupted");
                }
                ESP_LOGE(TAG, "ESP_HTTPS_OTA upgrade failed 0x%x", ota_finish_err);
                vTaskDelete(NULL);
            }
        }
    }
    else

    {
        esp_mesh_lite_ota_notify_child_node_pause();
    }

ota_end:
    esp_https_ota_abort(https_ota_handle);
    ESP_LOGE(TAG, "ESP_HTTPS_OTA upgrade failed");
    vTaskDelete(NULL);
}```
tswen commented 5 months ago

After the device receives the OTA upgrade command, the device needs to determine whether to perform OTA directly through https ota or through esp_mesh_lite_transmit_file_start according to the layer

if (esp_mesh_lite_get_level() > 1) {
        esp_mesh_lite_file_transmit_config_t transmit_config = {
            .type = ESP_MESH_LITE_OTA_TRANSMIT_FIRMWARE,
            .fw_version = "6e90e2",
            .size = 890880,
            .extern_url_ota_cb = NULL,
         };
         esp_mesh_lite_transmit_file_start(&transmit_config);
}
ThatBigPrint commented 5 months ago

So what I did was almost correct? so below correct? if not can you point to the issues ?


static esp_err_t validate_image_header(esp_app_desc_t *new_app_info)
{
    if (new_app_info == NULL)
    {
        return ESP_ERR_INVALID_ARG;
    }

    const esp_partition_t *running = esp_ota_get_running_partition();
    esp_app_desc_t running_app_info;
    if (esp_ota_get_partition_description(running, &running_app_info) == ESP_OK)
    {
        ESP_LOGI(TAG, "Running firmware version: %s", running_app_info.version);
    }

    // get the version of the new firmware to pass it to the mesh network
    ESP_LOGI(TAG, "New firmware version: %s", new_app_info->version);

    // get the size of the new firmware to pass it to the mesh network

    // if (memcmp(new_app_info->version, running_app_info.version, sizeof(new_app_info->version)) == 0)
    //{
    //     ESP_LOGW(TAG, "Current running version is the same as a new. We will not continue the update.");
    // return ESP_FAIL;
    //}

    return ESP_OK;
}

static esp_err_t _http_client_init_cb(esp_http_client_handle_t http_client)
{
    esp_err_t err = ESP_OK;
    /* Uncomment to add custom headers to HTTP request */
    // err = esp_http_client_set_header(http_client, "Custom-Header", "Value");
    return err;
}
void advanced_ota_example_task(void *pvParameter)
{
    ESP_LOGI(TAG, "Starting Advanced OTA example");

    ota_started = true;

    esp_err_t ota_finish_err = ESP_OK;
    esp_http_client_config_t config = {
        .url = "",
        .method = HTTP_METHOD_GET,
        .crt_bundle_attach = esp_crt_bundle_attach,
        .event_handler = _http_event_handler,
        .keep_alive_enable = false,
    };

    esp_https_ota_config_t ota_config = {
        .http_config = &config,
        .http_client_init_cb = _http_client_init_cb, // Register a callback to be invoked after esp_http_client is initialized
    };

    esp_https_ota_handle_t https_ota_handle = NULL;
    esp_err_t err = esp_https_ota_begin(&ota_config, &https_ota_handle);
    if (err != ESP_OK)
    {
        ESP_LOGE(TAG, "ESP HTTPS OTA Begin failed");
        vTaskDelete(NULL);
    }

    esp_app_desc_t app_desc;
    err = esp_https_ota_get_img_desc(https_ota_handle, &app_desc);
    if (err != ESP_OK)
    {
        ESP_LOGE(TAG, "esp_https_ota_read_img_desc failed");
        goto ota_end;
    }
    err = validate_image_header(&app_desc);
    if (err != ESP_OK)
    {
        ESP_LOGE(TAG, "image header verification failed");
        goto ota_end;
    }

    // Root node, start the OTA process
    if (esp_mesh_lite_get_level() >= 1)
    {

        while (1)
        {
            if (esp_mesh_lite_wait_ota_allow() != ESP_OK)
            {
                err = ESP_FAIL;
                break;
            }
            err = esp_https_ota_perform(https_ota_handle);
            if (err != ESP_ERR_HTTPS_OTA_IN_PROGRESS)
            {
                break;
            }

            // Report OTA progress to Firebase
            int image_len_read = esp_https_ota_get_image_len_read(https_ota_handle);
            int total_size = esp_https_ota_get_image_size(https_ota_handle);
            float progress = (float)image_len_read / total_size * 100;
            ESP_LOGI(TAG, "OTA Progress: %.2f%%", progress);
            // 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_LOGD(TAG, "Image bytes read: %d", esp_https_ota_get_image_len_read(https_ota_handle));
            vTaskDelay(10 / portTICK_PERIOD_MS);
        }

        ESP_LOGE(TAG, "root node, start the OTA process");
        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_LOGE(TAG, "Complete data was not received.");
        }
        else
        {
            ota_finish_err = esp_https_ota_finish(https_ota_handle);
            if ((err == ESP_OK) && (ota_finish_err == ESP_OK))
            {
                ESP_LOGI(TAG, "ESP_HTTPS_OTA upgrade successful. Rebooting ...");

                esp_http_client_cleanup(outbound_client);
                esp_http_client_cleanup(client);
                // Get the size of the updated firmware
                int filesize = esp_https_ota_get_image_size(https_ota_handle);

                ESP_LOGI(TAG, "Firmware size: %d", filesize);

                char *new_version = app_desc.version;

                ESP_LOGI(TAG, "New firmware version: %s", new_version);

                // Get the version of the updated firmware
                // char *new_version = app_desc.version;
                // ESP_LOGI(TAG, "New firmware version: %s", new_version);

                // Get the version of the current firmware
                // char *app_version = running_app_info.version;
                //

                // Propagate the update to child nodes
                esp_mesh_lite_file_transmit_config_t transmit_config = {
                    .type = ESP_MESH_LITE_OTA_TRANSMIT_FIRMWARE,
                    .size = filesize,
                    .extern_url_ota_cb = https_ota_handle,
                };
                memcpy(transmit_config.fw_version, app_desc.version, sizeof(transmit_config.fw_version));

                ESP_LOGI(TAG, "Propagating the update to child nodes");
                ESP_LOGI(TAG, "Firmware version: %s", transmit_config.fw_version);

                esp_mesh_lite_transmit_file_start(&transmit_config);

                vTaskDelay(1000 / portTICK_PERIOD_MS);
                esp_restart();
            }
            else
            {
                if (ota_finish_err == ESP_ERR_OTA_VALIDATE_FAILED)
                {
                    ESP_LOGE(TAG, "Image validation failed, image is corrupted");
                }
                ESP_LOGE(TAG, "ESP_HTTPS_OTA upgrade failed 0x%x", ota_finish_err);
                vTaskDelete(NULL);
            }
        }
    }
    else

    {
        esp_mesh_lite_ota_notify_child_node_pause();
    }

ota_end:
    esp_https_ota_abort(https_ota_handle);
    ESP_LOGE(TAG, "ESP_HTTPS_OTA upgrade failed");
    vTaskDelete(NULL);
}
tswen commented 5 months ago

The device level should be determined before executing esp_https_ota_begin. If it is a root node, execute esp_https_ota_begin. If it is a child node, execute LAN OTA.

ThatBigPrint commented 5 months ago

other than that it should work. i remember getting an error for the name header ?

tswen commented 5 months ago

Is there any log information?