cleanup https ota

This commit is contained in:
Hendrik Schutter 2021-01-18 12:49:52 +01:00
parent cf99410893
commit c542dc05ab
4 changed files with 152 additions and 80 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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 */

View File

@ -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);