File indexing completed on 2024-05-05 17:39:48

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