1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
9 * Copyright (C) 2008 by Dominik Riebeling
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
17 ****************************************************************************/
22 #include "bootloaderinstallbase.h"
23 #include "bootloaderinstallmi4.h"
24 #include "bootloaderinstallhex.h"
25 #include "bootloaderinstallipod.h"
26 #include "bootloaderinstallsansa.h"
27 #include "bootloaderinstallfile.h"
28 #include "bootloaderinstallchinachip.h"
29 #include "bootloaderinstallams.h"
30 #include "bootloaderinstalltcc.h"
31 #include "bootloaderinstallmpio.h"
32 #include "bootloaderinstallimx.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
);
71 else if(type
== "imx") {
72 return new BootloaderInstallImx(parent
);
80 BootloaderInstallBase::BootloaderType
BootloaderInstallBase::installed(void)
82 return BootloaderUnknown
;
86 BootloaderInstallBase::Capabilities
BootloaderInstallBase::capabilities(void)
92 void BootloaderInstallBase::downloadBlStart(QUrl source
)
94 m_http
.setFile(&m_tempfile
);
95 m_http
.setCache(true);
96 connect(&m_http
, SIGNAL(done(bool)), this, SLOT(downloadBlFinish(bool)));
97 // connect the http read signal to our logProgess *signal*
98 // to immediately emit it without any helper function.
99 connect(&m_http
, SIGNAL(dataReadProgress(int, int)),
100 this, SIGNAL(logProgress(int, int)));
101 m_http
.getFile(source
);
105 void BootloaderInstallBase::downloadReqFinished(int id
, bool error
)
107 qDebug() << "[BootloaderInstallBase] Download Request" << id
108 << "finished, error:" << m_http
.errorString();
110 downloadBlFinish(error
);
114 void BootloaderInstallBase::downloadBlFinish(bool error
)
116 qDebug() << "[BootloaderInstallBase] Downloading bootloader finished, error:"
119 // update progress bar
120 emit
logProgress(100, 100);
122 if(m_http
.httpResponse() != 200) {
123 emit
logItem(tr("Download error: received HTTP error %1.")
124 .arg(m_http
.errorString()), LOGERROR
);
129 emit
logItem(tr("Download error: %1")
130 .arg(m_http
.error()), LOGERROR
);
134 else if(m_http
.isCached())
135 emit
logItem(tr("Download finished (cache used)."), LOGOK
);
137 emit
logItem(tr("Download finished."), LOGOK
);
139 QCoreApplication::processEvents();
140 m_blversion
= m_http
.timestamp();
144 void BootloaderInstallBase::installBlfile(void)
146 qDebug() << "[BootloaderInstallBase] installBlFile(void)";
150 //! @brief backup OF file.
151 //! @param to folder to write backup file to. Folder will get created.
152 //! @return true on success, false on error.
154 bool BootloaderInstallBase::backup(QString to
)
156 qDebug() << "[BootloaderInstallBase] Backing up bootloader file";
158 emit
logItem(tr("Creating backup of original firmware file."), LOGINFO
);
159 if(!targetDir
.mkpath(to
)) {
160 emit
logItem(tr("Creating backup folder failed"), LOGERROR
);
163 QString tofile
= to
+ "/" + QFileInfo(m_blfile
).fileName();
164 qDebug() << "[BootloaderInstallBase] trying to backup" << m_blfile
<< "to" << tofile
;
165 if(!QFile::copy(Utils::resolvePathCase(m_blfile
), tofile
)) {
166 emit
logItem(tr("Creating backup copy failed."), LOGERROR
);
169 emit
logItem(tr("Backup created."), LOGOK
);
174 //! @brief log installation to logfile.
175 //! @param mode action to perform. 0: add to log, 1: remove from log.
176 //! @return 0 on success
177 int BootloaderInstallBase::logInstall(LogMode mode
)
180 QString section
= m_blurl
.path().section('/', -1);
181 QSettings
s(m_logfile
, QSettings::IniFormat
, this);
182 emit
logItem(tr("Creating installation log"), LOGINFO
);
185 s
.setValue("Bootloader/" + section
, m_blversion
.toString(Qt::ISODate
));
186 qDebug() << "[BootloaderInstallBase] Writing log, version:"
187 << m_blversion
.toString(Qt::ISODate
);
190 s
.remove("Bootloader/" + section
);
194 emit
logItem(tr("Installation log created"), LOGOK
);
200 //! @brief Return post install hints string.
201 //! @param model model string
203 QString
BootloaderInstallBase::postinstallHints(QString model
)
206 QString msg
= tr("Bootloader installation is almost complete. "
207 "Installation <b>requires</b> you to perform the "
208 "following steps manually:");
211 msg
+= tr("<li>Safely remove your player.</li>");
212 if(model
== "sansafuzeplus") {
213 msg
+= tr("<li>Remove any previously inserted microSD card</li>");
216 if(model
== "h100" || model
== "h120" || model
== "h300" ||
217 model
== "ondavx747") {
219 msg
+= tr("<li>Reboot your player into the original firmware.</li>"
220 "<li>Perform a firmware upgrade using the update functionality "
221 "of the original firmware. Please refer to your player's manual "
222 "on details.<br/><b>Important:</b> updating the firmware is a "
223 "critical process that must not be interrupted. <b>Make sure the "
224 "player is charged before starting the firmware update "
226 "<li>After the firmware has been updated reboot your player.</li>");
228 if(model
== "sansafuzeplus") {
230 msg
+= tr("<li>Disconnect your player. The player will reboot and "
231 "perform an update of the original firmware. "
232 "Please refer to your players manual on details.<br/>"
233 "<b>Important:</b> updating the firmware is a "
234 "critical process that must not be interrupted. <b>Make sure the "
235 "player is charged before disconnecting the player.</b></li>"
236 "<li>After the firmware has been updated reboot your player.</li>");
238 if(model
== "iaudiox5" || model
== "iaudiom5"
239 || model
== "iaudiox5v" || model
== "iaudiom3" || model
== "mpioh200") {
241 msg
+= tr("<li>Turn the player off</li>"
242 "<li>Insert the charger</li>");
244 if(model
== "gigabeatf") {
246 msg
+= tr("<li>Unplug USB and power adaptors</li>"
247 "<li>Hold <i>Power</i> to turn the player off</li>"
248 "<li>Toggle the battery switch on the player</li>"
249 "<li>Hold <i>Power</i> to boot into Rockbox</li>");
252 msg
+= tr("<p><b>Note:</b> You can safely install other parts first, but "
253 "the above steps are <b>required</b> to finish the installation!</p>");
262 #if defined(Q_OS_MACX)
263 void BootloaderInstallBase::waitRemount()
265 m_remountTries
= 600;
266 emit
logItem(tr("Waiting for system to remount player"), LOGINFO
);
268 QTimer::singleShot(100, this, SLOT(checkRemount()));
273 void BootloaderInstallBase::checkRemount()
275 #if defined(Q_OS_MACX)
276 if(m_remountTries
--) {
278 // check if device has been remounted
279 QCoreApplication::processEvents();
281 struct statfs
*mntinf
;
283 num
= getmntinfo(&mntinf
, MNT_WAIT
);
285 if(QString(mntinf
->f_mntfromname
).startsWith(m_remountDevice
)
286 && QString(mntinf
->f_fstypename
).contains("msdos", Qt::CaseInsensitive
))
291 // still not remounted, restart timer.
292 QTimer::singleShot(500, this, SLOT(checkRemount()));
293 qDebug() << "[BootloaderInstallBase] Player not remounted yet" << m_remountDevice
;
296 emit
logItem(tr("Player remounted"), LOGINFO
);
297 emit
remounted(true);
301 emit
logItem(tr("Timeout on remount"), LOGERROR
);
302 emit
remounted(false);
308 //! @brief set list of possible bootloader files and pick the existing one.
309 //! @param sl list of possible bootloader files.
310 void BootloaderInstallBase::setBlFile(QStringList sl
)
312 // figue which of the possible bootloader filenames is correct.
313 for(int a
= 0; a
< sl
.size(); a
++) {
314 if(!Utils::resolvePathCase(sl
.at(a
)).isEmpty()) {
318 if(m_blfile
.isEmpty()) {