completet https ota

This commit is contained in:
2021-01-18 17:38:08 +01:00
parent c542dc05ab
commit a0546aa3ef
4 changed files with 72 additions and 125 deletions

View File

@ -8,6 +8,8 @@ xQueueHandle queueMessageOTA; //mesh ota controll messages like "OTA_Version_Res
SemaphoreHandle_t bsStartStopServerWorker; //binary semaphore
const esp_partition_t* pOTAPartition; //pointer to ota partition
esp_err_t errMeshOTAInitialize()
{
esp_err_t err = ESP_OK;
@ -46,6 +48,17 @@ esp_err_t errMeshOTAInitialize()
ERROR_CHECK(errMeshNetworkSetOTAMessageHandleHandle(vAddOTAControllMessageToQueue));
ERROR_CHECK(errMeshNetworkSetChangeStateOfServerWorkerHandle(vChangeStateOfServerWorker));
if(err == ESP_OK)
{
pOTAPartition = esp_ota_get_next_update_partition(NULL); //get ota partition
if(pOTAPartition == NULL)
{
err = ESP_FAIL;
ESP_LOGE(LOG_TAG, "unable to get next ota partition");
}
}
if(err == ESP_OK)
{
xReturned = xTaskCreate(vTaskServerWorker, "vTaskServerWorker", 8192, NULL, 5, NULL);
@ -130,7 +143,7 @@ void vTaskServerWorker(void *arg)
{
esp_err_t err;
bool bNewOTAImage = false; // true if a new ota image was downloaded and validated
// bool bFirstRun = true;
bool bFirstRun = true;
while(true)
{
@ -140,16 +153,18 @@ void vTaskServerWorker(void *arg)
if (esp_mesh_is_root()) //check again that this node is the root node
{
// if(bFirstRun == true)
// {
if(bFirstRun == true)
{
ERROR_CHECK(https_clientInitialize());
// bFirstRun = false;
//}
bFirstRun = false;
}
ERROR_CHECK(https_clientConnectToServer());
ERROR_CHECK(https_clientValidateServer());
ERROR_CHECK(https_clientSendRequest());
ERROR_CHECK(errOTAHTTPS(&bNewOTAImage));
https_clientDeinitialize();
// https_clientReset();
https_clientReset();
if(bNewOTAImage == true)
{
@ -167,85 +182,58 @@ void vTaskServerWorker(void *arg)
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;
char u8OTABuffer[OTA_HTTPS_SEGMENT_SIZE]; //store image segment from server before ota write
uint32_t u32BufferLenght = OTA_HTTPS_SEGMENT_SIZE; //size of buffer
uint32_t u32BytesRead = 0; //number of bytes that are read from server, <= u32BufferLenght
char pcRemoteVersionNumber[12]; //string for version number in server image
const esp_partition_t* pBootPartition; //pointer to boot partition (that will booted after reset)
static esp_ota_handle_t otaHandle; //OTA process handle
uint32_t u32StartOffset = 0U; //start offset for image (exclude the http response data)
esp_app_desc_t bootPartitionDesc; //Metadate from boot partition
pBootPartition = esp_ota_get_boot_partition(); //get boot partition (that will booted after reset), not the running partition
ERROR_CHECK(esp_ota_get_partition_description(pBootPartition, &bootPartitionDesc)); //get metadate of partition
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(https_clientRetrieveData(u8OTABuffer, &u32BufferLenght, &u32BytesRead)); //read first bytes if image, including the version
ERROR_CHECK(errExtractVersionNumber(u8OTABuffer, &u32BytesRead, pcRemoteVersionNumber)); //extract version numbers
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(err == ESP_OK) //check if version number is found
{
if(bNewerVersion((curPartitionDesc).version, pcRemoteVersionNumber)) //compare local and remote version
if(bNewerVersion((bootPartitionDesc).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]);
ERROR_CHECK(errFindImageStart(u8OTABuffer, &u32BufferLenght, &u32StartOffset)); //get image start offset
//TODO lock ota mutex
ERROR_CHECK(esp_ota_begin(otaPartition, OTA_SIZE_UNKNOWN, &otaHandle));
ERROR_CHECK(esp_ota_begin(pOTAPartition, OTA_SIZE_UNKNOWN, &otaHandle)); //start ota update process
if(err == ESP_OK)
{
//image download and ota partition write
ESP_LOGI(LOG_TAG, "start ota https download");
do
{
ESP_LOGI(LOG_TAG, "OTA-Data written: %i", u32BytesRead);
ERROR_CHECK(esp_ota_write(otaHandle, (const void*) buffer+u32StartOffset, (u32BytesRead-u32StartOffset)));
//TODO progress log
ERROR_CHECK(esp_ota_write(otaHandle, (const void*) u8OTABuffer+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
ERROR_CHECK(https_clientRetrieveData(u8OTABuffer, &u32BufferLenght, &u32BytesRead)); //download next data segment
}
}
while ((u32BytesRead > 0) && (err == ESP_OK));
while ((u32BytesRead > 0) && (err == ESP_OK)); //loop until error or complete image downloaded
}
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
ERROR_CHECK(esp_ota_set_boot_partition(pOTAPartition)); //set new image as boot
if(err == ESP_OK)
{
*pbNewOTAImage = true; //image validated
@ -253,23 +241,17 @@ esp_err_t errOTAHTTPS(bool* pbNewOTAImage)
}
else
{
// error occurred --> abort ota update process
ESP_LOGE(LOG_TAG, "abort ota process");
//error occurred --> abort ota update process
ESP_LOGE(LOG_TAG, "abort ota process due to error 0x%x -> %s", err, esp_err_to_name(err));
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;
}
/*
* Return true if remote version is newer (higher) than local version
*/
@ -403,9 +385,9 @@ esp_err_t esp_mesh_ota_send(mesh_addr_t* dest)
static uint32_t u32index;
const esp_partition_t * currentPartition = esp_ota_get_boot_partition();
const esp_partition_t * pBootPartition = esp_ota_get_boot_partition();
if((*currentPartition).subtype == 0)
if((*pBootPartition).subtype == 0)
{
int data_read = 0;
@ -422,7 +404,7 @@ esp_err_t esp_mesh_ota_send(mesh_addr_t* dest)
else
{
ESP_LOGI(MESH_TAG, "OTA-Data read: %i", u32index);
err = esp_partition_read(currentPartition, (1024*u32index), packet.au8Payload, 1024 );
err = esp_partition_read(pBootPartition, (1024*u32index), packet.au8Payload, 1024 );
ESP_ERROR_CHECK(err);
data_read = 1024;
u32index++;
@ -438,7 +420,7 @@ esp_err_t esp_mesh_ota_send(mesh_addr_t* dest)
}
else
{
ESP_LOGI(MESH_TAG, "Subtype: %d", (*currentPartition).subtype);
ESP_LOGI(MESH_TAG, "Subtype: %d", (*pBootPartition).subtype);
}
return err;
}
@ -449,14 +431,14 @@ esp_err_t esp_mesh_ota_receive(mesh_addr_t* dest, struct ota_mesh_packet* packet
static esp_ota_handle_t otaHandle;
static uint32_t u32index;
const esp_partition_t * currentPartition = esp_ota_get_boot_partition();
const esp_partition_t * otaPartition = esp_ota_get_next_update_partition(currentPartition);
const esp_partition_t * pBootPartition = esp_ota_get_boot_partition();
const esp_partition_t * pOTAPartition = esp_ota_get_next_update_partition(pBootPartition);
if(u32index == 0)
{
//first run
err = esp_ota_begin(otaPartition, OTA_SIZE_UNKNOWN, &otaHandle);
err = esp_ota_begin(pOTAPartition, OTA_SIZE_UNKNOWN, &otaHandle);
ESP_ERROR_CHECK(err);
}
@ -480,11 +462,11 @@ esp_err_t esp_mesh_ota_receive(mesh_addr_t* dest, struct ota_mesh_packet* packet
err = esp_ota_end(otaHandle);
ESP_ERROR_CHECK(err);
esp_app_desc_t otaPartitionDesc;
err = esp_ota_get_partition_description(otaPartition, &otaPartitionDesc);
err = esp_ota_get_partition_description(pOTAPartition, &otaPartitionDesc);
ESP_ERROR_CHECK(err);
ESP_LOGI(MESH_TAG, "otaPartition project_name: %s", (otaPartitionDesc).project_name);
ESP_LOGI(MESH_TAG, "pOTAPartition project_name: %s", (otaPartitionDesc).project_name);
err = esp_ota_set_boot_partition(otaPartition);
err = esp_ota_set_boot_partition(pOTAPartition);
ESP_ERROR_CHECK(err);
struct ota_mesh_packet retPacket;