cleanup https ota
This commit is contained in:
		| @ -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) | ||||
|  | ||||
| @ -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) | ||||
|  | ||||
| @ -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 */ | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user