From 05b68f21c21ade0de90ea94782a5997b84deae3e Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Fri, 26 Apr 2024 13:05:19 +0200 Subject: [PATCH] Add System.h/System.cpp -> to be adapted later --- common/include/System.h | 55 ++++ common/src/System.cpp | 647 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 702 insertions(+) create mode 100644 common/include/System.h create mode 100644 common/src/System.cpp diff --git a/common/include/System.h b/common/include/System.h new file mode 100644 index 0000000..918aff6 --- /dev/null +++ b/common/include/System.h @@ -0,0 +1,55 @@ +#ifndef SYSTEM_H +#define SYSTEM_H + + +#include + +class System : public QObject +{ + Q_OBJECT + +private: + explicit System(QObject *parent = 0); + + static QString errorMsg; + + +public: + + + static bool checkForSDCard(); + static bool umountSDCard(); + + static bool checkForUSBStick(); + static QString getUSBMountPath(); + static QString getUSBDeviceName(); + static bool umountUSBStick(); + + static bool test_mount(const QString& dev, const QString &mountpoint); + static bool test_dir(const QString& dir); + + static quint32 getFreeDiskSpace(const QString& dev); + static quint32 getFreeDiskSpaceSDCard(); + static bool isSDCardWritable(); + static quint32 getFreeDiskSpaceUSBStick(); + static bool isUSBStickWritable(); + + static quint8 createLogFileBackup(const QString & targzfile, const QString &filelistfile = ""); + static QString getSDCardMountPath(); + static QString getSDCardDeviceName(); + + static QString getUniqueDeviceId(); + + static QString getErrorMessage(); + + static QString readStringFromFile(const QString & filename); + static int readIntFromFile(const QString & filename); + + static QString getPTU4SerialNumber(); + static QString getPTU4MACAddress(); + + + +}; + +#endif // SYSTEM_H diff --git a/common/src/System.cpp b/common/src/System.cpp new file mode 100644 index 0000000..b88477e --- /dev/null +++ b/common/src/System.cpp @@ -0,0 +1,647 @@ +#include "System.h" +#include +#include +#include +#include +#include +#include +#include +#include + +//#include "version.h" + + +QString System::errorMsg = ""; + +System::System(QObject *parent) : + QObject(parent) +{ + +} + + + +/******************************************************************************** + * static function to return error message. + * + */ +QString System::getErrorMessage() +{ + return errorMsg; +} + + + +/******************************************************************************** + * static function to check if a writable SD-card is in the cardslot. + * + * This function only checks a certain path or a mount entry. It does not mount + * a SD-card, this must be provided by the OS (automounter). + * + * returns 1 if a SD-card is available, 0 otherwise. + */ +bool System::checkForSDCard() +{ +#if defined (ARCH_DesktopLinux) + // DEBUG / TEST: + return true; +#endif + + + + if (!test_mount(getSDCardDeviceName(), getSDCardMountPath())) { + qDebug() << "check for SD-card failed: \n" + << " device name is: " << getSDCardDeviceName() + << " mount path is: " << getSDCardMountPath(); + return false; + } + + return true; +} + + +/******************************************************************************** + * static function for umount sd-card. + * + */ +bool System::umountSDCard() +{ +#if defined (ARCH_DesktopLinux) + // DEBUG / TEST: + return true; +#endif + + QProcess process; + process.setProcessChannelMode(QProcess::MergedChannels); + + QString commandString = "umount " + getSDCardMountPath(); + + process.start(commandString); + if (!process.waitForStarted()) { + errorMsg = "System::umountSDCard(): ERROR: waitForStarted()"; + return false; + } + if (!process.waitForFinished(600000)) { + errorMsg = "System::umountSDCard(): ERROR: " + process.errorString(); + qDebug() << errorMsg; + return false; + } + else { + QByteArray bytes = process.readAll(); + QStringList lines = QString(bytes).split("\n"); + foreach (QString line, lines) { + qDebug() << "System::umountSDCard() line: " << line; + } + } + + + return true; +} + + + +/******************************************************************************** + * static function for umount usb-stick. + * + */ +bool System::umountUSBStick() +{ +#if defined (ARCH_DesktopLinux) + // DEBUG / TEST: + return true; +#endif + + QProcess process; + process.setProcessChannelMode(QProcess::MergedChannels); + + QString commandString = "umount " + getUSBMountPath(); + + process.start(commandString); + if (!process.waitForStarted()) { + errorMsg = "System::umountUSBStick(): ERROR: waitForStarted()"; + return false; + } + if (!process.waitForFinished(600000)) { + errorMsg = "System::umountUSBStick(): ERROR: " + process.errorString(); + qDebug() << errorMsg; + return false; + } + else { + QByteArray bytes = process.readAll(); + QStringList lines = QString(bytes).split("\n"); + foreach (QString line, lines) { + qDebug() << "System::umountUSBStick() line: " << line; + } + } + + + return true; +} + + + +/***************************************************************************** + * test, if a certain device is already mounted + * + * e.g. a mounted SD-card on PTU4: + * - device is '/dev/mmcblk0p1' + * - mount path is '/media/mmcblk0p1' + * + * e.g. a mounted USB-Stick on PTU4: + * - device is '/dev/sda' + * - mount path is '/media/sda' + */ +bool System::test_mount(const QString& dev, const QString& mountpoint) +{ + bool mounted = false; + QProcess process; + process.setProcessChannelMode(QProcess::MergedChannels); + + qDebug() << "System::test_mount() dev = " << dev; + qDebug() << "System::test_mount() mountpoint = " << mountpoint; + + //normalize mountpoint: (mountpoint is without trailing '/') + QString tmp_mountpoint = QString(mountpoint).remove(QRegExp("/*$")); + + QString commandString = "mount"; + + process.start(commandString); + if (!process.waitForStarted()) { + errorMsg = "System::test_mount(): ERROR: waitForStarted()"; + return false; + } + if (!process.waitForFinished(600000)) { + errorMsg = "System::test_mount(): ERROR: " + process.errorString(); + qDebug() << errorMsg; + return false; + } + else { + QByteArray bytes = process.readAll(); + QStringList lines = QString(bytes).split("\n"); + foreach (QString line, lines) { + //qDebug() << "System::test_mount() line: " << line; + + //if (line.contains(dev)) qDebug() << "System::test_mount() line contains dev"; + //if (line.contains(tmp_mountpoint)) qDebug() << "System::test_mount() line contains mountpoint"; + + if (line.contains(dev) && line.contains(tmp_mountpoint)) { + qDebug() << "System::test_mount(): " << dev << " is mounted on " << tmp_mountpoint; + mounted = true; + } + } + } + + + return mounted; +} + + +/***************************************************************************** + * test, if a certain directory is existing and readable + */ +bool System::test_dir(const QString& dir) +{ + QFileInfo fileInfo(dir); + if (! fileInfo.isDir() ) { return false; } + + return true; +} + + + +bool System::checkForUSBStick() +{ +#if defined (ARCH_DesktopLinux) + // DEBUG / TEST: + if (QFileInfo(getUSBMountPath()).isDir()) + return true; + else + return false; +#endif + + if (getUSBMountPath().isEmpty()) { + return false; + } + + return true; +} + + + +/** + * @brief SupportSystem::getUSBMountPath + * @return path where a USB storage device is mounted. + * + * Note, do not return an empty string ("") here because a calling method (which could not be + * identified till now) is relying on this! + */ +QString System::getUSBMountPath() +{ + +#if defined (ARCH_DesktopLinux) + // DEBUG / TEST: + return QDir::homePath().append("/APconfigTest/USB"); +#endif + + QProcess process; + process.setProcessChannelMode(QProcess::MergedChannels); + + QStringList mountLine; + + qDebug() << "System::getUSBMountPath()"; + + QRegExp devRegExp = QRegExp("dev/sd*", Qt::CaseSensitive, QRegExp::WildcardUnix); + QRegExp mountRegExp = QRegExp("media/sd*", Qt::CaseSensitive, QRegExp::WildcardUnix); + + QString commandString = "mount"; + + process.start(commandString); + if (!process.waitForStarted()) { + errorMsg = "System::getUSBMountPath(): ERROR: waitForStarted()"; + return ""; + } + if (!process.waitForFinished(600000)) { + errorMsg = "System::getUSBMountPath(): ERROR: " + process.errorString(); + qDebug() << errorMsg; + return ""; + } + else { + QByteArray bytes = process.readAll(); + QStringList lines = QString(bytes).split("\n"); + foreach (QString line, lines) { + qDebug() << "System::getUSBMountPath() line: " << line; + + if (line.contains(devRegExp) && line.contains(mountRegExp)) { + + qDebug() << " -> this line is a usb storage device mount" << line; + + mountLine = line.split(' '); + if (mountLine.size() > 3) { + qDebug() << "System::getUSBMountPath(): " << mountLine.at(0) << " is mounted on " << mountLine.at(2); + return mountLine.at(2); + } + } + } + } + + qDebug() << "System::getUSBMountPath() no mounted usb device found!"; + + return ""; +} + + +/******************************************************************************** + * static function to check if a mounted sd-card is writable. + * + * Note: the caller must ensure (e.g. by calling checkForSDCard()) that a + * sd-card is mounted. + * + */ +bool System::isSDCardWritable() +{ + QFileInfo fi(getSDCardMountPath()); + + if(fi.isDir() && fi.isWritable()) { + return true; + } + else + { + return false; + } +} + +/******************************************************************************** + * static function to check if a mounted usb-stick is writable. + * + * Note: the caller must ensure (e.g. by calling checkForUSBStick()) that a + * usb-stick is mounted. + * + */ +bool System::isUSBStickWritable() +{ + QFileInfo fi(getUSBMountPath()); + + if(fi.isDir() && fi.isWritable()) { + return true; + } + else + { + return false; + } +} + + +/******************************************************************************** + * wrapper function for getting free space on a sd-card on ptu + * + */ +quint32 System::getFreeDiskSpaceSDCard() +{ +#if defined (ARCH_DesktopLinux) + return getFreeDiskSpace("/home/siegert/server1home"); +#endif + return getFreeDiskSpace(getSDCardMountPath()); +} + + +/******************************************************************************** + * wrapper function for getting free space on a usb storage device on ptu + * + */ +quint32 System::getFreeDiskSpaceUSBStick() +{ +#if defined (ARCH_DesktopLinux) + return getFreeDiskSpace("/home/siegert/server1home"); +#endif + return getFreeDiskSpace(getUSBMountPath()); +} + + +/******************************************************************************** + * static function to read free disk space + * + * example output of 'df' command on ptu: + * # df + * Filesystem 1K-blocks Used Available Use% Mounted on + * ubi0:rootfs 111704 78940 32764 71% / + * devtmpfs 62072 0 62072 0% /dev + * tmpfs 62332 0 62332 0% /dev/shm + * tmpfs 62332 416 61916 1% /tmp + * tmpfs 62332 24 62308 1% /run + * ubi0:data 222260 5892 216368 3% /opt + * tmpfs 62332 0 62332 0% /media + * /dev/mmcblk0p1 3878912 87360 3791552 3% /media/mmcblk0p1 + * + * in this case, if we want to get the free space on the sd-card the methode should + * be called: + * getFreeDiskSpace("/dev/mmcblk0p1") + * the result should be: + * 3791552 + * + */ +quint32 System::getFreeDiskSpace(const QString& dev) +{ + quint32 availableSpace = 0; + QProcess process; + process.setProcessChannelMode(QProcess::MergedChannels); + + //qDebug() << "System::getFreeDiskSpace() dev = " << dev; + + QString commandString = "df"; + + process.start(commandString); + if (!process.waitForStarted()) { + errorMsg = "System::getFreeDiskSpace(): ERROR: waitForStarted()"; + return availableSpace; + } + if (!process.waitForFinished(600000)) { + errorMsg = "System::getFreeDiskSpace(): ERROR: " + process.errorString(); + qDebug() << errorMsg; + return availableSpace; + } + else { + QByteArray bytes = process.readAll(); + QStringList lines = QString(bytes).split("\n"); + foreach (QString line, lines) { + //qDebug() << "System::getFreeDiskSpace() line: " << line; + + + + if (line.contains(dev)) { + //qDebug() << "System::getFreeDiskSpace() line contains dev"; + + QStringList processResultLine = line.split(' ', QString::SkipEmptyParts); + if (processResultLine.size() >= 4) { + bool ok; + availableSpace = processResultLine.at(3).toLong(&ok); + if (!ok) { + return 0; + } + qDebug() << "System::getFreeDiskSpace() availableSpace = " << availableSpace; + } + else { + return availableSpace; + } + + + } + } + } + + + return availableSpace; + + +} + + + + + + +/******************************************************************************** + * static function to create a backup of logfiles + * + * 'targzfile' is an absolute filename for ar tar.gz file wich will be created + * 'filelistfile' is an absolute filename of a file containing all names of files + * which should be backed up. + * + * returns: + * 1 on success + * 0 on failure + * + */ +quint8 System::createLogFileBackup(const QString & targzfile, const QString &filelistfile) +{ + QProcess process; + process.setProcessChannelMode(QProcess::MergedChannels); + + qDebug() << "System::createLogFileBackup() targzfile = " << targzfile; + qDebug() << "System::createLogFileBackup() filelistfile = " << filelistfile; + + QString commandString = "tar hczvf " + targzfile + " -T " + filelistfile; + + qDebug() << "System::createLogFileBackup() tar command:" << commandString; + + process.start(commandString); + if (!process.waitForStarted()) { + errorMsg = "System::createLogFileBackup(): ERROR: waitForStarted()"; + return 1; + } + if (!process.waitForFinished(600000)) { + errorMsg = "System::createLogFileBackup(): ERROR: " + process.errorString(); + qDebug() << errorMsg; + return 1; + } + else { + // DEBUG + //QByteArray bytes = process.readAll(); + //QStringList lines = QString(bytes).split("\n"); + //foreach (QString line, lines) { + // qDebug() << "System::createLogFileBackup() line: " << line; + //} + } + + QString resultMessage; + QProcess::ExitStatus exitStatus = process.exitStatus(); + int exitCode = process.exitCode(); + + if (exitStatus == QProcess::CrashExit) { + resultMessage = "local backup program crashed"; + qCritical() << resultMessage; + return 1; + } + else + + /** + * note for exit codes of process tar: + * see: http://www.gnu.org/software/tar/manual/html_section/tar_19.html#Synopsis + * + * tar returns exitCode 2 if some files in logFileList could not be read (e.g. if they are not existing) + * however, tar-archive is created although! + * This means success for our needs! + */ + + if ( (exitCode != 0) && (exitCode != 2) && (exitStatus == QProcess::NormalExit) ) { + resultMessage = "Local Backup file \"" + targzfile + "\" with exit code = " + QString::number(exitCode); + qCritical() << resultMessage; + return 1; + } + else { + resultMessage = "Local Backup file \"" + targzfile + "\" was created successfully."; + qCritical() << resultMessage; + return 0; + } + + return 0; + +} + + + +/***************************************************************************** + * get SD-card mount path. + */ +QString System::getSDCardMountPath() +{ +#if defined (ARCH_PTU4) + return "/media/mmcblk0p1"; +#elif defined (ARCH_PTU5) + return "/media/mmcblk0p1"; +#elif defined (ARCH_DesktopLinux) + // DEBUG / TEST: + return "/home/siegert/APconfigTest"; +#endif + return ""; +} + + +/***************************************************************************** + * get SD-card device name. + */ +QString System::getSDCardDeviceName() +{ +#if defined (ARCH_PTU4) + return "/dev/mmcblk0p1"; +#elif defined (ARCH_PTU5) + return "/dev/mmcblk0p1"; +#elif defined (ARCH_DesktopLinux) + return "/dev/sdf1"; +#endif + return ""; +} + + + + + + +/******************************************************************************** + * static function to build and return a unique device id. + * This id consists currently only of the mac-address of network device eth0. + */ +QString System::getUniqueDeviceId() +{ + QString filename = "/sys/class/net/eth0/address"; + QString result; + + QFile file(filename); + if(!file.open(QIODevice::ReadOnly)) { + qCritical() << "System::getUniqueDeviceId() could not open file: " << filename; + result = "0"; + } + else { + QTextStream in(&file); + result = in.readLine(20); + } + + file.close(); + + result.remove(':'); + + return result; + +} + + + +QString System::readStringFromFile(const QString & filename) +{ +#if defined (ARCH_PTU4) + QFileInfo fileinfo(filename); +#else + QFileInfo fileinfo(QDir::homePath() + filename); +#endif + if (! fileinfo.isReadable() ) { + qDebug() << "System::readStringFromFile(): \"" << filename << "\" is not readable"; + return ""; + } + +#if defined (ARCH_PTU4) + QFile file(filename); +#else + QFile file(QDir::homePath() + filename); +#endif + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + qDebug() << "System::readStringFromFile() cannot open file: " << filename; + return ""; + } + + QTextStream in(&file); + + QString stringValue = in.readLine(100); + qDebug() << "System::readStringFromFile() stringValue = " << stringValue; + + file.close(); + + return stringValue; +} + + +int System::readIntFromFile(const QString & filename) +{ + bool ok; + int result = (int)readStringFromFile(filename).toInt(&ok); + + if (!ok) { + result = 0; + } + + return result; +} + + +/**************************************************************************** + * read ptu internal data + * + */ +QString System::getPTU4SerialNumber() +{ + return readStringFromFile("/sys/bus/i2c/devices/0-0050/SNO"); +} + +QString System::getPTU4MACAddress() +{ + return readStringFromFile("/sys/bus/i2c/devices/0-0050/MAC"); +} +