From f6060d62d90c6920bd6edf9ed618f41b9cf7b60f Mon Sep 17 00:00:00 2001 From: Solomon Peachy Date: Sun, 19 Jul 2020 17:13:55 -0400 Subject: rbutil: Add support for the xDuoo X3, X3ii, X20, and AGPTek Rocker. * All include full bootloader installation! * X20 lack USB VID/PIDs so cannot be autodetected. * Benjie T6 (variant/OEM of the Rocker) USB VID/PID unknown. Change-Id: Ia823de072c83506d36410ec436be15a0caf97151 --- rbutil/rbutilqt/base/bootloaderinstallbspatch.cpp | 179 ++++++++++++++++++++++ rbutil/rbutilqt/base/bootloaderinstallbspatch.h | 47 ++++++ rbutil/rbutilqt/base/bootloaderinstallhelper.cpp | 6 +- rbutil/rbutilqt/rbutil.ini | 64 ++++++++ rbutil/rbutilqt/rbutilqt.pri | 2 + 5 files changed, 296 insertions(+), 2 deletions(-) create mode 100644 rbutil/rbutilqt/base/bootloaderinstallbspatch.cpp create mode 100644 rbutil/rbutilqt/base/bootloaderinstallbspatch.h diff --git a/rbutil/rbutilqt/base/bootloaderinstallbspatch.cpp b/rbutil/rbutilqt/base/bootloaderinstallbspatch.cpp new file mode 100644 index 0000000000..c9cbd91abe --- /dev/null +++ b/rbutil/rbutilqt/base/bootloaderinstallbspatch.cpp @@ -0,0 +1,179 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2020 by Solomon Peachy + * + * 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 +#include "bootloaderinstallbase.h" +#include "bootloaderinstallbspatch.h" +#include "../bspatch/bspatch.h" +#include "Logger.h" + +/* class for running bspatch() in a separate thread to keep the UI responsive. */ +class BootloaderThreadBSPatch : public QThread +{ + public: + void run(void); + void setInputFile(QString f) + { m_inputfile = f; } + void setOutputFile(QString f) + { m_outputfile = f; } + void setBootloaderFile(QString f) + { m_bootfile = f; } + int error(void) + { return m_error; } + private: + QString m_inputfile; + QString m_bootfile; + QString m_outputfile; + int m_error; +}; + +void BootloaderThreadBSPatch::run(void) +{ + LOG_INFO() << "Thread started."; + + m_error = apply_bspatch(m_inputfile.toLocal8Bit().constData(), + m_outputfile.toLocal8Bit().constData(), + m_bootfile.toLocal8Bit().constData()); + + LOG_INFO() << "Thread finished, result:" << m_error; +} + +BootloaderInstallBSPatch::BootloaderInstallBSPatch(QObject *parent) + : BootloaderInstallBase(parent) +{ + m_thread = NULL; +} + +QString BootloaderInstallBSPatch::ofHint() +{ + return tr("Bootloader installation requires you to provide " + "the correct verrsion of the original firmware file. " + "This file will be patched with the Rockbox bootloader and " + "installed to your player. You need to download this file " + "yourself due to legal reasons. Please refer to the " + "rockbox wiki " + "pages on how to obtain this file.
" + "Press Ok to continue and browse your computer for the firmware " + "file."); +} + +/** Start bootloader installation. + */ +bool BootloaderInstallBSPatch::install(void) +{ + if(!QFileInfo(m_offile).isReadable()) + { + LOG_ERROR() << "could not read original firmware file" + << m_offile; + emit logItem(tr("Could not read original firmware file"), LOGERROR); + return false; + } + + LOG_INFO() << "downloading bootloader"; + // download bootloader from server + emit logItem(tr("Downloading bootloader file"), LOGINFO); + connect(this, SIGNAL(downloadDone()), this, SLOT(installStage2())); + downloadBlStart(m_blurl); + return true; +} + +void BootloaderInstallBSPatch::installStage2(void) +{ + LOG_INFO() << "patching file..."; + emit logItem(tr("Patching file..."), LOGINFO); + m_tempfile.open(); + + // we have not detailed progress on the patching so just show a busy + // indicator instead. + emit logProgress(0, 0); + m_patchedFile.open(); + m_thread = new BootloaderThreadBSPatch(); + m_thread->setInputFile(m_offile); + m_thread->setBootloaderFile(m_tempfile.fileName()); + m_thread->setOutputFile(m_patchedFile.fileName()); + m_tempfile.close(); + m_patchedFile.close(); + connect(m_thread, SIGNAL(finished()), this, SLOT(installStage3())); + connect(m_thread, SIGNAL(terminated()), this, SLOT(installStage3())); + m_thread->start(); +} + +void BootloaderInstallBSPatch::installStage3(void) +{ + int err = m_thread->error(); + emit logProgress(1, 1); + // if the patch failed + if (err != 0) + { + LOG_ERROR() << "Could not patch the original firmware file"; + emit logItem(tr("Patching the original firmware failed"), LOGERROR); + emit done(true); + return; + } + + LOG_INFO() << "Original Firmware succesfully patched"; + emit logItem(tr("Succesfully patched firmware file"), LOGINFO); + + // if a bootloader is already present delete it. + QString fwfile(m_blfile); + if(QFileInfo(fwfile).isFile()) + { + LOG_INFO() << "deleting old target file"; + QFile::remove(fwfile); + } + + // place (new) bootloader. Copy, since the temporary file will be removed + // automatically. + LOG_INFO() << "moving patched bootloader to" << fwfile; + if(m_patchedFile.copy(fwfile)) + { + emit logItem(tr("Bootloader successful installed"), LOGOK); + logInstall(LogAdd); + emit done(false); + } + else + { + emit logItem(tr("Patched bootloader could not be installed"), LOGERROR); + emit done(true); + } + // clean up thread object. + delete m_thread; + return; +} + +bool BootloaderInstallBSPatch::uninstall(void) +{ + emit logItem(tr("To uninstall, perform a normal upgrade with an unmodified " + "original firmware."), LOGINFO); + logInstall(LogRemove); + emit done(true); + return false; +} + + +BootloaderInstallBase::BootloaderType BootloaderInstallBSPatch::installed(void) +{ + return BootloaderUnknown; +} + + +BootloaderInstallBase::Capabilities BootloaderInstallBSPatch::capabilities(void) +{ + return (Install | NeedsOf); +} diff --git a/rbutil/rbutilqt/base/bootloaderinstallbspatch.h b/rbutil/rbutilqt/base/bootloaderinstallbspatch.h new file mode 100644 index 0000000000..7108820fda --- /dev/null +++ b/rbutil/rbutilqt/base/bootloaderinstallbspatch.h @@ -0,0 +1,47 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Copyright (C) 2020 Solomon Peachy + * + * 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. + * + ****************************************************************************/ +#ifndef BOOTLOADERINSTALLBSPATCH_H +#define BOOTLOADERINSTALLBSPATCH_H + +#include +#include "bootloaderinstallbase.h" + +class BootloaderThreadBSPatch; + +//! bootloader installation class for devices handled by mkimxboot. +class BootloaderInstallBSPatch : public BootloaderInstallBase +{ + Q_OBJECT + public: + BootloaderInstallBSPatch(QObject *parent); + bool install(void); + bool uninstall(void); + BootloaderInstallBase::BootloaderType installed(void); + Capabilities capabilities(void); + QString ofHint(); + + private slots: + void installStage2(void); + void installStage3(void); + + private: + BootloaderThreadBSPatch *m_thread; + QTemporaryFile m_patchedFile; +}; + +#endif diff --git a/rbutil/rbutilqt/base/bootloaderinstallhelper.cpp b/rbutil/rbutilqt/base/bootloaderinstallhelper.cpp index d6d2dbc7a1..d7d7ace5e9 100644 --- a/rbutil/rbutilqt/base/bootloaderinstallhelper.cpp +++ b/rbutil/rbutilqt/base/bootloaderinstallhelper.cpp @@ -32,6 +32,7 @@ #include "bootloaderinstallmpio.h" #include "bootloaderinstallimx.h" #include "bootloaderinstalls5l.h" +#include "bootloaderinstallbspatch.h" BootloaderInstallBase* BootloaderInstallHelper::createBootloaderInstaller(QObject* parent, QString type) { @@ -68,10 +69,12 @@ BootloaderInstallBase* BootloaderInstallHelper::createBootloaderInstaller(QObjec else if(type == "s5l") { return new BootloaderInstallS5l(parent); } + else if(type == "bspatch") { + return new BootloaderInstallBSPatch(parent); + } else { return NULL; } - } @@ -134,4 +137,3 @@ QString BootloaderInstallHelper::postinstallHints(QString model) else return QString(); } - diff --git a/rbutil/rbutilqt/rbutil.ini b/rbutil/rbutilqt/rbutil.ini index 7034e46f42..2c113c89ce 100644 --- a/rbutil/rbutilqt/rbutil.ini +++ b/rbutil/rbutilqt/rbutil.ini @@ -91,6 +91,10 @@ platform101=gogearhdd1630 platform102=gogearhdd6330 platform103=gogearsa9200 platform110=creativezenxfi3 +platform120=xduoox3 +platform130=xduoox3ii +platform131=xduoox20 +platform132=agptekrocker ; devices sections ; @@ -873,6 +877,66 @@ configure_modelname=creativezenxfi3 playerpic=creativezenxfi3 encoder=rbspeex +[xduoox3] +name="xDuoo X3" +buildserver_modelname=xduoox3 +bootloadermethod=bspatch +bootloadername=/xduoo/X3-v11.bsdiff +bootloaderfile=update.zip +bootloaderfilter=*.zip +manualname= +brand=xDuoo +usbid=0x0525a4a5 +usberror= +configure_modelname=xduoox3 +playerpic=xduoox3 +encoder=rbspeex + +[xduoox3ii] +name="xDuoo X3 II" +buildserver_modelname=xduoox3ii +bootloadermethod=bspatch +bootloadername=/xduoo/X3II-v13.bsdiff +bootloaderfile=/update.upt +bootloaderfilter=*.upt *.zip +manualname= +brand=xDuoo +usbid=0x003cc502 +usberror= +configure_modelname=xduoox3ii +playerpic=xduoox3ii +encoder=rbspeex + +[xduoox20] +name="xDuoo X20" +buildserver_modelname=xduoox20 +bootloadermethod=bspatch +bootloadername=/xduoo/X20-v18.bsdiff +bootloaderfile=/update.upt +bootloaderfilter=*.upt *.zip +manualname= +brand=xDuoo +;usbid=0x0525a4a5 +usberror= +configure_modelname=xduoox20 +playerpic=xduoox20 +encoder=rbspeex + +[agptekrocker] +name="AGPTek Rocker" +buildserver_modelname=agptekrocker +bootloadermethod=bspatch +bootloadername=/agptek/ROCKER-20171101.bsdiff +bootloaderfile=/update.upt +bootloaderfilter=*.upt *.zip +manualname= +brand=AGPTek +usbid=0xc5020029 +usberror= +configure_modelname=agptekrocker +playerpic=agptekrocker +encoder=rbspeex + ; incompatible devices sections ; each section uses a USB VID / PID string as section name. ; name: human readable string to show the user when this device is detected. diff --git a/rbutil/rbutilqt/rbutilqt.pri b/rbutil/rbutilqt/rbutilqt.pri index d88ecac8cf..f622d1a0de 100644 --- a/rbutil/rbutilqt/rbutilqt.pri +++ b/rbutil/rbutilqt/rbutilqt.pri @@ -55,6 +55,7 @@ SOURCES += \ sysinfo.cpp \ systrace.cpp \ base/bootloaderinstallbase.cpp \ + base/bootloaderinstallbspatch.cpp \ base/bootloaderinstallhelper.cpp \ base/bootloaderinstallmi4.cpp \ base/bootloaderinstallhex.cpp \ @@ -134,6 +135,7 @@ HEADERS += \ base/system.h \ systrace.h \ base/bootloaderinstallbase.h \ + base/bootloaderinstallbspatch.h \ base/bootloaderinstallhelper.h \ base/bootloaderinstallmi4.h \ base/bootloaderinstallhex.h \ -- cgit