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