390 std::function<
void(
int,
int)> progress_cb = NULL) {
391 using namespace logger;
392#if defined(ESP32) || defined(ESP8266)
393 auto currentFW = std::make_shared<State>();
394 currentFW->role = role;
395 auto updateFW = std::make_shared<State>();
396 updateFW->role = role;
399 if (SPIFFS.exists(currentFW->ota_fn)) {
400 auto file = SPIFFS.open(currentFW->ota_fn,
"r");
403 if (LittleFS.exists(currentFW->ota_fn)) {
404 auto file = LittleFS.open(currentFW->ota_fn,
"r");
407 while (file.available()) {
408 msg += (char)file.read();
412 if (fw.role == role && fw.hardware == currentFW->hardware) {
413 Log(DEBUG,
"MD5 found %s\n", fw.md5.c_str());
414 currentFW->md5 = fw.md5;
424 if (currentFW->role == pkg.role && currentFW->hardware == pkg.hardware) {
425 if ((currentFW->md5 == pkg.md5 && !pkg.forced) ||
426 updateFW->md5 == pkg.md5) {
430 updateFW->
md5 = pkg.md5;
431 updateFW->broadcasted = pkg.broadcasted;
432 updateFW->compressed = pkg.compressed;
435 if (!pkg.broadcasted || mesh.
isRoot()) {
440 mesh.
addTask(scheduler, 30 * TASK_SECOND, 10,
441 [request, &mesh]() { mesh.
sendPackage(&request); });
442 updateFW->task->setOnDisable([updateFW]() {
443 Log(ERROR,
"OTA: Did not receive the requested data.\n");
460 auto pkg = variant.
to<
Data>();
462 if (updateFW->md5 == pkg.md5 && updateFW->role == pkg.role &&
463 updateFW->hardware == pkg.hardware) {
465 if (updateFW->partNo == pkg.partNo) {
466 if (progress_cb != NULL) {
467 progress_cb(pkg.partNo, pkg.noPart);
469 if (pkg.partNo == 0) {
471 uint32_t maxSketchSpace = UPDATE_SIZE_UNKNOWN;
473 uint32_t maxSketchSpace =
474 (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
476 Log(DEBUG,
"Sketch size %d\n", maxSketchSpace);
477 if (Update.isRunning()) {
480 if (!Update.begin(maxSketchSpace)) {
481 Log(DEBUG,
"handleOTA(): OTA start failed!");
482 Update.printError(Serial);
485 Update.setMD5(pkg.md5.c_str());
491 if (Update.write((uint8_t*)b64Data.c_str(), b64Data.length()) !=
493 Log(ERROR,
"handleOTA(): OTA write failed!");
494 Update.printError(Serial);
497 updateFW->partNo = 0;
502 if (pkg.partNo == pkg.noPart - 1) {
504 if (Update.end(
true)) {
507 auto file = SPIFFS.open(updateFW->ota_fn,
"w");
510 "handleOTA(): Unable to write md5 of new update to the "
512 "file. This will result in endless update loops for OTA\n");
515 auto file = LittleFS.open(updateFW->ota_fn,
"w");
517 Log(ERROR,
"handleOTA(): Unable to write md5 of new binary to the LittleFS file. This will result in endless update loops for OTA\n");
527 Log(DEBUG,
"handleOTA(): OTA Success! %s, %s\n", msg.c_str(),
528 updateFW->role.c_str());
530 mesh.addTask(scheduler, 2 * TASK_SECOND, TASK_ONCE,
531 []() { ESP.restart(); })
534 Log(DEBUG,
"handleOTA(): OTA failed!\n");
535 Update.printError(Serial);
537 updateFW->partNo = 0;
539 if (updateFW->task != NULL) {
540 updateFW->task->setOnDisable(NULL);
541 updateFW->task->disable();
546 if (updateFW->task != NULL) {
548 updateFW->task->setCallback(
549 [request, &mesh]() { mesh.sendPackage(&request); });
551 updateFW->task->restart();
556 if (updateFW->broadcasted && pkg.broadcasted) {
557 Log(DEBUG,
"Out of sequence packet! We may have missed a packet?");
559 updateFW->broadcasted =
false;
561 request.broadcasted =
false;
563 mesh.addTask(scheduler, 30 * TASK_SECOND, 10,
564 [request, &mesh]() { mesh.sendPackage(&request); });
565 updateFW->task->setOnDisable([updateFW]() {
566 Log(ERROR,
"OTA: Did not receive the requested data.\n");