File indexing completed on 2024-05-05 05:34:26

0001 /*
0002     KSysGuard, the KDE System Guard
0003 
0004     SPDX-FileCopyrightText: 1999, 2000 Chris Schlaeger <cs@kde.org>
0005 
0006     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0007 
0008 */
0009 
0010 #ifndef KSG_SENSORAGENT_H
0011 #define KSG_SENSORAGENT_H
0012 
0013 #include <QObject>
0014 #include <QPointer>
0015 #include <QQueue>
0016 #include <QSet>
0017 
0018 #include "ksgrd_export.h"
0019 
0020 class QString;
0021 
0022 namespace KSGRD
0023 {
0024 class SensorClient;
0025 class SensorManager;
0026 class SensorRequest;
0027 
0028 /**
0029   The SensorAgent depending on the type of requested connection
0030   starts a ksysguardd process or connects through a tcp connection to
0031   a running ksysguardd and handles the asynchronous communication. It
0032   keeps a list of pending requests that have not been answered yet by
0033   ksysguardd. The current implementation only allows one pending
0034   requests. Incoming requests are queued in an input FIFO.
0035 */
0036 class KSGRD_EXPORT SensorAgent : public QObject
0037 {
0038     Q_OBJECT
0039 
0040 public:
0041     explicit SensorAgent(SensorManager *sm);
0042     ~SensorAgent() override;
0043 
0044     virtual bool start(const QString &host, const QString &shell, const QString &command = QLatin1String(""), int port = -1) = 0;
0045 
0046     /**
0047       This function should only be used by the SensorManager and
0048       never by the SensorClients directly since the pointer returned by
0049       engaged is not guaranteed to be valid. Only the SensorManager knows
0050       whether a SensorAgent pointer is still valid or not.
0051 
0052       This function sends out a command to the sensor and notifies the
0053       agent to return the answer to 'client'. The 'id' can be used by the
0054       client to identify the answer. It is only passed through and never
0055       used by the SensorAgent. So it can be any value the client suits to
0056       use.
0057      */
0058     void sendRequest(const QString &req, SensorClient *client, int id = 0);
0059 
0060     virtual void hostInfo(QString &sh, QString &cmd, int &port) const = 0;
0061 
0062     void disconnectClient(SensorClient *client);
0063 
0064     QString hostName() const;
0065 
0066     bool daemonOnLine() const;
0067     QString reasonForOffline() const;
0068 
0069 Q_SIGNALS:
0070     void reconfigure(const SensorAgent *);
0071 
0072 protected:
0073     void processAnswer(const char *buf, int buflen);
0074     void executeCommand();
0075 
0076     SensorManager *sensorManager();
0077 
0078     void setDaemonOnLine(bool value);
0079 
0080     void setHostName(const QString &hostName);
0081     void setReasonForOffline(const QString &reasonForOffline);
0082 
0083 private:
0084     virtual bool writeMsg(const char *msg, int len) = 0;
0085     QString mReasonForOffline;
0086 
0087     QQueue<SensorRequest *> mInputFIFO;
0088     QQueue<SensorRequest *> mProcessingFIFO;
0089     QList<QByteArray> mAnswerBuffer; /// A single reply can be on multiple lines.
0090     QString mErrorBuffer;
0091     QByteArray mLeftOverBuffer; /// Any data read in but not terminated is copied into here, awaiting the next load of data
0092 
0093     QPointer<SensorManager> mSensorManager;
0094 
0095     bool mDaemonOnLine;
0096     QString mHostName;
0097     QSet<SensorRequest> mUnderwayRequests;
0098 };
0099 
0100 /**
0101   This auxiliary class is used to store requests during their processing.
0102 */
0103 class SensorRequest
0104 {
0105 public:
0106     SensorRequest(const QString &request, SensorClient *client, int id);
0107     ~SensorRequest();
0108 
0109     void setRequest(const QString &);
0110     QString request() const;
0111 
0112     void setClient(SensorClient *);
0113     SensorClient *client();
0114 
0115     void setId(int);
0116     int id();
0117 
0118     friend uint qHash(const SensorRequest &sr, uint seed = 0)
0119     {
0120         return qHash(qMakePair(sr.mRequest, qMakePair(sr.mClient, sr.mId)), seed);
0121     }
0122     friend bool operator==(const SensorRequest &a, const SensorRequest &b)
0123     {
0124         return a.mRequest == b.mRequest && a.mClient == b.mClient && a.mId == b.mId;
0125     }
0126 
0127 private:
0128     QString mRequest;
0129     SensorClient *mClient = nullptr;
0130     int mId;
0131 };
0132 
0133 }
0134 
0135 #endif