From 3938051c32697918dc017df0468152fc0be0d19e Mon Sep 17 00:00:00 2001 From: Gerhard Hoffmann Date: Fri, 19 May 2023 15:32:52 +0200 Subject: [PATCH] Add Utils-class to provide most of the previous functionality. --- utils.cpp | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ utils.h | 46 +++++++++++++ 2 files changed, 247 insertions(+) create mode 100644 utils.cpp create mode 100644 utils.h diff --git a/utils.cpp b/utils.cpp new file mode 100644 index 0000000..c91f809 --- /dev/null +++ b/utils.cpp @@ -0,0 +1,201 @@ +#include "utils.h" + +#include +#include +#include +#include +#include +#include + +#include "interfaces.h" +#include "DCPlugin/include/hwapi.h" + +//#include +#include +#include +#include +#include +#include + +#define COLUMN_STATUS (0) +#define COLUMN_NAME (1) +#define COLUMN_DATE_TIME (2) +#define COLUMN_RESULT (3) + +Utils::Utils(QString update_ctrl_file, + QObject *parent, + char const *serialInterface, + char const *baudrate) + : QObject(parent) + , m_hw(new hwapi()) + , m_serialInterface(serialInterface) + , m_baudrate(baudrate) + , m_update_ctrl_file(update_ctrl_file) + , m_update_ctrl_file_copy(update_ctrl_file + ".copy") + , m_in(&m_update_ctrl_file) + , m_out(&m_update_ctrl_file_copy) + , m_init(true) { + + if (!m_update_ctrl_file.exists()) { + qCritical() << "Update-file" << m_update_ctrl_file.fileName() + << "does not exist"; + m_init = false; + } + if (!m_update_ctrl_file.open(QIODevice::ReadOnly | QIODevice::Text)) { + qCritical() << "can not open " << m_update_ctrl_file.fileName() + << "for reading"; + m_init = false; + } + if (!m_update_ctrl_file_copy.open(QIODevice::WriteOnly | QIODevice::Text)) { + qCritical() << "can not open " << m_update_ctrl_file_copy.fileName() + << "for writing"; + m_init = false; + } +} + +Utils::~Utils() { + +} + +void Utils::updateBinary(char const *fileToSendToDC) { + qDebug() << "file to send to DC ..." << fileToSendToDC; + qDebug() << "baudrate ............." << m_baudrate; + qDebug() << "serial interface ....." << m_serialInterface; + m_hw->dc_updateDC(fileToSendToDC, m_baudrate, m_serialInterface); + std::this_thread::sleep_for(std::chrono::milliseconds(3000)); + QCoreApplication::quit(); +} + +void Utils::updatePrinterConf(int nrOfTemplate, char const *fileToSendToDC) { + QVector printTemplates{ nrOfTemplate }; + QVector filesToSend{ fileToSendToDC }; + + m_hw->dc_updatePrinterTemplate(hwapi::FileTypeJson::PRINTER, + printTemplates, filesToSend, + QString(m_baudrate), + QString(m_serialInterface)); + std::this_thread::sleep_for(std::chrono::milliseconds(3000)); + QCoreApplication::quit(); +} + +QStringList Utils::getOpenLines() { + QStringList openLines; + + while (!m_in.atEnd()) { + QString line = m_in.readLine().trimmed(); + // QString.split() is defined >= 5.14 + if (!line.startsWith("OPEN")) { + m_out << line; + } else { + openLines << line; + } + } + return openLines; +} + +bool Utils::doUpdate() { + /* + The file referred to by 'update_data' has the following structure for + each line: + + # ====================================================================== + # STATUS | NAME | DATE | RESULT + # ====================================================================== + # where + # + # STATUS: OPEN or CLOSED + # NAME : If starting with 'opkg' it is an opkg-command to be executed. + # Otherwise its the name of a file which has to be updated. + # DATE : 0000-00-00T00:00:00 + # RESULT: SUCCESS or ERROR (possibly with description) + # + */ + if (!m_init) { + return false; + } + + QStringList openLines = getOpenLines(); + + bool res = false; + QList::const_iterator it; + for (it = openLines.cbegin(); it != openLines.cend(); ++it) { + int start = 0, end; + int column = 0; + QString status, name, datetime, result; + QString line = *it; + while ((end = line.indexOf(QChar(','), start)) != -1) { + QString next = line.mid(start, end).trimmed(); + switch (column) { + case COLUMN_STATUS: + status = next; + break; + case COLUMN_NAME: + name = next; + break; + case COLUMN_DATE_TIME: + datetime = next; + break; + case COLUMN_RESULT: + result = next; + break; + } + ++column; + start = end + 1; + } + + if (!status.contains("OPEN")) { + qCritical() << "Parsing error for" << m_update_ctrl_file.fileName(); + return false; + } + if (name.contains("dc2c") && name.endsWith(".bin")) { + updateBinary(name.toStdString().c_str()); + res = true; + } else + if (name.contains("DC2C_print") && name.endsWith(".json")) { + int i = name.indexOf("DC2C_print"); + int templateIdx = name.mid(i).midRef(10, 2).toInt(); + updatePrinterConf(templateIdx, name.toStdString().c_str()); + res = true; + } else + if (name.contains("opkg")) { + int i = name.indexOf("opkg "); + QString rest = name.mid(i).trimmed(); + QScopedPointer p(new QProcess(this)); + p->setProcessChannelMode(QProcess::MergedChannels); + p->start("opkg", QStringList() << rest); + if (p->waitForStarted(1000)) { + if (p->state() == QProcess::ProcessState::Running) { + if (p->waitForFinished(10000)) { + QByteArray output = p->readAllStandardOutput(); + qCritical() << output; + res = true; + } + } + } + } else { + // TODO + } + QString resultLine = "CLOSED"; + resultLine += ", " + name; + resultLine += ", " + QDateTime::currentDateTime().toString(Qt::ISODate); + resultLine += ", " + (res == true) ? "SUCCESS" : "ERROR"; + m_out << resultLine; + } // for (it = openLines.cbegin(); it != openLines.end(); ++it) { + + return finishUpdate(openLines.size() > 0); +} + +bool Utils::finishUpdate(bool replaceCtrlFile) { + if (replaceCtrlFile) { + if (!m_update_ctrl_file_copy.exists()) { + return false; + } + if (!m_update_ctrl_file.remove()) { + return false; + } + if (!m_update_ctrl_file_copy.rename(m_update_ctrl_file.fileName())) { + return false; + } + } + return true; +} diff --git a/utils.h b/utils.h new file mode 100644 index 0000000..4e42753 --- /dev/null +++ b/utils.h @@ -0,0 +1,46 @@ +#ifndef UTILS_H_INCLUDED +#define UTILS_H_INCLUDED + +#include +#include +#include + +#include + +#include "interfaces.h" +#include "DCPlugin/include/hwapi.h" + +#ifdef PTU5 +#define SERIAL_PORT "ttymxc2" +#else +#define SERIAL_PORT "ttyUSB0" +#endif + +class Utils : public QObject { + Q_OBJECT + + std::unique_ptr m_hw; + char const *m_serialInterface; + char const *m_baudrate; + QFile m_update_ctrl_file; + QFile m_update_ctrl_file_copy; + QTextStream m_in; + QTextStream m_out; + + bool m_init; + + void updateBinary(char const *fileToSendToDC); + void updatePrinterConf(int nrOfTemplate, char const *fileToSendToDC); + bool finishUpdate(bool finish); + QStringList getOpenLines(); + static constexpr QChar SEPARATOR = QChar(','); + +public: + explicit Utils(QString update_ctrl_file, + QObject *parent = nullptr, + char const *serialInterface = SERIAL_PORT, + char const *baudrate = "115200"); + virtual ~Utils() override; + bool doUpdate(); +}; +#endif // UTILS_H_INCLUDED