diff --git a/TegraRcmGUI.pro b/TegraRcmGUI.pro index 00a02c7..849d130 100644 --- a/TegraRcmGUI.pro +++ b/TegraRcmGUI.pro @@ -5,6 +5,7 @@ CONFIG += c++11 RC_ICONS = res/TegraRcmGUI.ico + # The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the @@ -22,6 +23,7 @@ SOURCES += \ main.cpp \ qkourou.cpp \ qpayload.cpp \ + qsettings.cpp \ qtools.cpp \ qutils.cpp \ tegrarcmgui.cpp @@ -33,6 +35,7 @@ HEADERS += \ kourou/usb_command.h \ qkourou.h \ qpayload.h \ + qsettings.h \ qtools.h \ qutils.h \ rcm_device.h \ @@ -41,15 +44,28 @@ HEADERS += \ FORMS += \ qpayload.ui \ + qsettings.ui \ qtools.ui \ tegrarcmgui.ui TRANSLATIONS = languages/tegrarcmgui_fr.ts -LIBS += -L$$PWD/../../../../../../../libusbK-dev-kit/bin/lib/amd64/ -llibusbK +ARCH = 32 +#ARCH = 64 + +contains( ARCH, 64 ) { + LIBS += -L$$PWD/../../../../../../../libusbK-dev-kit/bin/lib/amd64/ -llibusbK +} +contains( ARCH, 32 ) { + LIBS += -L$$PWD/../../../../../../../libusbK-dev-kit/bin/lib/x86/ -llibusbK +} INCLUDEPATH += $$PWD/../../../../../../../libusbK-dev-kit/includes DEPENDPATH += $$PWD/../../../../../../../libusbK-dev-kit/includes + + +LIBS += -lsetupapi + RESOURCES += \ qresources.qrc diff --git a/ariane/out/ariane.bin b/ariane/out/ariane.bin index e190994..e1b7206 100644 Binary files a/ariane/out/ariane.bin and b/ariane/out/ariane.bin differ diff --git a/ariane/src/main.c b/ariane/src/main.c index 12e7165..4a82e73 100644 --- a/ariane/src/main.c +++ b/ariane/src/main.c @@ -527,6 +527,8 @@ void on_RebootRCMCommand() clock_halt_bpmp(); } + + bool get_autoRCM_state(bool *state) { if(!initialize_mount(NULL, 1)) @@ -600,6 +602,12 @@ bool set_autoRCM_state(bool autoRCM) return true; } +void on_setAutoRcmCommand(bool state) +{ + bool res = set_autoRCM_state(state); + send_response((const void*)&res, sizeof(bool)); // Notify caller +} + void on_getDeviceInfoCommand(FATFS *fs) { // Init a device info struct @@ -636,10 +644,8 @@ void on_getDeviceInfoCommand(FATFS *fs) di.emmc_fs_type = fs->fs_type; di.emmc_fs_cl_size = fs->csize; di.emmc_fs_last_cl = fs->n_fatent - 2; - printk("di.emmc_fs_last_cl = %lu\n", emmc_fs_last_cl); FATFS *ffs; f_getfree("", &di.emmc_fs_free_cl, &ffs); - printk("di.emmc_fs_free_cl = %lu\n", di.emmc_fs_free_cl); FILINFO fno; di.cfw_sxos = (f_stat("boot.dat", &fno) == FR_OK); di.cbl_hekate = (f_stat("bootloader/hekate_ipl.ini", &fno) == FR_OK); @@ -753,19 +759,22 @@ int main(void) break; case WRITE_SD_FILE : on_WriteSDFileCommand(); - break; - + break; case PUSH_PAYLOAD : on_PushPayloadCommand(); - break; - + break; case REBOOT_RCM : on_RebootRCMCommand(); break; - case GET_DEVICE_INFO: on_getDeviceInfoCommand(&fs); break; + case SET_AUTORCM_ON: + on_setAutoRcmCommand(true); + break; + case SET_AUTORCM_OFF: + on_setAutoRcmCommand(false); + break; } } diff --git a/ariane/src/usb_command.h b/ariane/src/usb_command.h index 06a2b65..74e4304 100644 --- a/ariane/src/usb_command.h +++ b/ariane/src/usb_command.h @@ -24,7 +24,9 @@ typedef enum _UC_CommandType PUSH_PAYLOAD, REBOOT_RCM, GET_DEVICE_INFO, - GET_STATUS + GET_STATUS, + SET_AUTORCM_ON, + SET_AUTORCM_OFF } UC_CommandType; diff --git a/kourou/kourou.cpp b/kourou/kourou.cpp index 21f09b4..903fb02 100644 --- a/kourou/kourou.cpp +++ b/kourou/kourou.cpp @@ -199,3 +199,22 @@ bool Kourou::rebootToRcm() return response; } + +bool Kourou::setAutoRcmEnabled(bool state) +{ + if (!arianeIsReady_sync()) + return false; + + UC_Header uc; + uc.command = state ? SET_AUTORCM_ON : SET_AUTORCM_OFF; + // Send command + write((const u8*)&uc, sizeof(uc)); + + // Get response + bool response = false; + if (!readResponse(&response, sizeof(bool))) + return false; + + return response; + +} diff --git a/kourou/kourou.h b/kourou/kourou.h index 44f4963..1c0c9e9 100644 --- a/kourou/kourou.h +++ b/kourou/kourou.h @@ -29,7 +29,8 @@ typedef enum _KRESULT : DWORD { RCM_REBOOT_FAILED = 0x00F, ARIANE_NOT_READY = 0x010, - WRONG_PARAM_GENERIC = 0x011 + WRONG_PARAM_GENERIC = 0x011, + FAILED_TO_SET_AUTORCM = 0x012 } KRESULT; @@ -48,6 +49,7 @@ public: bool arianeIsReady_sync(); void setArianeReady(bool b) { m_ariane_ready = b; } bool rebootToRcm(); + bool setAutoRcmEnabled(bool state); private: int sendBinPackets(char* buffer, u32 len); diff --git a/kourou/libs/rcm_device.cpp b/kourou/libs/rcm_device.cpp index 21c6517..5c4a00a 100644 --- a/kourou/libs/rcm_device.cpp +++ b/kourou/libs/rcm_device.cpp @@ -46,12 +46,19 @@ bool RcmDevice::initDevice(KLST_DEVINFO_HANDLE deviceInfo) return false; }; + // Load driver API + if (!m_usbAPI_loaded) + { + LibK_LoadDriverAPI(&m_usbApi, KUSB_DRVID_LIBUSBK); + m_usbAPI_loaded = true; + } + if (deviceInfo != nullptr && (deviceInfo->Common.Vid != RCM_VID && deviceInfo->Common.Pid != RCM_PID)) return error(WRONG_DEVICE_VID_PID); KLST_DEVINFO_HANDLE tmp_devInfo = deviceInfo != nullptr ? deviceInfo : m_devInfo; if(tmp_devInfo == nullptr && !getPluggedDevice(&tmp_devInfo)) - return error(DEVICE_NOT_FOUND); + return error(DEVICE_NOT_FOUND); // New device already initialized & connected, return ready state (no need to load anything else) if (m_devInfo != nullptr && m_devStatus == CONNECTED && m_devInfo->DeviceID == tmp_devInfo->DeviceID) @@ -62,14 +69,7 @@ bool RcmDevice::initDevice(KLST_DEVINFO_HANDLE deviceInfo) m_devIsInitialized = false; if (m_devInfo->DriverID != KUSB_DRVID_LIBUSBK) - return error(MISSING_LIBUSBK_DRIVER); - - // Load driver API - if (!m_usbAPI_loaded) - { - LibK_LoadDriverAPI(&m_usbApi, KUSB_DRVID_LIBUSBK); - m_usbAPI_loaded = true; - } + return error(MISSING_LIBUSBK_DRIVER); // Init USB handle m_usbApi.Free(m_usbHandle); // Free previous usb handle diff --git a/kourou/libs/rcm_device.h b/kourou/libs/rcm_device.h index ac4a102..d64269f 100644 --- a/kourou/libs/rcm_device.h +++ b/kourou/libs/rcm_device.h @@ -18,6 +18,9 @@ #define RCMDEVICE_H #include +#include +#include +#include #include "libusbk_int.h" #include #include "../../types.h" @@ -147,7 +150,7 @@ private: bool m_usbAPI_loaded = false; DEVICE_STATUS m_devStatus; -private: +private: bool getPluggedDevice(KLST_DEVINFO_HANDLE *devinfo); int switchToHighBuffer(); u32 getCurrentBufferAddress() const { return m_currentBuffer == 0 ? 0x40005000u : 0x40009000u; } diff --git a/kourou/usb_command.h b/kourou/usb_command.h index 1236b9a..527938b 100644 --- a/kourou/usb_command.h +++ b/kourou/usb_command.h @@ -29,7 +29,9 @@ typedef enum _UC_CommandType : u8 PUSH_PAYLOAD, REBOOT_RCM, GET_DEVICE_INFO, - GET_STATUS + GET_STATUS, + SET_AUTORCM_ON, + SET_AUTORCM_OFF } UC_CommandType; diff --git a/main.cpp b/main.cpp index df6157c..86aafd0 100644 --- a/main.cpp +++ b/main.cpp @@ -3,7 +3,6 @@ #include #include - int main(int argc, char *argv[]) { QApplication::setAttribute(Qt::AA_EnableHighDpiScaling); diff --git a/qkourou.cpp b/qkourou.cpp index 302aa9e..0abf5cd 100644 --- a/qkourou.cpp +++ b/qkourou.cpp @@ -11,10 +11,11 @@ QKourou::QKourou(QWidget *parent, Kourou* device, TegraRcmGUI* gui) : QWidget(pa connect(this, SIGNAL(clb_error(int)), parent, SLOT(error(int))); connect(this, SIGNAL(clb_deviceStateChange()), parent, SLOT(on_deviceStateChange())); connect(this, SIGNAL(clb_finished(int)), parent, SLOT(on_Kourou_finished(int))); + connect(this, SIGNAL(pushMessage(QString)), parent, SLOT(pushMessage(QString))); } void QKourou::initDevice(bool silent, KLST_DEVINFO_HANDLE deviceInfo) -{ +{ if (!waitUntilUnlock()) return; @@ -99,7 +100,7 @@ DWORD QKourou::autoInject() void QKourou::getDeviceInfo() { - qDebug() << "QKourou::getDeviceInfo() execute in " << QThread::currentThreadId(); + //qDebug() << "QKourou::getDeviceInfo() execute in " << QThread::currentThreadId(); if (!waitUntilUnlock()) return; @@ -117,6 +118,19 @@ void QKourou::getDeviceInfo() } +void QKourou::setAutoRcmEnabled(bool state) +{ + if (!waitUntilUnlock()) + return; + + setLockEnabled(true); + bool res = m_device->setAutoRcmEnabled(state); + setLockEnabled(false); + + if (!res) + emit clb_error(FAILED_TO_SET_AUTORCM); +} + void QKourou::hack(const char* payload_path, u8 *payload_buff, u32 buff_size) { if (!waitUntilUnlock()) @@ -193,7 +207,6 @@ bool QKourou::waitUntilRcmReady(uint timeout_s) return true; } - bool QKourou::waitUntilInit(uint timeout_s) { qint64 begin_timestamp = QDateTime::currentSecsSinceEpoch(); @@ -204,3 +217,62 @@ bool QKourou::waitUntilInit(uint timeout_s) } return true; } + +void QKourou::initNoDriverDeviceLookUpLoop() +{ + connect(this, SIGNAL(clb_driverMissing()), m_gui->settingsTab, SLOT(on_driverMissing())); + QTimer *lookup = new QTimer(this); + connect(lookup, SIGNAL(timeout()), this, SLOT(noDriverDeviceLookUp())); + lookup->start(1000); // Every second + m_askForDriverInstall = true; + m_APX_device_reconnect = true; +} + +void QKourou::noDriverDeviceLookUp() +{ + if (m_device->getStatus() == CONNECTED) + return; + + unsigned index; + HDEVINFO hDevInfo; + SP_DEVINFO_DATA DeviceInfoData; + TCHAR HardwareID[1024]; + bool found = false; + // List all connected USB devices + hDevInfo = SetupDiGetClassDevs(nullptr, TEXT("USB"), nullptr, DIGCF_PRESENT | DIGCF_ALLCLASSES); + for (index = 0; ; index++) + { + DeviceInfoData.cbSize = sizeof(DeviceInfoData); + if (!SetupDiEnumDeviceInfo(hDevInfo, index, &DeviceInfoData)) + break; + + SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_HARDWAREID, nullptr, (BYTE*)HardwareID, sizeof(HardwareID), nullptr); + if (_tcsstr(HardwareID, _T("VID_0955&PID_7321"))) + { + // device found, check driver + BYTE driverPath[256], zeroBuffer[256]; + memset(driverPath, 0, 256); + memset(zeroBuffer, 0, 256); + SetupDiGetDeviceRegistryProperty(hDevInfo, &DeviceInfoData, SPDRP_DRIVER, nullptr, driverPath, 256, nullptr); + if (!memcmp(driverPath, zeroBuffer, 256)) + { + found = true; + // Driver not found + if (!m_askForDriverInstall) + { + if (m_APX_device_reconnect) + emit pushMessage(tr("Device detected but driver is missing\nInstall driver from SETTINGS tab")); + } + else + { + emit clb_driverMissing(); + m_askForDriverInstall = false; + } + m_APX_device_reconnect = false; + } + break; + } + } + if (!found) + m_APX_device_reconnect = true; +} diff --git a/qkourou.h b/qkourou.h index a29cba3..ab4ab65 100644 --- a/qkourou.h +++ b/qkourou.h @@ -38,6 +38,8 @@ private: TegraRcmGUI *m_gui; bool m_locked = false; bool m_force_lock = false; + bool m_askForDriverInstall = true; + bool m_APX_device_reconnect = true; QWidget *parent; std::string tmp_string; void hack(const char* payload_path, u8 *payload_buff, u32 buff_size); @@ -54,14 +56,17 @@ public slots: void getDeviceInfo(); void hack(const char* payload_path); void hack(u8 *payload_buff, u32 buff_size); - + void initNoDriverDeviceLookUpLoop(); + void noDriverDeviceLookUp(); + void setAutoRcmEnabled(bool state); signals: void clb_deviceInfo(UC_DeviceInfo di); void clb_error(int error); void clb_deviceStateChange(); void clb_finished(int res); - + void clb_driverMissing(); + void pushMessage(QString); }; #endif // QKOUROU_H diff --git a/qpayload.cpp b/qpayload.cpp index c147102..e4b210c 100644 --- a/qpayload.cpp +++ b/qpayload.cpp @@ -56,11 +56,12 @@ QPayloadWidget::QPayloadWidget(TegraRcmGUI *parent) : QWidget(parent) buttons.at(i)->setCursor(Qt::PointingHandCursor); } + this->setStyleSheet(GetStyleSheetFromResFile(":/res/QMainWindow.qss")); ui->payload_tableView->setStyleSheet(GetStyleSheetFromResFile(":/res/QTableView.qss")); ui->payloadFrame->setStyleSheet(GetStyleSheetFromResFile(":/res/QFrame_box02.qss")); // Buttons - Switch *_switch = new Switch(parent->m_kourou->autoInjectPayload ? true : false, 70); + Switch *_switch = new Switch(parent->userSettings->value("autoInject").toBool() ? true : false, 50); ui->horizontalLayout->addWidget(_switch); connect(_switch, SIGNAL(clicked()), this, SLOT(on_autoInject_toggled())); //ui->injectPayloadBtn->setCursor(Qt::PointingHandCursor); diff --git a/qpayload.ui b/qpayload.ui index 3bc2504..f4b2e55 100644 --- a/qpayload.ui +++ b/qpayload.ui @@ -108,8 +108,8 @@ color: rgb(255, 255, 255); - 250 - 50 + 270 + 46 81 16 @@ -128,9 +128,9 @@ color: rgb(255, 255, 255); - 340 + 360 40 - 71 + 51 31 diff --git a/qresources.qrc b/qresources.qrc index a2ac1b2..d6408f3 100644 --- a/qresources.qrc +++ b/qresources.qrc @@ -13,5 +13,7 @@ res/QFrame_box02.qss res/delete.ico res/add.ico + res/QLabel_warning.qss + res/QLabel_title02.qss diff --git a/qsettings.cpp b/qsettings.cpp new file mode 100644 index 0000000..368cf6e --- /dev/null +++ b/qsettings.cpp @@ -0,0 +1,62 @@ +#include "qsettings.h" +#include "ui_qsettings.h" +#include "qutils.h" +#include + +qSettings::qSettings(TegraRcmGUI *parent) : QWidget(parent), + ui(new Ui::qSettings), parent(parent) +{ + ui->setupUi(this); + m_kourou = parent->m_kourou; + m_device = &parent->m_device; + + /// Stylesheets + // Apply stylesheet to all buttons + QString btnSs = GetStyleSheetFromResFile(":/res/QPushButton.qss"); + auto buttons = this->findChildren(); + for (int i = 0; i < buttons.count(); i++) + { + buttons.at(i)->setStyleSheet(btnSs); + buttons.at(i)->setCursor(Qt::PointingHandCursor); + } +} + +qSettings::~qSettings() +{ + delete ui; +} + +void qSettings::on_driverMissing() +{ + QString message(tr("The required APX device driver is missing.\nDo you wan to install it now ?")); + if(QMessageBox::question(this, "Warning", message, QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) + { + on_installDriverButton_clicked(); + } +} + +void qSettings::on_installDriverButton_clicked() +{ + QString q_path = QDir(".").absolutePath() + "/apx_driver/InstallDriver.exe"; + + QFile file(q_path); + if (!file.exists()) + return; + + std::wstring w_path = q_path.toStdWString(); + LPCWSTR path = (const wchar_t*) w_path.c_str(); + SHELLEXECUTEINFO shExInfo = { 0 }; + shExInfo.cbSize = sizeof(shExInfo); + shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS; + shExInfo.hwnd = nullptr; + shExInfo.lpVerb = _T("runas"); + shExInfo.lpFile = path; + shExInfo.lpDirectory = nullptr; + shExInfo.nShow = SW_SHOW; + shExInfo.hInstApp = nullptr; + + if (ShellExecuteEx(&shExInfo)) + { + CloseHandle(shExInfo.hProcess); + } +} diff --git a/qsettings.h b/qsettings.h new file mode 100644 index 0000000..6978464 --- /dev/null +++ b/qsettings.h @@ -0,0 +1,38 @@ +#ifndef QSETTINGSU_H +#define QSETTINGSU_H + +#include +#include "tegrarcmgui.h" + +class TegraRcmGUI; +class Kourou; +class QKourou; + +QT_BEGIN_NAMESPACE +namespace Ui { +class qSettings; +} +QT_BEGIN_NAMESPACE + +class qSettings : public QWidget +{ + Q_OBJECT + +public: + explicit qSettings(TegraRcmGUI *parent = nullptr); + ~qSettings(); + +public slots: + void on_driverMissing(); +private slots: + void on_installDriverButton_clicked(); + +private: + Ui::qSettings *ui; + TegraRcmGUI *parent; + QKourou *m_kourou; + Kourou *m_device; + +}; + +#endif // QSETTINGSU_H diff --git a/qsettings.ui b/qsettings.ui new file mode 100644 index 0000000..8a11e8d --- /dev/null +++ b/qsettings.ui @@ -0,0 +1,32 @@ + + + qSettings + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + 10 + 10 + 80 + 22 + + + + Install driver + + + + + + diff --git a/qtools.cpp b/qtools.cpp index 65b7dd2..a0d0f4c 100644 --- a/qtools.cpp +++ b/qtools.cpp @@ -1,14 +1,76 @@ #include "qtools.h" #include "ui_qtools.h" -qTools::qTools(QWidget *parent) : - QWidget(parent), - ui(new Ui::qTools) +qTools::qTools(TegraRcmGUI *parent) : QWidget(parent), + ui(new Ui::qTools), parent(parent) { ui->setupUi(this); + m_kourou = parent->m_kourou; + m_device = &parent->m_device; + connect(this, SIGNAL(error(int)), parent, SLOT(error(int))); + + /// Stylesheets + // Apply stylesheet to all buttons + QString btnSs = GetStyleSheetFromResFile(":/res/QPushButton.qss"); + auto buttons = this->findChildren(); + for (int i = 0; i < buttons.count(); i++) + { + buttons.at(i)->setStyleSheet(btnSs); + buttons.at(i)->setCursor(Qt::PointingHandCursor); + } + + ui->autoRcmFrame->setStyleSheet(GetStyleSheetFromResFile(":/res/QFrame_box02.qss")); + ui->genricToolFrame->setStyleSheet(GetStyleSheetFromResFile(":/res/QFrame_box02.qss")); + ui->autoRcm_warningFrame->setStyleSheet(GetStyleSheetFromResFile(":/res/QLabel_warning.qss")); + ui->autoRcmTitleLbl->setStyleSheet(GetStyleSheetFromResFile(":/res/QLabel_title02.qss")); + + // Buttons + autoRCM_switch = new Switch(false, 50); + ui->autoRcmLayout->addWidget(autoRCM_switch); + connect(autoRCM_switch, SIGNAL(clicked()), this, SLOT(on_autoRcmSwitchToggled())); + + Switch *_switch2 = new Switch(false, 50); + ui->genricToolLayout->addWidget(_switch2); + //connect(_switch, SIGNAL(clicked()), this, SLOT(on_autoInject_toggled())); } qTools::~qTools() { delete ui; } + +void qTools::on_deviceStateChange() +{ + //autoRcm_arianeLbl + + if (!m_device->arianeIsReady() || !parent->isDeviceInfoAvailable()) + { + QString label; + if (m_device->arianeIsReady()) + label.append(tr("Waiting for Ariane response")); + else + { + label.append(tr("Ariane needs to be loaded!\n")); + label.append(m_kourou->autoLaunchAriane ? tr("Boot device to RCM") : tr("Enable Ariane autoboot first")); + } + ui->autoRcm_warningLbl->setText(label); + ui->autoRcm_warningFrame->show(); + autoRCM_switch->hide(); + } + else + { + ui->autoRcm_warningFrame->hide(); + autoRCM_switch->show(); + } +} + +void qTools::on_autoRcmSwitchToggled() +{ + if (!m_device->arianeIsReady()) + { + emit error(ARIANE_NOT_READY); + return; + } + + QtConcurrent::run(m_kourou, &QKourou::setAutoRcmEnabled, autoRCM_switch->getState()); +} diff --git a/qtools.h b/qtools.h index 8702dd5..fc1ae68 100644 --- a/qtools.h +++ b/qtools.h @@ -2,21 +2,41 @@ #define QTOOLS_H #include +#include +#include "tegrarcmgui.h" +#include "qutils.h" -namespace Ui { -class qTools; -} +class TegraRcmGUI; +class Kourou; +class QKourou; + +QT_BEGIN_NAMESPACE +namespace Ui { class qTools; } +QT_END_NAMESPACE class qTools : public QWidget { Q_OBJECT - public: - explicit qTools(QWidget *parent = nullptr); + explicit qTools(TegraRcmGUI *parent = nullptr); ~qTools(); + Switch *autoRCM_switch; private: Ui::qTools *ui; + TegraRcmGUI *parent; + QKourou *m_kourou; + Kourou *m_device; + +public slots: + void on_deviceStateChange(); + +private slots: + void on_autoRcmSwitchToggled(); + +signals: + void error(int); + }; #endif // QTOOLS_H diff --git a/qtools.ui b/qtools.ui index 29fa67f..ba58725 100644 --- a/qtools.ui +++ b/qtools.ui @@ -6,25 +6,192 @@ 0 0 - 400 - 300 + 496 + 404 Form - + - 50 - 30 - 47 - 14 + 20 + 20 + 211 + 121 - - TextLabel + + QFrame::StyledPanel + + QFrame::Raised + + + + + 150 + 80 + 51 + 31 + + + + + + + + 10 + 10 + 191 + 16 + + + + + + + Toggle autoRCM + + + + + + 10 + 30 + 201 + 51 + + + + font: italic 9pt "Calibri"; + + + autoRCM is a controlled brick of BOOT0 +partition. Enabling autoRCM will force +your Switch to boot straight to RCM + + + Qt::AlignJustify|Qt::AlignTop + + + + + + 10 + 79 + 191 + 31 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + true + + + + 0 + 0 + 191 + 31 + + + + + + + + + + Qt::AlignCenter + + + + + + + + 240 + 20 + 211 + 121 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + + 150 + 80 + 51 + 31 + + + + + + + + 10 + 10 + 241 + 16 + + + + font: 75 11pt "Calibri"; + + + Another Tool: + + + + + + 10 + 30 + 201 + 51 + + + + font: italic 9pt "Calibri"; + + + blabababla + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + + 6 + 79 + 141 + 31 + + + + Tool state: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + diff --git a/qutils.cpp b/qutils.cpp index b88000e..d7d3d94 100644 --- a/qutils.cpp +++ b/qutils.cpp @@ -85,7 +85,7 @@ void Switch::paintEvent(QPaintEvent *e) { } } -void Switch::toggle(bool state) +void Switch::toggle() { int toffset = offset(); _switch = _switch ? false : true; @@ -105,7 +105,7 @@ void Switch::toggle(bool state) void Switch::mouseReleaseEvent(QMouseEvent *e) { if (e->button() & Qt::LeftButton) { - toggle(_switch); + toggle(); } QAbstractButton::mouseReleaseEvent(e); } diff --git a/qutils.h b/qutils.h index 6988470..0e41e5a 100644 --- a/qutils.h +++ b/qutils.h @@ -42,8 +42,9 @@ public: } bool isActive() { return _switch; } + bool getState() { return _switch; } void setState(bool value) { _switch = value; } - void toggle(bool state); + void toggle(); protected: void paintEvent(QPaintEvent*) override; diff --git a/res/QLabel_title02.qss b/res/QLabel_title02.qss new file mode 100644 index 0000000..a1054f1 --- /dev/null +++ b/res/QLabel_title02.qss @@ -0,0 +1,5 @@ +QLabel +{ + font: 75 10pt "Rubik"; + color: rgb(0, 150, 136); +} diff --git a/res/QLabel_warning.qss b/res/QLabel_warning.qss new file mode 100644 index 0000000..a9600c1 --- /dev/null +++ b/res/QLabel_warning.qss @@ -0,0 +1,11 @@ +QFrame +{ + border-radius: 5px; + border:1px solid rgb(150, 35, 0); +} + +QLabel +{ + font: 75 9pt "Calibri"; + color: rgb(150, 35, 0); +} diff --git a/res/QMainWindow.qss b/res/QMainWindow.qss index 78392a0..7f084b6 100644 --- a/res/QMainWindow.qss +++ b/res/QMainWindow.qss @@ -13,6 +13,11 @@ QToolTip background-color: rgb(30, 30, 30); color: rgb(255, 255, 255); } -QMessageBox QLabel { +QMessageBox QLabel +{ color: rgb(0, 0, 0); } +QLabel +{ + color: rgb(255, 255, 255); +} diff --git a/res/QTabWidget.qss b/res/QTabWidget.qss index 39a064e..fafac29 100644 --- a/res/QTabWidget.qss +++ b/res/QTabWidget.qss @@ -1,8 +1,7 @@ QTabWidget::pane { border-radius:10px; - background-color: rgb(60, 60, 60); - color: rgb(255, 255, 255); + background-color: rgb(60, 60, 60); } QTabWidget::tab-bar { diff --git a/res/QTableView.qss b/res/QTableView.qss index fa9f9fd..6b25d32 100644 --- a/res/QTableView.qss +++ b/res/QTableView.qss @@ -1,7 +1,8 @@ QTableView { border-radius: 10px; - alternate-background-color: rgb(188, 188, 188); - background: rgb(240, 240, 240); - selection-background-color: rgb(150, 0, 83); + color: rgb(255, 255, 255); + alternate-background-color: rgb(80, 80, 80); + background: rgb(41, 41, 41); + selection-background-color: rgb(30, 105, 98); } diff --git a/tegrarcmgui.cpp b/tegrarcmgui.cpp index aa48d4f..aec7205 100644 --- a/tegrarcmgui.cpp +++ b/tegrarcmgui.cpp @@ -2,6 +2,7 @@ #include "ui_tegrarcmgui.h" #include "qutils.h" #include +#include QMouseEvent MouseLeftButtonEvent(QEvent::MouseButtonPress, QPoint(0,0), Qt::LeftButton, nullptr, nullptr); @@ -32,6 +33,9 @@ TegraRcmGUI::TegraRcmGUI(QWidget *parent) // Init acces to builtin resources Q_INIT_RESOURCE(qresources); + // Load settings + userSettings = new QSettings("nx", "TegraRcmGUI"); + // Tray icon init trayIcon = new QSystemTrayIcon; trayIcon->setIcon(switchOffIcon); @@ -39,22 +43,30 @@ TegraRcmGUI::TegraRcmGUI(QWidget *parent) connect(trayIcon, &QSystemTrayIcon::activated, this, &TegraRcmGUI::trayIconActivated); trayIconMenu = trayIcon->contextMenu(); - // Load settings - userSettings = new QSettings("nx", "TegraRcmGUI"); - // Create a qKourou instance to invoke Kourou methods (asynchronously) using signals and slots m_kourou = new QKourou(this, &m_device, this); m_kourou->autoLaunchAriane = userSettings->value("autoAriane").toBool(); m_kourou->autoInjectPayload = userSettings->value("autoInject").toBool(); + // Init tabs + ui->tabWidget->tabBar()->setCursor(Qt::PointingHandCursor); + ui->push_layout->setAlignment(Qt::AlignTop); + ui->pushLayoutWidget->setAttribute(Qt::WA_TransparentForMouseEvents); + payloadTab = new QPayloadWidget(this); + ui->tabWidget->addTab(payloadTab, tr("PAYLOAD")); + toolsTab = new qTools(this); + ui->tabWidget->addTab(toolsTab, tr("TOOLS")); + settingsTab = new qSettings(this); + ui->tabWidget->addTab(settingsTab, tr("SETTINGS")); + // Load builtin Ariane payload QFile file(":/ariane_bin"); if (file.open(QIODevice::ReadOnly)) { m_kourou->ariane_bin = file.readAll(); file.close(); - } + } // Init device at startup (in a concurrent thread) QtConcurrent::run(m_kourou, &QKourou::initDevice, true, nullptr); @@ -74,7 +86,8 @@ TegraRcmGUI::TegraRcmGUI(QWidget *parent) devInfoTimer->start(60000*5); // Every 5 minutes QTimer *pushTimer = new QTimer(this); connect(pushTimer, SIGNAL(timeout()), this, SLOT(pushTimer())); - pushTimer->start(1000); // Every minute + pushTimer->start(1000); // Every second + m_kourou->initNoDriverDeviceLookUpLoop(); /// GUI inits @@ -86,16 +99,6 @@ TegraRcmGUI::TegraRcmGUI(QWidget *parent) ui->statusBoxFrame->setStyleSheet(GetStyleSheetFromResFile(":/res/QFrame_box01.qss")); ui->deviceInfoBoxFrame->setStyleSheet(GetStyleSheetFromResFile(":/res/QFrame_box01.qss")); - // Init tabs - ui->tabWidget->tabBar()->setCursor(Qt::PointingHandCursor); - ui->push_layout->setAlignment(Qt::AlignTop); - ui->pushLayoutWidget->setAttribute(Qt::WA_TransparentForMouseEvents); - - payloadTab = new QPayloadWidget(this); - ui->tabWidget->addTab(payloadTab, tr("PAYLOAD")); - toolsTab = new qTools(this); - ui->tabWidget->addTab(toolsTab, tr("TOOLS")); - ui->closeAppBtn->setCursor(Qt::PointingHandCursor); connect(ui->closeAppBtn, SIGNAL(clicked()), this, SLOT(close())); @@ -136,19 +139,33 @@ void TegraRcmGUI::deviceInfoTimer() void TegraRcmGUI::on_deviceStateChange() { - ui->devStatusLbl_2->setText(m_device.getStatus() == CONNECTED ? tr("CONNECTED") : tr("DISCONNECTED")); + ui->devStatusLbl_2->setText(tr("DEVICE STATUS")); ui->devStatusFrame->setStyleSheet(m_device.getStatus() == CONNECTED ? statusOnStyleSht : statusOffStyleSht); ui->rcmStatusLbl_2->setText(m_device.rcmIsReady() ? tr("READY") : tr("OFF")); - QString arianeStatus; + QString arianeStatus, arianeStyle; if (m_kourou->arianeIsLoading) + { arianeStatus.append(tr("LOADING")); + arianeStyle = statusOffStyleSht; + } else if (m_device.arianeIsReady()) + { arianeStatus.append(tr("READY")); + arianeStyle = statusOnStyleSht; + } else + { arianeStatus.append(tr("OFF")); + arianeStyle = m_kourou->autoLaunchAriane ? statusOffRedStyleSht : statusOffStyleSht; + } ui->arianeStatusLbl_2->setText(arianeStatus); - ui->rcmStatusFrame->setStyleSheet(m_device.rcmIsReady() ? statusOnStyleSht : statusOffStyleSht); - ui->arianeStatusFrame->setStyleSheet(m_device.arianeIsReady() ? statusOnStyleSht : statusOffStyleSht); + QString style = statusOffRedStyleSht; + if (m_device.arianeIsReady()) + style = statusOffStyleSht; + else if (m_device.rcmIsReady()) + style = statusOnStyleSht; + ui->rcmStatusFrame->setStyleSheet(style); + ui->arianeStatusFrame->setStyleSheet(arianeStyle); if (!m_device.arianeIsReady()) clearDeviceInfo(); @@ -157,8 +174,11 @@ void TegraRcmGUI::on_deviceStateChange() else trayIcon->setIcon(switchOffIcon); - payloadTab->on_deviceStateChange(); + if (m_device.getStatus() != CONNECTED || !m_device.rcmIsReady()) + m_deviceInfoAvailable = false; + payloadTab->on_deviceStateChange(); + toolsTab->on_deviceStateChange(); } void TegraRcmGUI::on_autoLaunchAriane_toggled(bool value) @@ -166,8 +186,15 @@ void TegraRcmGUI::on_autoLaunchAriane_toggled(bool value) m_kourou->autoLaunchAriane = !m_kourou->autoLaunchAriane; userSettings->setValue("autoAriane", m_kourou->autoLaunchAriane); - if (m_device.rcmIsReady() && m_kourou->autoLaunchAriane) + on_deviceStateChange(); + + if (!m_kourou->autoLaunchAriane) + return; + + if (m_device.rcmIsReady()) QtConcurrent::run(m_kourou, &QKourou::initDevice, true, nullptr); + else if (!m_device.arianeIsReady()) + pushMessage((m_device.getStatus() == CONNECTED ? tr("Reboot") : tr("Boot")) + tr(" device to RCM to launch Ariane")); } bool TegraRcmGUI::enableWidget(QWidget *widget, bool enable) @@ -200,6 +227,12 @@ void TegraRcmGUI::clearDeviceInfo() void TegraRcmGUI::on_deviceInfo_received(UC_DeviceInfo di) { + if (!m_deviceInfoAvailable) + { + m_deviceInfoAvailable = true; + toolsTab->on_deviceStateChange(); + } + else m_deviceInfoAvailable = true; ui->batteryLbl->show(); ui->burntFusesLbl1->show(); ui->sdfsLbl1->show(); @@ -230,11 +263,27 @@ void TegraRcmGUI::on_deviceInfo_received(UC_DeviceInfo di) ui->fsTotSizeLbl2->setText("N/A"); ui->fsFreeSpaceLbl2->setText("N/A"); } + + if (di.autoRCM != toolsTab->autoRCM_switch->isActive()) + toolsTab->autoRCM_switch->toggle(); } void TegraRcmGUI::error(int error) { - QMessageBox::critical(this, "Error", QString().asprintf("Error %d", error)); + if (error == FAILED_TO_SET_AUTORCM) + toolsTab->autoRCM_switch->toggle(); + + QString err_label; + for (ErrorLabel item : ErrorLabelArr) + { + if (item.error == error) + err_label = item.label; + } + + if (!err_label.size()) + err_label.append(QString().asprintf("Error %d", error)); + + QMessageBox::critical(this, "Error", err_label); } void TegraRcmGUI::pushMessage(QString message) diff --git a/tegrarcmgui.h b/tegrarcmgui.h index abd85f4..133570a 100644 --- a/tegrarcmgui.h +++ b/tegrarcmgui.h @@ -6,11 +6,14 @@ #include #include "qpayload.h" #include "qtools.h" +#include "qsettings.h" #include "kourou/kourou.h" #include "kourou/usb_command.h" #include "qkourou.h" class QPayloadWidget; +class qTools; +class qSettings; class QKourou; QT_BEGIN_NAMESPACE @@ -36,7 +39,9 @@ public: QKourou *m_kourou; QPayloadWidget *payloadTab; qTools *toolsTab; + qSettings *settingsTab; bool enableWidget(QWidget *widget, bool enable); + bool isDeviceInfoAvailable() { return m_deviceInfoAvailable; } private slots: void on_deviceInfo_received(UC_DeviceInfo di); @@ -58,8 +63,7 @@ signals: private: Ui::TegraRcmGUI *ui; KHOT_HANDLE m_hotHandle = nullptr; - - bool m_ready = false; + bool m_deviceInfoAvailable = false; std::string tmp_string; QVector push_ts; int tsToDeleteCount = 0; @@ -81,4 +85,15 @@ const QString statusOffStyleSht("QFrame{border-radius: 10px; background-color: r const QString statusOffRedStyleSht("QFrame{border-radius: 10px; background-color: rgb(150, 35, 0); border-color: rgb(0, 0, 0);}" "QLabel{font: 75 9pt \"Calibri\"; color: rgb(255, 255, 255);}"); +typedef struct ErrorLabel ErrorLabel; +struct ErrorLabel { + int error; + QString label; +}; + +static ErrorLabel ErrorLabelArr[] = +{ + { FAILED_TO_SET_AUTORCM, "Failed to set autoRCM" }, +}; + #endif // TEGRARCMGUI_H