diff --git a/README-flash_api.md b/README-flash_api.md index bffed4a..7d1ce56 100644 --- a/README-flash_api.md +++ b/README-flash_api.md @@ -16,6 +16,7 @@ Legacy function for ESP8266 (not needed for ESP32) * __cgiUploadFirmware()__ CGI function writes HTTP POST data to flash. +A `CgiUploadFlashDef` must be passed as cgiArg with some options including callbacks. * __cgiRebootFirmware()__ CGI function reboots the ESP firmware after a short time-delay. diff --git a/include/libesphttpd/cgiflash.h b/include/libesphttpd/cgiflash.h index 19ec12d..853209c 100644 --- a/include/libesphttpd/cgiflash.h +++ b/include/libesphttpd/cgiflash.h @@ -11,11 +11,22 @@ extern "C" { #endif typedef struct { - int type; - int fw1Pos; - int fw2Pos; - int fwSize; - const char *tagName; + const void *update_partition; // maybe useful info for the callback. Points to a esp_partition_t + int totalLen; // total length of the image in bytes + int received; // how much has been received so far +} CgiUploadFlashStatus; + +typedef void(*CgiFlashUploadCb)(const CgiUploadFlashStatus *status); + +typedef struct { + int type; // CGIFLASH_TYPE_FW or CGIFLASH_TYPE_ESPFS + int fw1Pos; // not used for ESP32 FW + int fw2Pos; // not used for ESP32 FW + int fwSize; // not used for ESP32 FW + const char *tagName; // not used for ESP32 + CgiFlashUploadCb beforeBeginCb; // Optional callback to be called before flash writing begins (i.e. shutdown unessary tasks) + CgiFlashUploadCb progressCb; // Optional callback to be called when upload progresses + CgiFlashUploadCb endCb; // Optional callback to be called after flash writing ends } CgiUploadFlashDef; CgiStatus cgiGetFirmwareNext(HttpdConnData *connData); diff --git a/util/cgiflash.c b/util/cgiflash.c index 9bc00c2..57d804f 100644 --- a/util/cgiflash.c +++ b/util/cgiflash.c @@ -221,6 +221,14 @@ CgiStatus ICACHE_FLASH_ATTR cgiUploadFirmware(HttpdConnData *connData) { else { ESP_LOGI(TAG, "Writing to partition subtype %d at offset 0x%x", state->update_partition->subtype, state->update_partition->address); + // Check if there is a user callback for beginning the upload + if (def->beforeBeginCb) { + CgiUploadFlashStatus status = {0}; + status.update_partition = state->update_partition; + status.totalLen = connData->post.len; + status.received = connData->post.received; + def->beforeBeginCb(&status); + } #ifdef CONFIG_ESPHTTPD_ALLOW_OTA_FACTORY_APP // hack the API to allow write to the factory partition! @@ -284,6 +292,15 @@ CgiStatus ICACHE_FLASH_ATTR cgiUploadFirmware(HttpdConnData *connData) { } dataLen = 0; + // Check if there is a user callback for progress + if (def->progressCb) { + CgiUploadFlashStatus status = {0}; + status.update_partition = state->update_partition; + status.totalLen = connData->post.len; + status.received = connData->post.received; + def->progressCb(&status); + } + } else if (state->state==FLST_DONE) { ESP_LOGE(TAG, "%d bogus bytes received after data received", dataLen); //Ignore those bytes. @@ -319,6 +336,14 @@ CgiStatus ICACHE_FLASH_ATTR cgiUploadFirmware(HttpdConnData *connData) { if (err != ESP_OK) { ESP_LOGE(TAG, "esp_ota_set_boot_partition failed! err=0x%x", err); } + // Check if there is a user callback for end of upload + if (def->endCb) { + CgiUploadFlashStatus status = {0}; + status.update_partition = state->update_partition; + status.totalLen = connData->post.len; + status.received = connData->post.received; + def->endCb(&status); + } } cJSON_AddStringToObject(jsroot, "message", state->err); cJSON_AddBoolToObject(jsroot, "success", (state->state==FLST_DONE)?true:false);