/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * * Copyright (C) 2008 by Dominik Riebeling * $Id$ * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include #include "bootloaderinstallbase.h" #include "bootloaderinstallmi4.h" #include "bootloaderinstallhex.h" #include "bootloaderinstallipod.h" #include "bootloaderinstallsansa.h" #include "bootloaderinstallfile.h" #include "bootloaderinstallchinachip.h" #include "bootloaderinstallams.h" #include "bootloaderinstalltcc.h" #include "bootloaderinstallmpio.h" #include "utils.h" #if defined(Q_OS_MACX) #include #include #include #endif BootloaderInstallBase* BootloaderInstallBase::createBootloaderInstaller(QObject* parent,QString type) { if(type == "mi4") { return new BootloaderInstallMi4(parent); } else if(type == "hex") { return new BootloaderInstallHex(parent); } else if(type == "sansa") { return new BootloaderInstallSansa(parent); } else if(type == "ipod") { return new BootloaderInstallIpod(parent); } else if(type == "file") { return new BootloaderInstallFile(parent); } else if(type == "chinachip") { return new BootloaderInstallChinaChip(parent); } else if(type == "ams") { return new BootloaderInstallAms(parent); } else if(type == "tcc") { return new BootloaderInstallTcc(parent); } else if(type == "mpio") { return new BootloaderInstallMpio(parent); } else { return NULL; } } BootloaderInstallBase::BootloaderType BootloaderInstallBase::installed(void) { return BootloaderUnknown; } BootloaderInstallBase::Capabilities BootloaderInstallBase::capabilities(void) { return 0; } void BootloaderInstallBase::downloadBlStart(QUrl source) { m_http.setFile(&m_tempfile); m_http.setCache(true); connect(&m_http, SIGNAL(done(bool)), this, SLOT(downloadBlFinish(bool))); // connect the http read signal to our logProgess *signal* // to immediately emit it without any helper function. connect(&m_http, SIGNAL(dataReadProgress(int, int)), this, SIGNAL(logProgress(int, int))); m_http.getFile(source); } void BootloaderInstallBase::downloadReqFinished(int id, bool error) { qDebug() << "[BootloaderInstallBase] Download Request" << id << "finished, error:" << m_http.errorString(); downloadBlFinish(error); } void BootloaderInstallBase::downloadBlFinish(bool error) { qDebug() << "[BootloaderInstallBase] Downloading bootloader finished, error:" << error; // update progress bar emit logProgress(100, 100); if(m_http.httpResponse() != 200) { emit logItem(tr("Download error: received HTTP error %1.") .arg(m_http.errorString()), LOGERROR); emit done(true); return; } if(error) { emit logItem(tr("Download error: %1") .arg(m_http.error()), LOGERROR); emit done(true); return; } else if(m_http.isCached()) emit logItem(tr("Download finished (cache used)."), LOGOK); else emit logItem(tr("Download finished."), LOGOK); QCoreApplication::processEvents(); m_blversion = m_http.timestamp(); emit downloadDone(); } void BootloaderInstallBase::installBlfile(void) { qDebug() << "[BootloaderInstallBase]" << __func__; } //! @brief backup OF file. //! @param to folder to write backup file to. Folder will get created. //! @return true on success, false on error. bool BootloaderInstallBase::backup(QString to) { qDebug() << "[BootloaderInstallBase] Backing up bootloader file"; QDir targetDir("."); emit logItem(tr("Creating backup of original firmware file."), LOGINFO); if(!targetDir.mkpath(to)) { emit logItem(tr("Creating backup folder failed"), LOGERROR); return false; } QString tofile = to + "/" + QFileInfo(m_blfile).fileName(); qDebug() << "[BootloaderInstallBase] trying to backup" << m_blfile << "to" << tofile; if(!QFile::copy(Utils::resolvePathCase(m_blfile), tofile)) { emit logItem(tr("Creating backup copy failed."), LOGERROR); return false; } emit logItem(tr("Backup created."), LOGOK); return true; } //! @brief log installation to logfile. //! @param mode action to perform. 0: add to log, 1: remove from log. //! @return 0 on success int BootloaderInstallBase::logInstall(LogMode mode) { int result = 0; QString section = m_blurl.path().section('/', -1); QSettings s(m_logfile, QSettings::IniFormat, this); emit logItem(tr("Creating installation log"), LOGINFO); if(mode == LogAdd) { s.setValue("Bootloader/" + section, m_blversion.toString(Qt::ISODate)); qDebug() << "[BootloaderInstallBase] Writing log, version:" << m_blversion.toString(Qt::ISODate); } else { s.remove("Bootloader/" + section); } s.sync(); emit logItem(tr("Installation log created"), LOGOK); return result; } //! @brief Return post install hints string. //! @param model model string //! @return hints. QString BootloaderInstallBase::postinstallHints(QString model) { bool hint = false; QString msg = tr("Bootloader installation is almost complete. " "Installation requires you to perform the " "following steps manually:"); msg += "
    "; msg += tr("
  1. Safely remove your player.
  2. "); if(model == "h100" || model == "h120" || model == "h300" || model == "ondavx747") { hint = true; msg += tr("
  3. Reboot your player into the original firmware.
  4. " "
  5. Perform a firmware upgrade using the update functionality " "of the original firmware. Please refer to your player's manual " "on details.
  6. " "
  7. After the firmware has been updated reboot your player.
  8. "); } if(model == "iaudiox5" || model == "iaudiom5" || model == "iaudiox5v" || model == "iaudiom3" || model == "mpioh200") { hint = true; msg += tr("
  9. Turn the player off
  10. " "
  11. Insert the charger
  12. "); } if(model == "gigabeatf") { hint = true; msg += tr("
  13. Unplug USB and power adaptors
  14. " "
  15. Hold Power to turn the player off
  16. " "
  17. Toggle the battery switch on the player
  18. " "
  19. Hold Power to boot into Rockbox
  20. "); } msg += "
"; msg += tr("

Note: You can safely install other parts first, but " "the above steps are required to finish the installation!

"); if(hint) return msg; else return QString(""); } #if defined(Q_OS_MACX) void BootloaderInstallBase::waitRemount() { m_remountTries = 600; emit logItem(tr("Waiting for system to remount player"), LOGINFO); QTimer::singleShot(100, this, SLOT(checkRemount())); } #endif void BootloaderInstallBase::checkRemount() { #if defined(Q_OS_MACX) if(m_remountTries--) { int status = 0; // check if device has been remounted QCoreApplication::processEvents(); int num; struct statfs *mntinf; num = getmntinfo(&mntinf, MNT_WAIT); while(num--) { if(QString(mntinf->f_mntfromname).startsWith(m_remountDevice) && QString(mntinf->f_fstypename).contains("msdos", Qt::CaseInsensitive)) status = 1; mntinf++; } if(!status) { // still not remounted, restart timer. QTimer::singleShot(500, this, SLOT(checkRemount())); qDebug() << "[BootloaderInstallBase] Player not remounted yet" << m_remountDevice; } else { emit logItem(tr("Player remounted"), LOGINFO); emit remounted(true); } } else { emit logItem(tr("Timeout on remount"), LOGERROR); emit remounted(false); } #endif } //! @brief set list of possible bootloader files and pick the existing one. //! @param sl list of possible bootloader files. void BootloaderInstallBase::setBlFile(QStringList sl) { // figue which of the possible bootloader filenames is correct. for(int a = 0; a < sl.size(); a++) { if(!Utils::resolvePathCase(sl.at(a)).isEmpty()) { m_blfile = sl.at(a); } } if(m_blfile.isEmpty()) { m_blfile = sl.at(0); } }