summaryrefslogtreecommitdiffstats
path: root/src/fbgui.cpp
diff options
context:
space:
mode:
authorNiklas Goby2011-11-23 11:56:19 +0100
committerNiklas Goby2011-11-23 11:56:19 +0100
commitc0b6b199a9878bc1e95907200501211c09c1e66c (patch)
tree0079c34c6536e5f1d0414aebde1793db60a78f35 /src/fbgui.cpp
parentdeleted the NetworkDiscovery and UnixDomainSocketServer folder (diff)
downloadfbgui-c0b6b199a9878bc1e95907200501211c09c1e66c.tar.gz
fbgui-c0b6b199a9878bc1e95907200501211c09c1e66c.tar.xz
fbgui-c0b6b199a9878bc1e95907200501211c09c1e66c.zip
created modules
Diffstat (limited to 'src/fbgui.cpp')
-rw-r--r--src/fbgui.cpp492
1 files changed, 0 insertions, 492 deletions
diff --git a/src/fbgui.cpp b/src/fbgui.cpp
deleted file mode 100644
index 22a2ac6..0000000
--- a/src/fbgui.cpp
+++ /dev/null
@@ -1,492 +0,0 @@
-#include "fbgui.h"
-#include "sysinfo.h"
-#include "loggerengine.h"
-#include "downloadmanager.h"
-#include "javascriptinterface.h"
-
-#include <iostream>
-#include <QThread>
-#include <QtWebKit>
-#include <QxtCore>
-
-QThread dmThread;
-QString logFilePath("");
-QString ipConfigFilePath("");
-QString binPath("");
-QUrl baseURL("");
-QString downloadPath("");
-int updateInterval = -1;
-QString fileToTriggerURL("");
-QString serialLocation("");
-QString sessionID("");
-int debugMode = -1;
-
-//-------------------------------------------------------------------------------------------
-/**
- * A constructor.
- *
- * The constructor of the fbgui class. It initializes the main objects
- * which are needed while the program is running.
- * The appearance of the webView is here also defined.
- *
- * @see JavascriptInterface
- * @see DownloadManager
- */
-fbgui::fbgui() {
-}
-fbgui::~fbgui() {
- dmThread.quit();
-}
-
-
-
-/**
- * init function.
- */
-void fbgui::init() {
- // start fbgui
- qxtLog->debug() << "Initializing fbgui...";
-
- setupLayout();
- createActions();
-
- // initialize javascript interface
- JavascriptInterface* jsi = new JavascriptInterface(
- _webView->page()->mainFrame());
- QObject::connect(jsi, SIGNAL(quitFbgui()), this, SLOT(close()));
- QObject::connect(jsi, SIGNAL(shutDownClient()), this,
- SLOT(performShutDown()));
- QObject::connect(_webView->page()->mainFrame(), SIGNAL(
- javaScriptWindowObjectCleared()), jsi, SLOT(attachToDOM()));
-
- // initialize download manager
- DownloadManager* dm = new DownloadManager();
- QObject::connect(dm, SIGNAL(downloadInfo(const QString&, const double&)),
- jsi, SLOT(downloadInfo(const QString&, const double&)));
- QObject::connect(dm, SIGNAL(notify(const QString&)), jsi,
- SLOT(notify(const QString&)));
- QObject::connect(jsi, SIGNAL(requestFile(const QString&)), dm,
- SLOT(downloadFile(const QString&)));
- QObject::connect(
- dm,
- SIGNAL(updateProgress(const int&, const double&, const QString&)),
- jsi,
- SLOT(updateProgressBar(const int&, const double&, const QString&)));
- QObject::connect(dm, SIGNAL(downloadQueueEmpty()), jsi, SLOT(
- callbackOnFinished()));
- QObject::connect(dm, SIGNAL(downloadQueueEmpty()), this, SLOT(loadSystem()));
-
- // move download manager to its own thread
- dm->moveToThread(&dmThread);
- dmThread.start();
-
- // show "waiting for internet" page until triggered.
- if (debugMode > -1) {
- _webView->load(QUrl("qrc:/html/preload-debug.html"));
- } else {
- _webView->load(QUrl("qrc:/html/preload.html"));
- }
-
- // watcher is not needed anymore since we guarantee internet connection with the networkDiscovery.
- // start watching for fileToTriggerURL
- //watchForTrigger();
- loadURL();
-
- // set properties
- setWindowTitle("fbgui");
- setAttribute(Qt::WA_QuitOnClose, true);
- setWindowFlags(Qt::FramelessWindowHint);
- showFullScreen();
- this->show();
-}
-//-------------------------------------------------------------------------------------------
-// Layout / actions setup
-//-------------------------------------------------------------------------------------------
-/**
- * This method sets the used Layout.
- *
- * This method sets the used Layout. Possible layout are:
- * - browser mode: only the browser is visible
- * - debug mode: the screen is divided into the browser and a debug
- * out console
- */
-void fbgui::setupLayout() {
- // setup layout of the gui: debug split or browser
- _webView = new QWebView(this);
- if (debugMode == 1) {
- // split main window in browser & debug console
- createDebugConsole();
- _splitter = new QSplitter(Qt::Vertical, this);
- _splitter->addWidget(_webView);
- _splitter->addWidget(_debugConsole);
- setCentralWidget(_splitter);
- } else
- setCentralWidget(_webView);
-}
-//-------------------------------------------------------------------------------------------
-/**
- * This method enables a shortcut for closing the program.
- * The shortcut itself is not configurable: CTRL + X
- */
-void fbgui::createActions() {
- _quit = new QAction(tr("&quit"), this);
- _quit->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_X));
- this->addAction(_quit);
- connect(_quit, SIGNAL(triggered()), this, SLOT(close()));
-}
-//-------------------------------------------------------------------------------------------
-// File system watching
-//-------------------------------------------------------------------------------------------
-/**
- * This method sets a "watchdog" to a special file.
- *
- * This method sets a "watchdog" to a special file. If needed it creates the
- * file which it has to watch over. It than connects a QFileSystemWatcher with
- * this file. If changes happen to this file, the
- * fbgui::checkForTrigger(const QString& dirname) method will be called.
- *
- */
-void fbgui::watchForTrigger() {
- // check if fileToTriggerURL already exists
- QFile file(fileToTriggerURL);
- if (file.exists()) {
- qxtLog->debug() << "[watcher] " << fileToTriggerURL << " found.";
- // try to load URL
- loadURL();
- } else {
- // create it
- if (file.open(QIODevice::WriteOnly)) {
- qxtLog->debug() << "[gui] Created: " << fileToTriggerURL;
- file.close();
- } else {
- qxtLog->debug() << "[gui] Creation of " << fileToTriggerURL
- << " failed!";
- qxtLog->debug() << "[gui] Exiting in 5 seconds...";
- QTimer::singleShot(5000, this, SLOT(close()));
- }
- }
- // watch the path to trigger file
- qxtLog->debug() << "[watcher] Watching " << fileToTriggerURL;
- _watcher = new QFileSystemWatcher(QStringList(fileToTriggerURL), this);
-QObject::connect(_watcher, SIGNAL(fileChanged(const QString&)), this, SLOT(prepareURLLoad()));
-
-}
-//-------------------------------------------------------------------------------------------
-/**
- * This method checks if the trigger was valid.
- *
- * This method checks if the trigger was valid. If yes,
- * we have received an IP Address an can load the main screen.
- * If not, something some error happened.
- *
- * @see fbgui::checkHost()
- * @see fbgui::loadURL()
- */
-void fbgui::prepareURLLoad() {
- qxtLog->debug() << "[watcher] " << fileToTriggerURL << " changed!";
- // disconnect _watcher, his job is done
- qxtLog->debug() << "[watcher] disconnected.";
- _watcher->disconnect(this);
- _watcher->deleteLater();
- // try to load URL
- loadURL();
-}
-//-------------------------------------------------------------------------------------------
-// Preparations for URL load
-//-------------------------------------------------------------------------------------------
-/**
- * This method checks the existance of the host.
- *
- * This method checks if the host exists / can be found.
- * The host is from the URL given through the configuration.
- */
-bool fbgui::checkHost() const {
- QHostInfo hostInfo = QHostInfo::fromName(baseURL.host());
- if (hostInfo.error() != QHostInfo::NoError) {
- qxtLog->debug() << "[gui] Lookup of " << baseURL.host() << "failed.";
- qxtLog->debug() << "[gui] Host can not be reached.";
- return false;
- } else {
- qxtLog->debug() << "[gui] Lookup of " << baseURL.host() << " succeeded.";
- return true;
- }
-}
-//-------------------------------------------------------------------------------------------
-/**
- * This method tries loads the URL.
- *
- * This method loads the main screen via an POST request. If also disconnects the watcher
- * of the file, (Watcher is set in the fbgui::watchForTrigger() method).
- * and generates the POST data body.
- *
- * @see fbgui::watchForTrigger()
- * @see fbgui::generatePOSTData()
- */
-void fbgui::loadURL() {
- if (checkHost()) {
- qxtLog->debug() << "[gui] Loading URL: " << baseURL.toString() << " ...";
-
- // Generate POST identification data needed by PBS.
- QByteArray postData = generatePOSTData();
- QNetworkRequest req(baseURL);
-
- // show cursor again since user is about to interact.
- //QWSServer::instance()->setCursorVisible(true);
- QObject::connect(_webView, SIGNAL(loadFinished(bool)), this, SLOT(loadURLDone(bool)));
- _webView->load(req, QNetworkAccessManager::PostOperation, postData);
- }
- // TODO: error page if no host.
-}
-void fbgui::loadURLDone(bool success) {
- // done contains the success of the loading: false / true
- if (!success) {
- qxtLog->debug() << "[gui] Loading failed. URL: "
- << _webView->url().toString();
- qxtLog->debug() << "[gui] You can quit with CTRL + X ...";
- // TODO handle failure properly...
- } else {
- qxtLog->debug() << "[gui] Loaded URL: " << _webView->url().toString();
- }
-}
-//-------------------------------------------------------------------------------------------
-/**
- * This method generates the POST data body.
- *
- * This method generates the POST data body. The body contains the
- * MAC address, an hardwarehash and a specific serial number.
- * The hardwarehash is a MD5 hash over the MAC address and the
- * mainboard serial number.
- * The specific serial number is set at the creation of the usb boot stick.
- * This file has to be present on the directory specified in
- * the configuration for this to work.
- *
- * @see SysInfo::getMACAddress()
- * @see SysInfo::getMainboardSerial()
- */
-QByteArray fbgui::generatePOSTData() {
- qxtLog->debug() << "[gui] Generating POST data...";
- // use MAC address as base data
- SysInfo si;
- QByteArray data(si.getInfo("mac").toUtf8());
- // append mainboard serial to the mac address for more unique hardwarehash
- QByteArray mbserial(si.getInfo("mbserial").toUtf8());
- if (!mbserial.isEmpty())
- data.append(mbserial);
- else {
- qxtLog->debug()
- << "[gui] Mainboard serial was empty. Not appending to base hash data.";
- }
- qxtLog->debug() << "[post] Hashing: " << data;
- // generate MD5 hash of data
- QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Md5);
- qxtLog->debug() << "[post] MD5 Hash: " << hash.toHex();
-
- // fetch serial number from usb
- QByteArray serial;
- QFile file(serialLocation);
- if (!file.open(QIODevice::ReadOnly)) {
- qxtLog->debug() << "[post] No such file: " << file.fileName();
- }
- // everything ok, read data
- serial = file.readAll();
- file.close();
- serial.chop(1); // chop EOF
- qxtLog->debug() << "[post] Serial number is: " << serial;
-
- // construct final byte array
- QByteArray postData("mac=");
- postData.append(si.getInfo("mac"));
- postData.append("&hardwarehash=" + hash.toHex());
- postData.append("&serialnumber=" + serial);
- qxtLog->debug() << "[post] POST data: " << postData;
- return postData;
-}
-
-//-------------------------------------------------------------------------------------------
-// Shutdown / Reboot of the client
-//-------------------------------------------------------------------------------------------
-// TODO One function for reboot and shutdown, with parameter for the action.
-// for example: doSystemCall(_REBOOT_);
-/**
- * This method performs the shutdown of the client.
- *
- * This method performs the shutdown of the client. It is triggered by the
- * JavascriptInterface::shutDownClient() signal which will be emited in the
- * JavascriptInterface::shutDown() method.
- * This method writes the character 'o' in /proc/sysrq-trigger
- * which will shutdown the computer immediatly.
- * (See linux magic keys)
- *
- * @see JavascriptInterface::shutDownClient()
- * @see JavascriptInterface::shutDown()
- */
-void fbgui::performShutDown() {
- QFile file("/proc/sysrq-trigger");
- if (file.open(QIODevice::WriteOnly)) {
- file.write("o");
- file.close();
- } else {
- qxtLog->debug() << "[gui] Could not open /proc/sysrq-trigger";
- }
-}
-//-------------------------------------------------------------------------------------------
-/**
- * This method performs the reboot of the client.
- *
- * This method performs the reboot of the client. It is triggered by the
- * JavascriptInterface::rebootClient() signal which will be emited in the
- * JavascriptInterface::reboot() method.
- * This method writes the character 'b' in /proc/sysrq-trigger
- * which will shutdown the computer immediatly.
- * (See linux magic keys)
- *
- * @see JavascriptInterface::rebootClient()
- * @see JavascriptInterface::reboot()
- */
-void fbgui::performReboot() {
- QFile file("/proc/sysrq-trigger");
- if (file.open(QIODevice::WriteOnly)) {
- file.write("b");
- file.close();
- } else {
- qxtLog->debug() << "[gui] Could not open /proc/sysrq-trigger";
- }
-}
-//-------------------------------------------------------------------------------------------
-// Preparing Kernel Switch per kexec (initiating Stage 3)
-//-------------------------------------------------------------------------------------------
-void fbgui::loadSystem() {
- //show loading system page.
- //_webView->disconnect(this);
- //QObject::connect(_webView, SIGNAL(loadFinished(bool)), this, SLOT(prepareKexec()));
- _webView->load(QUrl("qrc:/html/loadsystem.html"));
- QTimer::singleShot(1000, this, SLOT(prepareKexec()));
-}
-//-------------------------------------------------------------------------------------------
-/**
- * This method prepares kexec.
- *
- * The kernel command line file that should have been downloaded from the Preboot-Server
- * and the ip config file (created by udhcpc) are merged into the final completed KCL.
- *
- * A process is then started to load the kernel, initramfs and kcl into kexec.
- * The process tries to execute kexec -l with these parameters.
- *
- * If this succeeds, runKexec() is called
- *
- * @see fbgui::runKexec()
- *
- */
-void fbgui::prepareKexec() {
-
- qxtLog->debug() << "[gui] Preparing kexec ...";
- // try to read KCL file that was downloaded.
- QFile file(downloadPath + "/kcl");
- if (!file.open(QIODevice::ReadOnly)) {
- qxtLog->debug() << "[gui] No such file: " << file.fileName();
- }
- // everything ok, read data.
- QString kcl = file.readAll();
- file.close();
- qxtLog->debug() << "[gui] KCL from PBS: " << kcl;
-
- // try to read ipconfig file generated by udhcpc.
- file.setFileName("/tmp/ip_config_fbgui");
- if (!file.open(QIODevice::ReadOnly)) {
- qxtLog->debug() << "[gui] No such file: " << file.fileName();
- }
- // everything ok, read data.
- QString ipConfig = file.readAll();
- file.close();
- qxtLog->debug() << "[gui] IP config: " << ipConfig;
-
- // append ipConfig
- kcl.append(" ip=");
- kcl.append(ipConfig);
- qxtLog->debug() << "[gui] Complete KCL: " << kcl;
-
- // load the kernel + initramfs + append of kcl into kexec.
- QProcess *process = new QProcess(this);
- QString cmdline = "kexec -l " + downloadPath.toUtf8() + "/kernel --initrd="
- + downloadPath.toUtf8() + "/initramfs --append=\"" + kcl.toUtf8()
- + "\"";
- qxtLog->debug() << "[gui] kexec cmdline: " << cmdline;
- process->start(cmdline);
- bool ret = process->waitForFinished();
- if (!ret) {
- qxtLog->debug() << "[gui] Failed to execute: " << cmdline;
- qxtLog->debug() << "[gui] Exiting in 5 seconds...";
- QTimer::singleShot(5000, this, SLOT(close()));
- } else {
- qxtLog->debug() << "[gui] Kexec load was successfull.";
- if (debugMode < 0) {
- // if process successfully finished, try to run kexec -e
- runKexec();
- } else {
- qxtLog->debug()
- << "[gui] Skipping execution of kexec - open debug shell.";
- qxtLog->debug()
- << "[gui] To start the system execute \"kexec -e\" in your shell.";
- close();
- }
- }
-}
-//-------------------------------------------------------------------------------------------
-/**
- * This method tries to execute: kexec -e
- *
- * This method tries to execute: kexec -e
- *
- */
-void fbgui::runKexec() {
- QProcess *process = new QProcess(this);
- process->start("kexec -e");
- if (!process->waitForStarted()) {
- qxtLog->debug() << "[gui] Failed to execute: kexec -e";
- qxtLog->debug() << "[gui] Exiting in 5 seconds...";
- QTimer::singleShot(5000, this, SLOT(close()));
- //TODO: Handle failure properly...
- }
-}
-//-------------------------------------------------------------------------------------------
-// Debug console setup / control
-//-------------------------------------------------------------------------------------------
-/**
- * This method creates a debug console as a widget.
- *
- * It is basicly a QTextEdit widget as provided by QT's Framework.
- * An action to toggle this widget is implemented (CTRL + D).
- *
- * @see fbgui::toggleDebugConsole()
- */
-void fbgui::createDebugConsole() {
- // create the debug console widget
- _debugConsole = new QTextEdit(this);
- _debugConsole->setWindowFlags(Qt::FramelessWindowHint);
- // fanciness
- QPalette pal;
- pal.setColor(QPalette::Base, Qt::black);
- _debugConsole->setPalette(pal);
- _debugConsole->setTextColor(Qt::white);
- // enable custom logger engine
- qxtLog->addLoggerEngine("fb_logger", new LoggerEngine_fb(_debugConsole));
- //qxtLog->initLoggerEngine("fb_logger");
- qxtLog->setMinimumLevel("fb_logger", QxtLogger::DebugLevel);
- // CTRL + D toggles debug window
- _toggleDebugConsole = new QAction(tr("&toggleDebug"), this);
- _toggleDebugConsole->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D));
- addAction(_toggleDebugConsole);
- connect(_toggleDebugConsole, SIGNAL(triggered()), this, SLOT(
- toggleDebugConsole()));
-}
-//-------------------------------------------------------------------------------------------
-/**
- * This method toggles the debug console.
- *
- * Toggle the visibility of the debug console if the action _toggleDebugConsole is triggered.
- *
- * @see fbgui::createDebugConsole()
- */
-void fbgui::toggleDebugConsole() {
- (_debugConsole->isVisible()) ? _debugConsole->hide() : _debugConsole->show();
-}