Index: sources/update/VSwUpdate.cpp =================================================================== diff -u -r7cf31f6cfef97bb564a103c263821a3b722c8a2b -ra789f05e3d97087703029792b6fd81bce77157f0 --- sources/update/VSwUpdate.cpp (.../VSwUpdate.cpp) (revision 7cf31f6cfef97bb564a103c263821a3b722c8a2b) +++ sources/update/VSwUpdate.cpp (.../VSwUpdate.cpp) (revision a789f05e3d97087703029792b6fd81bce77157f0) @@ -41,6 +41,10 @@ #define MSG_ID_REBOOT_NOW (0x8094) ///< HD Reboot RM46 immediately #define MSG_ID_SET_ENTER_BOOTLOADER (0x8095) ///< HD Set the flag to stay +/** 1 or 0 means do once, 2 = do twice, 3 = three times, etc. */ +#define MAX_TEST_LOOPS (1) + + /*! * \brief Constructor. * @@ -63,7 +67,9 @@ _isVisible(false), _progressVisible(false), _postWasOk(false), - _settingsOk(false) + _settingsOk(false), + _testLoops(0), + _maxTestLoops(MAX_TEST_LOOPS) { setButtonText("Start"); setState(""); @@ -278,52 +284,9 @@ _ApplicationController.enableKeepAlive(true); } else { - // Start. - int row_index = (int)_selected; - if (row_index >= 0) { - std::vector update; - std::string package_location = _available[row_index].fullPath; + _testLoops = 0; // UI initiated. - // Copy / cache it (if not already in there). - // - // The UI has already checked the package as ok before allowing the user to pick it. - bool ok = _package.copyUpdate(package_location, _oldUpdates, _maxOld); - if (!ok) - { - writeLog("Failed to cache: " + QString::fromStdString(package_location), true); - } - - // As part of starting, it re-checks and then leaves the file open during the rest of the process - // and thus not-modifiable as a stream as a security feature. - _ApplicationController.enableKeepAlive(false); - _CanInterface.setSWUpdateMode(true); - - // Tell it to enter bootloader, this is done using the application protocol but from here. - // - // If these did fail which is extremely unlikely it feels to the user like they didn't quite - // press the start button. - - ok = _package.start_hasKey(package_location, update); - if (ok) - { - // If we got an ok, we are no longer allowed to trust the DG or HD image - // that exists so we'll never use MSG_ID_HD_REBOOT_NOW - QString info = QString::fromStdString(_package.get_info()); - set_progress(info); - startStopUpdate("Started update" + info, true); - } else { - // This is the only point in an update that can fail and just go to the existing image. - // Because we didn't write MSG_ID_HD_SET_ENTER_BOOTLOADER this should reboot to the app. - // - // This should put both into the FW bootloader, which timesout into launching the app if - // nothing else is commanded. - _package.rebootFW(); - - set_progress("Failed to start " + QString::fromStdString(_available[row_index].fileName)); - writeLog("Failed to start " + QString::fromStdString(package_location), false); - writeLog(QString::fromStdString(_package.get_info()), true); - } - } + startUpdate(); } // Falling through, success or failure ensure these are set correctly. @@ -676,6 +639,16 @@ } } + if (!_updating) { + _testLoops++; + + // Finished but not abort, so... + if (_testLoops< _maxTestLoops) { + startUpdate(); + } + } + + // Ensure these match up with _updating state. _ApplicationController.enableKeepAlive(!_updating); _mpBackButton->setEnabled(!_updating); @@ -820,6 +793,9 @@ return true; } +/*! + * \brief Check and if needed mount the USB. + */ void VSWUpdate::checkMountUsb() { static bool mounted = false; static QString oldDevice; @@ -847,3 +823,55 @@ mounted = false; oldDevice = ""; } + +/*! + * \brief Start the update. + */ +void VSWUpdate::startUpdate() { + // Start. + int row_index = (int)_selected; + if (row_index >= 0) { + std::vector update; + std::string package_location = _available[row_index].fullPath; + + // Copy / cache it (if not already in there). + // + // The UI has already checked the package as ok before allowing the user to pick it. + bool ok = _package.copyUpdate(package_location, _oldUpdates, _maxOld); + if (!ok) + { + writeLog("Failed to cache: " + QString::fromStdString(package_location), true); + } + + // As part of starting, it re-checks and then leaves the file open during the rest of the process + // and thus not-modifiable as a stream as a security feature. + _ApplicationController.enableKeepAlive(false); + _CanInterface.setSWUpdateMode(true); + + // Tell it to enter bootloader, this is done using the application protocol but from here. + // + // If these did fail which is extremely unlikely it feels to the user like they didn't quite + // press the start button. + + ok = _package.start_hasKey(package_location, update); + if (ok) + { + // If we got an ok, we are no longer allowed to trust the DG or HD image + // that exists so we'll never use MSG_ID_HD_REBOOT_NOW + QString info = QString::fromStdString(_package.get_info()); + set_progress(info); + startStopUpdate("Started update" + info, true); + } else { + // This is the only point in an update that can fail and just go to the existing image. + // Because we didn't write MSG_ID_HD_SET_ENTER_BOOTLOADER this should reboot to the app. + // + // This should put both into the FW bootloader, which timesout into launching the app if + // nothing else is commanded. + _package.rebootFW(); + + set_progress("Failed to start " + QString::fromStdString(_available[row_index].fileName)); + writeLog("Failed to start " + QString::fromStdString(package_location), false); + writeLog(QString::fromStdString(_package.get_info()), true); + } + } +}