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; i32RetHTTPClient = HTTPS_CLIENT_ERROR;
bRetriveData = false; bRetriveData = false;
} }
} }
return i32RetHTTPClient; 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 https_clientDeinitialize()
{ {
https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK; 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; https_client_ret_t i32RetHTTPClient = HTTPS_CLIENT_OK;
int32_t i32RetEmbedTLS = ESP_OK; int32_t i32RetEmbedTLS = ESP_OK;
static bool bAlreadySetup = false;
mbedtls_ssl_init(&sHTTPS_ClientConfig.ssl); mbedtls_ssl_init(&sHTTPS_ClientConfig.ssl);
mbedtls_x509_crt_init(&sHTTPS_ClientConfig.cacert); 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_ca_chain(&sHTTPS_ClientConfig.conf, &sHTTPS_ClientConfig.cacert, NULL);
mbedtls_ssl_conf_rng(&sHTTPS_ClientConfig.conf, mbedtls_ctr_drbg_random, &sHTTPS_ClientConfig.ctr_drbg); 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 (bAlreadySetup == false) //check if mbedtls_ssl_setup was called before
{
i32RetEmbedTLS = mbedtls_ssl_setup(&sHTTPS_ClientConfig.ssl, &sHTTPS_ClientConfig.conf); //call this only once
if(i32RetEmbedTLS != ESP_OK) if(i32RetEmbedTLS != ESP_OK)
{ {
ESP_LOGE(TAG, "mbedtls_ssl_setup returned -0x%x\n\n", i32RetEmbedTLS); 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) if(i32RetEmbedTLS == ESP_OK)

View File

@ -128,28 +128,56 @@ void vTaskOTAWorker(void *arg)
void vTaskServerWorker(void *arg) void vTaskServerWorker(void *arg)
{ {
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
{
// if(bFirstRun == true)
// {
ERROR_CHECK(https_clientInitialize());
// bFirstRun = false;
//}
ERROR_CHECK(errOTAHTTPS(&bNewOTAImage));
https_clientDeinitialize();
// https_clientReset();
if(bNewOTAImage == true)
{
//set want reboot
ESP_LOGI(LOG_TAG, "Updated successfully via HTTPS, will reboot if possible");
}
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; esp_err_t err = ESP_OK;
uint32_t u32BufferLenght = 1024U;
char buffer[1024U]; char buffer[1024U];
uint32_t u32BufferLenght = 1024U;
uint32_t u32BytesRead = 0; uint32_t u32BytesRead = 0;
char pcRemoteVersionNumber[12]; char pcRemoteVersionNumber[12];
const esp_partition_t * currentPartition; const esp_partition_t * currentPartition;
const esp_partition_t * otaPartition; const esp_partition_t * otaPartition;
static esp_ota_handle_t otaHandle; static esp_ota_handle_t otaHandle;
uint32_t u32StartOffset; uint32_t u32StartOffset;
esp_app_desc_t otaPartitionDesc; //esp_app_desc_t otaPartitionDesc;
esp_app_desc_t curPartitionDesc;
while(true)
{
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");
//server get version
currentPartition = esp_ota_get_boot_partition(); currentPartition = esp_ota_get_boot_partition();
ESP_LOGI(LOG_TAG, "Type: %d", (*currentPartition).subtype); ESP_LOGI(LOG_TAG, "Type: %d", (*currentPartition).subtype);
@ -157,76 +185,92 @@ void vTaskServerWorker(void *arg)
ESP_LOGI(LOG_TAG, "Size: %d", (*currentPartition).size); ESP_LOGI(LOG_TAG, "Size: %d", (*currentPartition).size);
ESP_LOGI(LOG_TAG, "Encrypted: %d", (*currentPartition).encrypted); ESP_LOGI(LOG_TAG, "Encrypted: %d", (*currentPartition).encrypted);
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(); ERROR_CHECK(esp_ota_get_partition_description(currentPartition, &curPartitionDesc));
https_clientRetrieveData(buffer, &u32BufferLenght, &u32BytesRead); //ESP_LOGI(LOG_TAG, "currentPartition project_name: %s", (curPartitionDesc).project_name);
ESP_LOGI(LOG_TAG, "Data received: %i", u32BytesRead); //ESP_LOGI(LOG_TAG, "currentPartition version: %s", (curPartitionDesc).version);
err = errExtractVersionNumber(buffer, &u32BytesRead, pcRemoteVersionNumber); //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(err == ESP_OK)
{ {
if(bNewerVersion((curPartitionDesc).version, pcRemoteVersionNumber)) if(bNewerVersion((curPartitionDesc).version, pcRemoteVersionNumber)) //compare local and remote version
{ {
ESP_LOGI(LOG_TAG, "Newer Version available"); // server image is newer --> OTA update required
//write ota ESP_LOGI(LOG_TAG, "server image is newer --> OTA update required");
otaPartition = esp_ota_get_next_update_partition(currentPartition); otaPartition = esp_ota_get_next_update_partition(currentPartition);
err = errFindImageStart(buffer, &u32BufferLenght, &u32StartOffset); if(otaPartition == NULL)
{
err = ESP_FAIL;
ESP_LOGE(LOG_TAG, "unable to get next ota partition");
}
ESP_LOGI(LOG_TAG, "first byte offset: %i", u32StartOffset); ERROR_CHECK(errFindImageStart(buffer, &u32BufferLenght, &u32StartOffset)); //get image start offset
ESP_LOGI(LOG_TAG, "first byte: %x", buffer[u32StartOffset]);
err = esp_ota_begin(otaPartition, OTA_SIZE_UNKNOWN, &otaHandle); //ESP_LOGI(LOG_TAG, "first byte offset: %i", u32StartOffset);
ESP_ERROR_CHECK(err); //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 do
{ {
ESP_LOGI(LOG_TAG, "OTA-Data written: %i", u32BytesRead); ESP_LOGI(LOG_TAG, "OTA-Data written: %i", u32BytesRead);
err = esp_ota_write(otaHandle, (const void*) buffer+u32StartOffset, (u32BytesRead-u32StartOffset)); ERROR_CHECK(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); if(err == ESP_OK)
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"); //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 else
{ {
ESP_LOGI(LOG_TAG, "errExtractVersionNumber failed: %i", err); // error occurred --> abort ota update process
ESP_LOGE(LOG_TAG, "abort ota process");
ERROR_CHECK(esp_ota_abort(otaHandle));
*pbNewOTAImage = false; //ota update failed
} }
https_clientDeinitialize(); //TODO unlock ota mutex
//ota update if newer } //end newer version on server
} //end version number extracted
//lock ota mutex
vTaskDelay( (SERVER_CHECK_INTERVAL*1000) / portTICK_PERIOD_MS); //sleep till next server check
} return err;
}
} }
/* /*
* 999.999.999
* Return true if remote version is newer (higher) than local version * Return true if remote version is newer (higher) than local version
*/ */
bool bNewerVersion(const char* pu8Local, const char* pu8Remote) 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_clientInitialize();
https_client_ret_t https_clientRetrieveData(char* pu8Data, uint32_t* pu32DataLenght, uint32_t* pu32BytesRead); 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(); https_client_ret_t https_clientDeinitialize();
#endif /* H_HTTPS_CLIENT */ #endif /* H_HTTPS_CLIENT */

View File

@ -32,6 +32,8 @@
esp_err_t errMeshOTAInitialize(); esp_err_t errMeshOTAInitialize();
esp_err_t errOTAHTTPS(bool* pbNewOTAImage);
//helper functions //helper functions
bool bNewerVersion(const char* pu8Local, const char* pu8Remote); bool bNewerVersion(const char* pu8Local, const char* pu8Remote);
esp_err_t errExtractVersionNumber(const char* pu8Data, uint32_t* pu32DataLenght, char* pc8RemoteVersionNumber); esp_err_t errExtractVersionNumber(const char* pu8Data, uint32_t* pu32DataLenght, char* pc8RemoteVersionNumber);