Browse Source

cleanup https ota

feature/blockingOTA
Hendrik Schutter 1 year ago
parent
commit
c542dc05ab
  1. 31
      components/mesh_ota/HTTPS_client.c
  2. 168
      components/mesh_ota/Mesh_OTA.c
  3. 1
      components/mesh_ota/include/HTTPS_client.h
  4. 2
      components/mesh_ota/include/Mesh_OTA.h

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

168
components/mesh_ota/Mesh_OTA.c

@ -128,105 +128,149 @@ void vTaskOTAWorker(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;
uint32_t u32BufferLenght = 1024U;
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 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");
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);
//server get version
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);
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)
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)
{
if(bNewerVersion((curPartitionDesc).version, pcRemoteVersionNumber))
{
ESP_LOGI(LOG_TAG, "Newer Version available");
//write ota
otaPartition= esp_ota_get_next_update_partition(currentPartition);
err = ESP_FAIL;
ESP_LOGE(LOG_TAG, "unable to get next ota partition");
}
err = errFindImageStart(buffer, &u32BufferLenght, &u32StartOffset);
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]);
//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);
//TODO lock ota mutex
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);
ERROR_CHECK(esp_ota_begin(otaPartition, OTA_SIZE_UNKNOWN, &otaHandle));
err = esp_ota_end(otaHandle);
ESP_ERROR_CHECK(err);
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)));
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();
if(err == ESP_OK)
{
//write was succsesfull
u32StartOffset = 0U; //reset the offset for next download
https_clientRetrieveData(buffer, &u32BufferLenght, &u32BytesRead); //download next data segment
}
}
else
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)
{
ESP_LOGI(LOG_TAG, "NO newer Version available");
*pbNewOTAImage = true; //image validated
}
}
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
*/
bool bNewerVersion(const char* pu8Local, const char* pu8Remote)

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

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

Loading…
Cancel
Save

Du besuchst diese Seite mit einem veralteten IPv4-Internetzugang. Möglicherweise treten in Zukunft Probleme mit der Erreichbarkeit und Performance auf. Bitte frage deinen Internetanbieter oder Netzwerkadministrator nach IPv6-Unterstützung.
You are visiting this site with an outdated IPv4 internet access. You may experience problems with accessibility and performance in the future. Please ask your ISP or network administrator for IPv6 support.
Weitere Infos | More Information
Klicke zum schließen | Click to close