OTA on ESP32-S3, running the webserver
Posted: Mon Mar 13, 2023 11:02 am
Hello, i have a ESP32-S3, which is configured as RNDIS device, with a webserver running on 2.2.2.2. I'm trying to implement a functionallity, so i can upload new firmware via the webserver. It says OTA image has invalid magic byte (expected 0xE9, saw 0x2d). I dont know if it is possible for you guys, to see any issues.
I am a little bit worried it is a ram allocation issue.
(37407) ./main/http_service.c: Running partition type 0 subtype 16 (offset 0x00090000)
I (37408) ./main/http_service.c: Writing to partition subtype 17 at offset 0x390000
I (37417) ./main/http_service.c: Looking for string application/octet-stream 517
I (37425) ./main/http_service.c: New firmware version: 02692151847
Content-Disposition: form-data; name="myfile"; filenamm((void *)dstart)
I (37438) ./main/http_service.c: Running firmware version: Basic-7-g59bf
I (37447) ./main/http_service.c: esp_ota_begin succeeded
E (37453) esp_ota_ops: OTA image has invalid magic byte (expected 0xE9, saw 0x2d)
I am a little bit worried it is a ram allocation issue.
(37407) ./main/http_service.c: Running partition type 0 subtype 16 (offset 0x00090000)
I (37408) ./main/http_service.c: Writing to partition subtype 17 at offset 0x390000
I (37417) ./main/http_service.c: Looking for string application/octet-stream 517
I (37425) ./main/http_service.c: New firmware version: 02692151847
Content-Disposition: form-data; name="myfile"; filenamm((void *)dstart)
I (37438) ./main/http_service.c: Running firmware version: Basic-7-g59bf
I (37447) ./main/http_service.c: esp_ota_begin succeeded
E (37453) esp_ota_ops: OTA image has invalid magic byte (expected 0xE9, saw 0x2d)
Code: Select all
#include "esp_flash_partitions.h"
#include "esp_partition.h"
#include "esp_ota_ops.h"
#define BUFFSIZE 517
static char ota_write_data[BUFFSIZE+1];// [BUFFSIZE + 1] = { 0 };
static esp_err_t update_get_handler(httpd_req_t *req) {
static char *ota_write_dataPtr;
esp_err_t err;
// update handle : set by esp_ota_begin(), must be freed via esp_ota_end()
esp_ota_handle_t update_handle = 0;
const esp_partition_t *update_partition = NULL;
ESP_LOGE(TAG, "Starting OTA");
const esp_partition_t *configured = esp_ota_get_boot_partition();
const esp_partition_t *running = esp_ota_get_running_partition();
if (configured != running) {
ESP_LOGW(TAG,
"Configured OTA boot partition at offset 0x%08x, but running from offset 0x%08x",
configured->address, running->address);
ESP_LOGW(TAG,
"(This can happen if either the OTA boot data or preferred boot image become corrupted somehow.)");
}
ESP_LOGI(TAG, "Running partition type %d subtype %d (offset 0x%08x)",
running->type, running->subtype, running->address);
update_partition = esp_ota_get_next_update_partition(NULL);
assert(update_partition != NULL);
ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x",
update_partition->subtype, update_partition->address);
int binary_file_length = 0;
//deal with all receive packet
bool image_header_was_checked = false;
char firmwareStartPosString[] = "application/octet-stream";
int remaining = req->content_len;
firmwareSize = req->content_len;
char jsonData[100];
//ota_write_data = (char *) malloc((BUFFSIZE) + 1);
while (remaining > 0) {
//int data_read = esp_http_client_read(client, ota_write_data, BUFFSIZE);
if(ota_write_data == NULL){
ESP_LOGE(TAG, "Ninja malloc faliure");
return ESP_FAIL;
}
int data_read = httpd_req_recv(req, (char*)ota_write_data,
MIN(BUFFSIZE, remaining));
ota_write_dataPtr = ota_write_data;
remaining -= data_read;
if (data_read < 0) {
ESP_LOGE(TAG, "Error: SSL data read error");
//http_cleanup(client);
//task_fatal_error();
} else if (data_read > 0) {
if (image_header_was_checked == false) {
esp_app_desc_t new_app_info;
if (data_read
> sizeof(esp_image_header_t)
+ sizeof(esp_image_segment_header_t)
+ sizeof(esp_app_desc_t)) {
ESP_LOGI(TAG, "Looking for string %s %i",
firmwareStartPosString, data_read);
int s = 0;
for (s = 0; s < BUFFSIZE; s++) {
int x = 0;
while (firmwareStartPosString[x]
== ota_write_data[x + s]
&& x < sizeof(firmwareStartPosString) - 1) {
x++;
}
if (x == sizeof(firmwareStartPosString) - 1) {
ota_write_dataPtr = &ota_write_dataPtr[28 + s]; //0x51
break;
}
}
// if (strstr(ota_write_dataPtr, firmwareStartPosString) != NULL) {
// ESP_LOGI(TAG, "Found String start ");
// }else {
// ESP_LOGI(TAG, "String not found ");
// printHexBlock(64, &ota_write_dataPtr[0x2a0]);
// //free(ota_write_data);
// return ESP_FAIL;
// }
//ota_write_dataPtr = &ota_write_dataPtr[0x2a0 + 28];
data_read -= 28 + s;
// check current version with downloading
memcpy(&new_app_info,
&ota_write_dataPtr[sizeof(esp_image_header_t)
+ sizeof(esp_image_segment_header_t)],
sizeof(esp_app_desc_t));
ESP_LOGI(TAG, "New firmware version: %s",
new_app_info.version);
esp_app_desc_t running_app_info;
if (esp_ota_get_partition_description(running,
&running_app_info) == ESP_OK) {
ESP_LOGI(TAG, "Running firmware version: %s",
running_app_info.version);
}
const esp_partition_t *last_invalid_app =
esp_ota_get_last_invalid_partition();
esp_app_desc_t invalid_app_info;
if (esp_ota_get_partition_description(last_invalid_app,
&invalid_app_info) == ESP_OK) {
ESP_LOGI(TAG, "Last invalid firmware version: %s",
invalid_app_info.version);
}
// check current version with last invalid partition
if (last_invalid_app != NULL) {
if (memcmp(invalid_app_info.version,
new_app_info.version,
sizeof(new_app_info.version)) == 0) {
ESP_LOGW(TAG,
"New version is the same as invalid version.");
ESP_LOGW(TAG,
"Previously, there was an attempt to launch the firmware with %s version, but it failed.",
invalid_app_info.version);
ESP_LOGW(TAG,
"The firmware has been rolled back to the previous version.");
}
}
#ifndef CONFIG_EXAMPLE_SKIP_VERSION_CHECK
// if (memcmp(new_app_info.version, running_app_info.version, sizeof(new_app_info.version)) == 0) {
// ESP_LOGW(TAG, "Current running version is the same as a new. We will not continue the update.");
// http_cleanup(client);
// infinite_loop();
// }
#endif
image_header_was_checked = true;
err = esp_ota_begin(update_partition,
OTA_WITH_SEQUENTIAL_WRITES, &update_handle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_ota_begin failed (%s)",
esp_err_to_name(err));
esp_ota_abort(update_handle);
}
ESP_LOGI(TAG, "esp_ota_begin succeeded");
} else {
ESP_LOGE(TAG, "received package is not fit len");
esp_ota_abort(update_handle);
}
}
//printHexBlock(128 ,&ota_write_dataPtr[32]);
//while(1);
err = esp_ota_write(update_handle, (const void*) ota_write_dataPtr,
data_read);
if (err != ESP_OK) {
esp_ota_abort(update_handle);
}
binary_file_length += data_read;
//ESP_LOGW(TAG, "Written image length %d", binary_file_length);
int newPct = ((firmwareSize - remaining) * 100) / firmwareSize;
if(newPct % 2 == 0 && newPct != pct){
vTaskDelay(1);
pct = newPct;
sprintf(jsonData, "{ \"progressFirmware\":\"%d\"}", pct);
SendJsonToAll(jsonData);
vTaskDelay(1);
}
} else if (data_read == 0) {
///As esp_http_client_read never returns negative error code, we rely on
// `errno` to check for underlying transport connectivity closure if any
//
if (errno == ECONNRESET || errno == ENOTCONN) {
ESP_LOGE(TAG, "Connection closed, errno = %d", errno);
break;
}
}
}
//free(ota_write_data);
ESP_LOGI(TAG, "Total Write binary data length: %d", binary_file_length);
err = esp_ota_end(update_handle);
if (err != ESP_OK) {
if (err == ESP_ERR_OTA_VALIDATE_FAILED) {
ESP_LOGE(TAG, "Image validation failed, image is corrupted");
} else {
ESP_LOGE(TAG, "esp_ota_end failed (%s)!", esp_err_to_name(err));
}
}
ESP_LOGI(TAG, "esp_ota_set_boot_partition!");
err = esp_ota_set_boot_partition(update_partition);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_ota_set_boot_partition failed (%s)!",
esp_err_to_name(err));
}
httpd_resp_set_status(req, "303 See Other");
httpd_resp_set_hdr(req, "Location", "/");
vTaskDelay(200);
ESP_LOGI(TAG, "Prepare to restart system!");
esp_restart();
return ESP_OK;
}
//#define SCRATCH_BUFSIZE 80000
//char fpgaBuf[SCRATCH_BUFSIZE];
static esp_err_t upload_post_handler(httpd_req_t *req) {
// char filepath[FILE_PATH_MAX];
//struct stat file_stat;
ESP_LOGI(TAG, "Receiving file : %s...", "fpga file ");
// Retrieve the pointer to scratch buffer for temporary storage
//char *buf = ((struct file_server_data *)req->user_ctx)->scratch;
int received;
// Content length of the request gives
// the size of the file being uploaded
int remaining = req->content_len;
//char *fpgaTempBuf = fpgaBuf;
while (remaining > 0) {
ESP_LOGI(TAG, "Remaining size : %d", remaining);
// Receive the file part by part into a buffer
}
// Close file upon upload completion
ESP_LOGI(TAG, "File reception complete");
// SendSpiFPGAFirmware((uint8_t*)fpgaBuf,MIN(req->content_len,SCRATCH_BUFSIZE),1);
uint32_t sum = 0;
int i = 0;
uint8_t last = 0;
// Redirect onto root to see the updated file list
httpd_resp_set_status(req, "303 See Other");
httpd_resp_set_hdr(req, "Location", "/");
#ifdef CONFIG_EXAMPLE_HTTPD_CONN_CLOSE_HEADER
httpd_resp_set_hdr(req, "Connection", "close");
#endif
httpd_resp_sendstr(req, "File uploaded successfully");
return ESP_OK;
}