Compare commits

..

No commits in common. "35d40e3b3c84472157f9542feb5a800af89d58da" and "2b5fca73a269422bcf0f9470f9bb5a010e02d978" have entirely different histories.

6 changed files with 10 additions and 290 deletions

View File

@ -1,73 +0,0 @@
# QT -= gui
QT += core
QT += widgets serialport
QT += network
TARGET = up_dev_ctrl
CONFIG += c++11
# CONFIG -= app_bundle
# DEFINES+=LinuxDesktop
QMAKE_CXXFLAGS += -Wno-deprecated-copy
# custom target for 'git subtree'
# subtree.target = subtree
# subtree.commands = git subtree add --prefix DCPlugin https://git.mimbach49.de/GerhardHoffmann/DCPlugin.git master --squash
# subtree.depends =
# QMAKE_EXTRA_UNIX_TARGETS += subtree
! exists(DCPlugin) {
$$system("git subtree add --prefix DCPlugin https://git.mimbach49.de/GerhardHoffmann/DCPlugin.git master --squash")
} else {
# $$system("git subtree pull --prefix DCPlugin https://git.mimbach49.de/GerhardHoffmann/DCPlugin.git master --squash")
}
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
contains( CONFIG, PTU5 ) {
greaterThan(QT_MAJOR_VERSION, 4): QT += serialport
CONFIG += link_pkgconfig
lessThan(QT_MAJOR_VERSION, 5): PKGCONFIG += qextserialport
QMAKE_CXXFLAGS += -std=c++11 # for GCC >= 4.7
QMAKE_CXXFLAGS += -Wno-deprecated-copy
ARCH = PTU5
DEFINES+=PTU5
}
contains( CONFIG, DesktopLinux ) {
greaterThan(QT_MAJOR_VERSION, 4): QT += serialport
lessThan(QT_MAJOR_VERSION, 5): CONFIG += extserialport
# QMAKE_CC = ccache $$QMAKE_CC
# QMAKE_CXX = ccache $$QMAKE_CXX
QMAKE_CXXFLAGS += -std=c++11
QMAKE_CXXFLAGS += -Wno-deprecated-copy
linux-clang { QMAKE_CXXFLAGS += -Qunused-arguments }
ARCH = DesktopLinux
DEFINES+=DesktopLinux
}
SOURCES += \
main.cpp \
update.cpp \
message_handler.cpp
HEADERS += \
update.h \
message_handler.h \
DCPlugin/include/interfaces.h
OTHER_FILES += \
/opt/app/tools/atbupdate/update_log.csv
# https://blog.developer.atlassian.com/the-power-of-git-subtree/?_ga=2-71978451-1385799339-1568044055-1068396449-1567112770
# git subtree add --prefix DCPlugin https://git.mimbach49.de/GerhardHoffmann/DCPlugin.git master --squash
# git subtree pull --prefix DCPlugin https://git.mimbach49.de/GerhardHoffmann/DCPlugin.git master --squash
include(./DCPlugin/DCPlugin.pri)
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

Binary file not shown.

View File

@ -1,110 +0,0 @@
\documentclass[12pt]{article}
\usepackage{euler}
\usepackage[english]{babel}
\usepackage{lipsum}
\usepackage[colorlinks=true, urlcolor=blue, linkcolor=red]{hyperref}
\newcounter{Chapcounter}
\newcommand\showmycounter{\addtocounter{Chapcounter}{1}\themycounter}
\newcommand{\chapter}[1]
{{\centering
\addtocounter{Chapcounter}{1} \Large \underline{\textbf{ \color{blue} Chapter \theChapcounter: ~#1}} }
\addcontentsline{toc}{section}{ \color{blue} Chapter:~\theChapcounter~~ #1}
}
\hypersetup{colorlinks=true}
\hypersetup{linkcolor=black}
\title{Update PTU}
\author{Gerhard Hoffmann}
\date{\today}
\begin{document}
\maketitle
\chapter{Introduction}
\section{Motivation}
The two main components of a PSA are
\begin{itemize}
\item PTU software.
\item Device controller (DC) firmware.
\end{itemize}
While the DC firmware is basically the same for each PSA (even for different
customers), the PTU software is highly dependent on customer requirements.\par
Hence, each customer is assigned an own git-repository, which will be loaded
("cloned") on the PSA when configuring the machine for the first time.\par
Two special tools, the {\bf UpdateController} (a \href{https://doc.qt.io/qt-5/}{Qt}
binary [{\bf \nameref{UpdateTool}}]) and the {\bf UpdateScript}
(a \href{https://www.gnu.org/software/bash/manual/bash.html}{bash}
script [{\bf \nameref{UpdateScript}}]), work together to finish a PSA installation.\par
\section{PSA: Initial configuration}
For the initial configuration, a PSA loads a customer-specific git-repository,
which structure is detailed below [{\bf \nameref{repostructure}}].\par
The "git clone" for the repository is done by the UpdateScript [{\bf \nameref{UpdateScript}}].
It updates the file
\begin{center}
\fbox{
/opt/app/tools/atbupdate/update\_log.csv
}
\end{center}
which will be interpreted by the UpdateController [{\bf \nameref{UpdateTool}}].
The structure of {\bf update\_log.csv} is detailed below [{\bf \nameref{updatelogcsv}}].\par
Each line of {\bf update\_log.csv} represents a command for the UpdateController,
which will either download certain files to the DC or execute some
\href{https://openwrt.org/docs/guide-user/additional-software/opkg}{opkg}
commands [{\bf \nameref{opkg}}].
\section{PSA: Update}
\newpage
\chapter{Update-Tool "up\_dev\_ctrl"}
\section{up\_dev\_ctrl}
\label{UpdateTool}
The update-tool is a Qt binary ("up\_dev\_ctrl") and called by the
system-controller application. It is installed under
\begin{center}
\fbox{
/opt/app/tools/atbupdate/up\_dev\_ctrl
}
\end{center}
and has two responsibilities:
\begin{itemize}
\item Call update-script "update\_psa".
\item Update the device controller firmware.
\end{itemize}
\subsection{Calling the update-script "update\_psa"}
The update-script "update\_psa" is about executing all git-commands
necessary to clone and pull a customer repository.
\newpage
\chapter{Update-Script "update\_psa"}
\section{update\_psa}
\label{UpdateScript}
Inside of such a
repository, there are at least the following directories:
\begin{itemize}
\item {\bf etc}
\item {\bf etc/dc}\newline
Contains the device controller firmware as binary file.
\item {\bf etc/psa\_config}\newline
Contains the printer template files (JSON).
\item {\bf etc/psa\_tariff}\newline
Contains the tariff files (JSON).
\item {\bf etc/psa\_update}\newline
Contains a single file for opkg-commands.
\end{itemize}
\newpage
\chapter{Annex}
\section{Structure of a customer git-repository}
\label{repostructure}
\section{Structure of "update\_log.csv"}
\label{updatelogcsv}
\section{The package manager "opkg"}
\label{opkg}
\end{document}

View File

@ -5,6 +5,7 @@
#include <QFileInfo>
#include "message_handler.h"
#include "interfaces.h"
#include "DCPlugin/include/hwapi.h"
@ -14,7 +15,6 @@
#include <QSharedMemory>
#include <QRunnable>
#include <QThreadPool>
#include <QDir>
#include "update.h"
@ -26,16 +26,12 @@
class Work : public QRunnable {
QString m_update_ctrl_file;
QString m_workingDir;
public:
explicit Work(QString update_ctrl_file, QString workingDir)
: m_update_ctrl_file(update_ctrl_file)
, m_workingDir(workingDir) {
}
explicit Work(QString update_ctrl_file)
: m_update_ctrl_file(update_ctrl_file) {}
void run() {
Update m_update(m_update_ctrl_file, m_workingDir);
// if (m_update.doUpdate()) {
// }
Update m_update(m_update_ctrl_file);
m_update.doUpdate();
}
};
@ -49,15 +45,13 @@ int main(int argc, char *argv[]) {
//setDebugLevel(QtMsgType::QtDebugMsg);
}
QByteArray const value = qgetenv("XDG_RUNTIME_DIR");
if (value.size() == 0) {
qputenv("XDG_RUNTIME_DIR", "/run/user/0");
QString update_ctrl_file = "/opt/app/tools/atbupdate/update_log.csv";
if (argc == 2) {
update_ctrl_file = argv[1];
}
qInfo() << "Using" << update_ctrl_file << "as update logfile";
QString const update_ctrl_file = "/opt/app/tools/atbupdate/update_log.csv";
QString const workingDir = (argc == 2) ? argv[1] : ".";
Work work(update_ctrl_file, workingDir);
Work work(update_ctrl_file);
work.setAutoDelete(false);
QThreadPool *threadPool = QThreadPool::globalInstance();
threadPool->start(&work);

View File

@ -6,7 +6,6 @@
#include <QTemporaryFile>
#include <QDebug>
#include <QTextStream>
#include <QRegularExpression>
#include "interfaces.h"
#include "DCPlugin/include/hwapi.h"
@ -14,7 +13,6 @@
#include <QSharedMemory>
#include <QScopedPointer>
#include <QProcess>
#include <QDir>
#define COLUMN_REQUEST (0)
#define COLUMN_NAME (1)
@ -28,7 +26,6 @@ void ScopedPointerCustomDeleter::cleanup(Update *update) {
}
Update::Update(QString update_ctrl_file,
QString workingDir,
QObject *parent,
hwinf *hw,
char const *serialInterface,
@ -39,12 +36,9 @@ Update::Update(QString update_ctrl_file,
, m_baudrate(baudrate)
, m_update_ctrl_file(update_ctrl_file)
, m_update_ctrl_file_copy(update_ctrl_file + ".copy")
, m_workingDir(workingDir)
, m_init(true)
, m_delete(hw == nullptr) {
execUpdateScript();
if (!m_update_ctrl_file.exists()) {
qCritical() << "Update-file" << m_update_ctrl_file.fileName()
<< "does not exist";
@ -70,34 +64,6 @@ Update::Update(QString update_ctrl_file,
Update::~Update() {
}
bool Update::execUpdateScript() {
// path of update-script 'update_psa'
QString update_psa("/opt/app/tools/atbupdate/update_psa --wdir ");
update_psa += m_workingDir;
//QStringList const params(QStringList() << "-c" << update_psa);
QScopedPointer<QProcess> p(new QProcess(this));
p->setProcessChannelMode(QProcess::MergedChannels);
p->start(update_psa);
if (p->waitForStarted(1000)) {
if (p->state() == QProcess::ProcessState::Running) {
if (p->waitForFinished(60000)) {
QString output = p->readAllStandardOutput().toStdString().c_str();
QStringList lst = output.split('\n');
for (int i = 0; i < lst.size(); ++i) {
qDebug() << lst[i];
}
qInfo() << "EXECUTED" << update_psa;
return ((p->exitStatus() == QProcess::NormalExit)
&& (p->exitCode() == 0));
}
}
}
return false;
}
bool Update::updateBinary(char const *fileToSendToDC) {
return m_hw->dc_updateDC(fileToSendToDC, m_baudrate, m_serialInterface);
}

View File

@ -1,57 +0,0 @@
#ifndef UPDATE_H_INCLUDED
#define UPDATE_H_INCLUDED
#include <QObject>
#include <QString>
#include <QFile>
#include "interfaces.h"
#include "DCPlugin/include/hwapi.h"
#ifdef PTU5
#define SERIAL_PORT "ttymxc2"
#else
#define SERIAL_PORT "ttyUSB0"
#endif
class Update;
struct ScopedPointerCustomDeleter {
static void cleanup(Update *pointer);
};
// TODO: check hardware compatibility
// TODO: opkg commandos
class Update : public QObject {
Q_OBJECT
QScopedPointer<hwinf> m_hw;
char const *m_serialInterface;
char const *m_baudrate;
QFile m_update_ctrl_file;
QFile m_update_ctrl_file_copy;
QString m_workingDir;
bool m_init;
bool updateBinary(char const *fileToSendToDC);
bool updatePrinterConf(int nrOfTemplate, char const *fileToSendToDC);
bool finishUpdate(bool finish);
QStringList getOpenLines();
QStringList split(QString line);
static constexpr QChar SEPARATOR = QChar(',');
bool execUpdateScript();
public:
explicit Update(QString update_ctrl_file,
QString workingDir = ".",
QObject *parent = nullptr,
hwinf *hw = nullptr,
char const *serialInterface = SERIAL_PORT,
char const *baudrate = "115200");
virtual ~Update() override;
bool doUpdate();
bool const m_delete;
};
#endif // UPDATE_H_INCLUDED