1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
9 * Copyright (C) 2008 by Dominik Riebeling
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
23 #include "bootloaderinstallbase.h"
24 #include "bootloaderinstallmi4.h"
25 #include "bootloaderinstallhex.h"
26 #include "bootloaderinstallipod.h"
27 #include "bootloaderinstallsansa.h"
28 #include "bootloaderinstallfile.h"
29 #include "bootloaderinstallchinachip.h"
30 #include "bootloaderinstallams.h"
31 #include "bootloaderinstalltcc.h"
32 #include "bootloaderinstallmpio.h"
35 #if defined(Q_OS_MACX)
36 #include <sys/param.h>
37 #include <sys/ucred.h>
38 #include <sys/mount.h>
42 BootloaderInstallBase
* BootloaderInstallBase::createBootloaderInstaller(QObject
* parent
,QString type
)
45 return new BootloaderInstallMi4(parent
);
47 else if(type
== "hex") {
48 return new BootloaderInstallHex(parent
);
50 else if(type
== "sansa") {
51 return new BootloaderInstallSansa(parent
);
53 else if(type
== "ipod") {
54 return new BootloaderInstallIpod(parent
);
56 else if(type
== "file") {
57 return new BootloaderInstallFile(parent
);
59 else if(type
== "chinachip") {
60 return new BootloaderInstallChinaChip(parent
);
62 else if(type
== "ams") {
63 return new BootloaderInstallAms(parent
);
65 else if(type
== "tcc") {
66 return new BootloaderInstallTcc(parent
);
68 else if(type
== "mpio") {
69 return new BootloaderInstallMpio(parent
);
77 BootloaderInstallBase::BootloaderType
BootloaderInstallBase::installed(void)
79 return BootloaderUnknown
;
83 BootloaderInstallBase::Capabilities
BootloaderInstallBase::capabilities(void)
89 void BootloaderInstallBase::downloadBlStart(QUrl source
)
91 m_http
.setFile(&m_tempfile
);
92 m_http
.setCache(true);
93 connect(&m_http
, SIGNAL(done(bool)), this, SLOT(downloadBlFinish(bool)));
94 // connect the http read signal to our logProgess *signal*
95 // to immediately emit it without any helper function.
96 connect(&m_http
, SIGNAL(dataReadProgress(int, int)),
97 this, SIGNAL(logProgress(int, int)));
98 m_http
.getFile(source
);
102 void BootloaderInstallBase::downloadReqFinished(int id
, bool error
)
104 qDebug() << "[BootloaderInstallBase] Download Request" << id
105 << "finished, error:" << m_http
.errorString();
107 downloadBlFinish(error
);
111 void BootloaderInstallBase::downloadBlFinish(bool error
)
113 qDebug() << "[BootloaderInstallBase] Downloading bootloader finished, error:"
116 // update progress bar
117 emit
logProgress(100, 100);
119 if(m_http
.httpResponse() != 200) {
120 emit
logItem(tr("Download error: received HTTP error %1.")
121 .arg(m_http
.errorString()), LOGERROR
);
126 emit
logItem(tr("Download error: %1")
127 .arg(m_http
.error()), LOGERROR
);
131 else if(m_http
.isCached())
132 emit
logItem(tr("Download finished (cache used)."), LOGOK
);
134 emit
logItem(tr("Download finished."), LOGOK
);
136 QCoreApplication::processEvents();
137 m_blversion
= m_http
.timestamp();
141 void BootloaderInstallBase::installBlfile(void)
143 qDebug() << "[BootloaderInstallBase]" << __func__
;
147 //! @brief backup OF file.
148 //! @param to folder to write backup file to. Folder will get created.
149 //! @return true on success, false on error.
151 bool BootloaderInstallBase::backup(QString to
)
153 qDebug() << "[BootloaderInstallBase] Backing up bootloader file";
155 emit
logItem(tr("Creating backup of original firmware file."), LOGINFO
);
156 if(!targetDir
.mkpath(to
)) {
157 emit
logItem(tr("Creating backup folder failed"), LOGERROR
);
160 QString tofile
= to
+ "/" + QFileInfo(m_blfile
).fileName();
161 qDebug() << "[BootloaderInstallBase] trying to backup" << m_blfile
<< "to" << tofile
;
162 if(!QFile::copy(Utils::resolvePathCase(m_blfile
), tofile
)) {
163 emit
logItem(tr("Creating backup copy failed."), LOGERROR
);
166 emit
logItem(tr("Backup created."), LOGOK
);
171 //! @brief log installation to logfile.
172 //! @param mode action to perform. 0: add to log, 1: remove from log.
173 //! @return 0 on success
174 int BootloaderInstallBase::logInstall(LogMode mode
)
177 QString section
= m_blurl
.path().section('/', -1);
178 QSettings
s(m_logfile
, QSettings::IniFormat
, this);
179 emit
logItem(tr("Creating installation log"), LOGINFO
);
182 s
.setValue("Bootloader/" + section
, m_blversion
.toString(Qt::ISODate
));
183 qDebug() << "[BootloaderInstallBase] Writing log, version:"
184 << m_blversion
.toString(Qt::ISODate
);
187 s
.remove("Bootloader/" + section
);
191 emit
logItem(tr("Installation log created"), LOGOK
);
197 //! @brief Return post install hints string.
198 //! @param model model string
200 QString
BootloaderInstallBase::postinstallHints(QString model
)
203 QString msg
= tr("Bootloader installation is almost complete. "
204 "Installation <b>requires</b> you to perform the "
205 "following steps manually:");
208 msg
+= tr("<li>Safely remove your player.</li>");
209 if(model
== "h100" || model
== "h120" || model
== "h300" ||
210 model
== "ondavx747") {
212 msg
+= tr("<li>Reboot your player into the original firmware.</li>"
213 "<li>Perform a firmware upgrade using the update functionality "
214 "of the original firmware. Please refer to your player's manual "
216 "<li>After the firmware has been updated reboot your player.</li>");
218 if(model
== "iaudiox5" || model
== "iaudiom5"
219 || model
== "iaudiox5v" || model
== "iaudiom3" || model
== "mpioh200") {
221 msg
+= tr("<li>Turn the player off</li>"
222 "<li>Insert the charger</li>");
224 if(model
== "gigabeatf") {
226 msg
+= tr("<li>Unplug USB and power adaptors</li>"
227 "<li>Hold <i>Power</i> to turn the player off</li>"
228 "<li>Toggle the battery switch on the player</li>"
229 "<li>Hold <i>Power</i> to boot into Rockbox</li>");
232 msg
+= tr("<p><b>Note:</b> You can safely install other parts first, but "
233 "the above steps are <b>required</b> to finish the installation!</p>");
242 #if defined(Q_OS_MACX)
243 void BootloaderInstallBase::waitRemount()
245 m_remountTries
= 600;
246 emit
logItem(tr("Waiting for system to remount player"), LOGINFO
);
248 QTimer::singleShot(100, this, SLOT(checkRemount()));
253 void BootloaderInstallBase::checkRemount()
255 #if defined(Q_OS_MACX)
256 if(m_remountTries
--) {
258 // check if device has been remounted
259 QCoreApplication::processEvents();
261 struct statfs
*mntinf
;
263 num
= getmntinfo(&mntinf
, MNT_WAIT
);
265 if(QString(mntinf
->f_mntfromname
).startsWith(m_remountDevice
)
266 && QString(mntinf
->f_fstypename
).contains("msdos", Qt::CaseInsensitive
))
271 // still not remounted, restart timer.
272 QTimer::singleShot(500, this, SLOT(checkRemount()));
273 qDebug() << "[BootloaderInstallBase] Player not remounted yet" << m_remountDevice
;
276 emit
logItem(tr("Player remounted"), LOGINFO
);
277 emit
remounted(true);
281 emit
logItem(tr("Timeout on remount"), LOGERROR
);
282 emit
remounted(false);
288 //! @brief set list of possible bootloader files and pick the existing one.
289 //! @param sl list of possible bootloader files.
290 void BootloaderInstallBase::setBlFile(QStringList sl
)
292 // figue which of the possible bootloader filenames is correct.
293 for(int a
= 0; a
< sl
.size(); a
++) {
294 if(!Utils::resolvePathCase(sl
.at(a
)).isEmpty()) {
298 if(m_blfile
.isEmpty()) {