From c542dc05abddac1487a1f4ed25dbcd5684ffa9d6 Mon Sep 17 00:00:00 2001 From: localhorst Date: Mon, 18 Jan 2021 12:49:52 +0100 Subject: [PATCH] cleanup https ota --- components/mesh_ota/HTTPS_client.c | 31 +++- components/mesh_ota/Mesh_OTA.c | 198 +++++++++++++-------- components/mesh_ota/include/HTTPS_client.h | 1 + components/mesh_ota/include/Mesh_OTA.h | 2 + 4 files changed, 152 insertions(+), 80 deletions(-) diff --git a/components/mesh_ota/HTTPS_client.c b/components/mesh_ota/HTTPS_client.c index 40fd597..d273704 100644 --- a/components/mesh_ota/HTTPS_client.c +++ b/components/mesh_ota/HTTPS_client.c @@ -111,10 +111,20 @@ https_client_ret_t https_clientRetrieveData(char* pu8Data, uint32_t* pu32DataLen i32RetHTTPClient = HTTPS_CLIENT_ERROR; bRetriveData = false; } + } return i32RetHTTPClient; } +https_client_ret_t https_clientReset() +{ + https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK; + + i32RetHTTPClient = https_clientSendRequest(); + + return i32RetHTTPClient; +} + https_client_ret_t https_clientDeinitialize() { https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK; @@ -137,6 +147,7 @@ https_client_ret_t https_clientInitEmbedTLS() https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK; int32_t i32RetEmbedTLS = ESP_OK; + static bool bAlreadySetup = false; mbedtls_ssl_init(&sHTTPS_ClientConfig.ssl); mbedtls_x509_crt_init(&sHTTPS_ClientConfig.cacert); @@ -191,11 +202,25 @@ https_client_ret_t https_clientInitEmbedTLS() mbedtls_ssl_conf_ca_chain(&sHTTPS_ClientConfig.conf, &sHTTPS_ClientConfig.cacert, NULL); mbedtls_ssl_conf_rng(&sHTTPS_ClientConfig.conf, mbedtls_ctr_drbg_random, &sHTTPS_ClientConfig.ctr_drbg); - i32RetEmbedTLS = mbedtls_ssl_setup(&sHTTPS_ClientConfig.ssl, &sHTTPS_ClientConfig.conf); - if(i32RetEmbedTLS != ESP_OK) + if (bAlreadySetup == false) //check if mbedtls_ssl_setup was called before { - ESP_LOGE(TAG, "mbedtls_ssl_setup returned -0x%x\n\n", i32RetEmbedTLS); + i32RetEmbedTLS = mbedtls_ssl_setup(&sHTTPS_ClientConfig.ssl, &sHTTPS_ClientConfig.conf); //call this only once + if(i32RetEmbedTLS != ESP_OK) + { + ESP_LOGE(TAG, "mbedtls_ssl_setup returned 0x%x\n\n", i32RetEmbedTLS); + + // uint8_t buffer[20]; + //mbedtls_strerror(i32RetEmbedTLS, buffer, 20); + //ESP_LOGE(TAG, "%s", buffer); + } + else + { + bAlreadySetup = true; + } + } + + } if(i32RetEmbedTLS == ESP_OK) diff --git a/components/mesh_ota/Mesh_OTA.c b/components/mesh_ota/Mesh_OTA.c index 4496bed..5ec0713 100644 --- a/components/mesh_ota/Mesh_OTA.c +++ b/components/mesh_ota/Mesh_OTA.c @@ -128,105 +128,149 @@ void vTaskOTAWorker(void *arg) void vTaskServerWorker(void *arg) { - - esp_err_t err = ESP_OK; - uint32_t u32BufferLenght = 1024U; - char buffer[1024U]; - uint32_t u32BytesRead = 0; - char pcRemoteVersionNumber[12]; - const esp_partition_t * currentPartition; - const esp_partition_t * otaPartition; - static esp_ota_handle_t otaHandle; - uint32_t u32StartOffset; - esp_app_desc_t otaPartitionDesc; + esp_err_t err; + bool bNewOTAImage = false; // true if a new ota image was downloaded and validated + // bool bFirstRun = true; while(true) { + err = ESP_OK; xSemaphoreTake(bsStartStopServerWorker, portMAX_DELAY); //wait for binary semaphore that allows to start the worker xSemaphoreGive(bsStartStopServerWorker); //free binary semaphore, this allows the handler to change is to taken if (esp_mesh_is_root()) //check again that this node is the root node { - ESP_LOGI(LOG_TAG, "DEMO HTTP request"); + // if(bFirstRun == true) + // { + ERROR_CHECK(https_clientInitialize()); + // bFirstRun = false; + //} - //server get version + ERROR_CHECK(errOTAHTTPS(&bNewOTAImage)); + https_clientDeinitialize(); - currentPartition = esp_ota_get_boot_partition(); - ESP_LOGI(LOG_TAG, "Type: %d", (*currentPartition).subtype); - ESP_LOGI(LOG_TAG, "Start address: %d", (*currentPartition).address); - ESP_LOGI(LOG_TAG, "Size: %d", (*currentPartition).size); - ESP_LOGI(LOG_TAG, "Encrypted: %d", (*currentPartition).encrypted); + // https_clientReset(); - esp_app_desc_t curPartitionDesc; - err = esp_ota_get_partition_description(currentPartition, &curPartitionDesc); - ESP_ERROR_CHECK(err); - ESP_LOGI(LOG_TAG, "currentPartition project_name: %s", (curPartitionDesc).project_name); - ESP_LOGI(LOG_TAG, "currentPartition version: %s", (curPartitionDesc).version); - ESP_LOGI(LOG_TAG, "currentPartition Timestamp: %s %s", (curPartitionDesc).date, (curPartitionDesc).time); - - https_clientInitialize(); - https_clientRetrieveData(buffer, &u32BufferLenght, &u32BytesRead); - ESP_LOGI(LOG_TAG, "Data received: %i", u32BytesRead); - err = errExtractVersionNumber(buffer, &u32BytesRead, pcRemoteVersionNumber); - - if(err == ESP_OK) + if(bNewOTAImage == true) { - if(bNewerVersion((curPartitionDesc).version, pcRemoteVersionNumber)) - { - ESP_LOGI(LOG_TAG, "Newer Version available"); - //write ota - otaPartition= esp_ota_get_next_update_partition(currentPartition); - - err = errFindImageStart(buffer, &u32BufferLenght, &u32StartOffset); - - ESP_LOGI(LOG_TAG, "first byte offset: %i", u32StartOffset); - ESP_LOGI(LOG_TAG, "first byte: %x", buffer[u32StartOffset]); - - err = esp_ota_begin(otaPartition, OTA_SIZE_UNKNOWN, &otaHandle); - ESP_ERROR_CHECK(err); - - do - { - ESP_LOGI(LOG_TAG, "OTA-Data written: %i", u32BytesRead); - err = esp_ota_write(otaHandle, (const void*) buffer+u32StartOffset, (u32BytesRead-u32StartOffset)); - u32StartOffset = 0U; - https_clientRetrieveData(buffer, &u32BufferLenght, &u32BytesRead); - } - while (u32BytesRead > 0); - - err = esp_ota_end(otaHandle); - ESP_ERROR_CHECK(err); - - err = esp_ota_get_partition_description(otaPartition, &otaPartitionDesc); - ESP_ERROR_CHECK(err); - ESP_LOGI(LOG_TAG, "otaPartition project_name: %s", (otaPartitionDesc).project_name); - err = esp_ota_set_boot_partition(otaPartition); - ESP_ERROR_CHECK(err); - //esp_restart(); - } - else - { - ESP_LOGI(LOG_TAG, "NO newer Version available"); - } - } - else - { - ESP_LOGI(LOG_TAG, "errExtractVersionNumber failed: %i", err); + //set want reboot + ESP_LOGI(LOG_TAG, "Updated successfully via HTTPS, will reboot if possible"); } - https_clientDeinitialize(); - //ota update if newer - - //lock ota mutex vTaskDelay( (SERVER_CHECK_INTERVAL*1000) / portTICK_PERIOD_MS); //sleep till next server check } } } +esp_err_t errOTAHTTPS(bool* pbNewOTAImage) +{ + esp_err_t err = ESP_OK; + char buffer[1024U]; + uint32_t u32BufferLenght = 1024U; + uint32_t u32BytesRead = 0; + char pcRemoteVersionNumber[12]; + const esp_partition_t * currentPartition; + const esp_partition_t * otaPartition; + static esp_ota_handle_t otaHandle; + uint32_t u32StartOffset; + //esp_app_desc_t otaPartitionDesc; + esp_app_desc_t curPartitionDesc; + + + currentPartition = esp_ota_get_boot_partition(); + ESP_LOGI(LOG_TAG, "Type: %d", (*currentPartition).subtype); + ESP_LOGI(LOG_TAG, "Start address: %d", (*currentPartition).address); + ESP_LOGI(LOG_TAG, "Size: %d", (*currentPartition).size); + ESP_LOGI(LOG_TAG, "Encrypted: %d", (*currentPartition).encrypted); + + + ERROR_CHECK(esp_ota_get_partition_description(currentPartition, &curPartitionDesc)); + //ESP_LOGI(LOG_TAG, "currentPartition project_name: %s", (curPartitionDesc).project_name); + //ESP_LOGI(LOG_TAG, "currentPartition version: %s", (curPartitionDesc).version); + //ESP_LOGI(LOG_TAG, "currentPartition Timestamp: %s %s", (curPartitionDesc).date, (curPartitionDesc).time); + + + + ERROR_CHECK(https_clientRetrieveData(buffer, &u32BufferLenght, &u32BytesRead)); //read first bytes if image, including the version + + //ESP_LOGI(LOG_TAG, "Data received: %i", u32BytesRead); + + ERROR_CHECK(errExtractVersionNumber(buffer, &u32BytesRead, pcRemoteVersionNumber)); + + if(err == ESP_OK) + { + if(bNewerVersion((curPartitionDesc).version, pcRemoteVersionNumber)) //compare local and remote version + { + // server image is newer --> OTA update required + ESP_LOGI(LOG_TAG, "server image is newer --> OTA update required"); + + otaPartition = esp_ota_get_next_update_partition(currentPartition); + + if(otaPartition == NULL) + { + err = ESP_FAIL; + ESP_LOGE(LOG_TAG, "unable to get next ota partition"); + } + + ERROR_CHECK(errFindImageStart(buffer, &u32BufferLenght, &u32StartOffset)); //get image start offset + + //ESP_LOGI(LOG_TAG, "first byte offset: %i", u32StartOffset); + //ESP_LOGI(LOG_TAG, "first byte: %x", buffer[u32StartOffset]); + + //TODO lock ota mutex + + ERROR_CHECK(esp_ota_begin(otaPartition, OTA_SIZE_UNKNOWN, &otaHandle)); + + if(err == ESP_OK) + { + //image download and ota partition write + do + { + ESP_LOGI(LOG_TAG, "OTA-Data written: %i", u32BytesRead); + ERROR_CHECK(esp_ota_write(otaHandle, (const void*) buffer+u32StartOffset, (u32BytesRead-u32StartOffset))); + + if(err == ESP_OK) + { + //write was succsesfull + u32StartOffset = 0U; //reset the offset for next download + https_clientRetrieveData(buffer, &u32BufferLenght, &u32BytesRead); //download next data segment + } + } + while ((u32BytesRead > 0) && (err == ESP_OK)); + } + + if(err == ESP_OK) + { + //no error occurred --> finish ota update process + ERROR_CHECK(esp_ota_end(otaHandle)); //finish process + ERROR_CHECK(esp_ota_set_boot_partition(otaPartition)); //set new image as boot + if(err == ESP_OK) + { + *pbNewOTAImage = true; //image validated + } + } + else + { + // error occurred --> abort ota update process + ESP_LOGE(LOG_TAG, "abort ota process"); + ERROR_CHECK(esp_ota_abort(otaHandle)); + *pbNewOTAImage = false; //ota update failed + } + + //TODO unlock ota mutex + + } //end newer version on server + } //end version number extracted + + + + return err; +} + + /* - * 999.999.999 * Return true if remote version is newer (higher) than local version */ bool bNewerVersion(const char* pu8Local, const char* pu8Remote) diff --git a/components/mesh_ota/include/HTTPS_client.h b/components/mesh_ota/include/HTTPS_client.h index f2c9252..889363a 100644 --- a/components/mesh_ota/include/HTTPS_client.h +++ b/components/mesh_ota/include/HTTPS_client.h @@ -66,6 +66,7 @@ typedef struct HTTPS_Client HTTPS_Client_t; https_client_ret_t https_clientInitialize(); https_client_ret_t https_clientRetrieveData(char* pu8Data, uint32_t* pu32DataLenght, uint32_t* pu32BytesRead); +https_client_ret_t https_clientReset(); https_client_ret_t https_clientDeinitialize(); #endif /* H_HTTPS_CLIENT */ diff --git a/components/mesh_ota/include/Mesh_OTA.h b/components/mesh_ota/include/Mesh_OTA.h index 343baec..fece273 100644 --- a/components/mesh_ota/include/Mesh_OTA.h +++ b/components/mesh_ota/include/Mesh_OTA.h @@ -32,6 +32,8 @@ esp_err_t errMeshOTAInitialize(); +esp_err_t errOTAHTTPS(bool* pbNewOTAImage); + //helper functions bool bNewerVersion(const char* pu8Local, const char* pu8Remote); esp_err_t errExtractVersionNumber(const char* pu8Data, uint32_t* pu32DataLenght, char* pc8RemoteVersionNumber);