summaryrefslogtreecommitdiffstats
path: root/ksysguard/gui/ksgrd/SensorAgent.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ksysguard/gui/ksgrd/SensorAgent.cc')
-rw-r--r--ksysguard/gui/ksgrd/SensorAgent.cc260
1 files changed, 260 insertions, 0 deletions
diff --git a/ksysguard/gui/ksgrd/SensorAgent.cc b/ksysguard/gui/ksgrd/SensorAgent.cc
new file mode 100644
index 000000000..a24bf5594
--- /dev/null
+++ b/ksysguard/gui/ksgrd/SensorAgent.cc
@@ -0,0 +1,260 @@
+/*
+ KSysGuard, the KDE System Guard
+
+ Copyright (c) 1999 - 2001 Chris Schlaeger <cs@kde.org>
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of version 2 of the GNU General Public
+ License as published by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <stdlib.h>
+
+#include <kdebug.h>
+#include <klocale.h>
+#include <kpassdlg.h>
+
+#include "SensorClient.h"
+#include "SensorManager.h"
+
+#include "SensorAgent.h"
+
+/**
+ This can be used to debug communication problems with the daemon.
+ Should be set to 0 in any production version.
+*/
+#define SA_TRACE 0
+
+using namespace KSGRD;
+
+SensorAgent::SensorAgent( SensorManager *sm )
+ : mSensorManager( sm )
+{
+ /* SensorRequests migrate from the inputFIFO to the processingFIFO. So
+ * we only have to delete them when they are removed from the
+ * processingFIFO. */
+ mInputFIFO.setAutoDelete( false );
+ mProcessingFIFO.setAutoDelete( true );
+
+ mDaemonOnLine = false;
+ mTransmitting = false;
+ mState = 0;
+}
+
+SensorAgent::~SensorAgent()
+{
+}
+
+bool SensorAgent::sendRequest( const QString &req, SensorClient *client, int id )
+{
+ /* The request is registered with the FIFO so that the answer can be
+ * routed back to the requesting client. */
+ mInputFIFO.prepend( new SensorRequest( req, client, id ) );
+
+#if SA_TRACE
+ kdDebug(1215) << "-> " << req << "(" << mInputFIFO.count() << "/"
+ << mProcessingFIFO.count() << ")" << endl;
+#endif
+ executeCommand();
+
+ return false;
+}
+
+void SensorAgent::processAnswer( const QString &buffer )
+{
+#if SA_TRACE
+ kdDebug(1215) << "<- " << buffer << endl;
+#endif
+
+ for ( uint i = 0; i < buffer.length(); i++ ) {
+ if ( buffer[ i ] == '\033' ) {
+ mState = ( mState + 1 ) & 1;
+ if ( !mErrorBuffer.isEmpty() && mState == 0 ) {
+ if ( mErrorBuffer == "RECONFIGURE\n" )
+ emit reconfigure( this );
+ else {
+ /* We just received the end of an error message, so we
+ * can display it. */
+ SensorMgr->notify( i18n( "Message from %1:\n%2" )
+ .arg( mHostName )
+ .arg( mErrorBuffer ) );
+ }
+ mErrorBuffer = QString::null;
+ }
+ } else if ( mState == 0 ) // receiving to answerBuffer
+ mAnswerBuffer += buffer[ i ];
+ else // receiving to errorBuffer
+ mErrorBuffer += buffer[ i ];
+ }
+
+ int end;
+ // And now the real information
+ while ( ( end = mAnswerBuffer.find( "\nksysguardd> " ) ) >= 0 ) {
+#if SA_TRACE
+ kdDebug(1215) << "<= " << mAnswerBuffer.left( end )
+ << "(" << mInputFIFO.count() << "/"
+ << mProcessingFIFO.count() << ")" << endl;
+#endif
+ if ( !mDaemonOnLine ) {
+ /* First '\nksysguardd> ' signals that the daemon is
+ * ready to serve requests now. */
+ mDaemonOnLine = true;
+#if SA_TRACE
+ kdDebug(1215) << "Daemon now online!" << endl;
+#endif
+ mAnswerBuffer = QString::null;
+ break;
+ }
+
+ // remove pending request from FIFO
+ SensorRequest* req = mProcessingFIFO.last();
+ if ( !req ) {
+ kdDebug(1215) << "ERROR: Received answer but have no pending "
+ << "request! : " << mAnswerBuffer.left( end ) << endl;
+ mAnswerBuffer = QString::null;
+ } else {
+ if ( !req->client() ) {
+ /* The client has disappeared before receiving the answer
+ * to his request. */
+ } else {
+ if ( mAnswerBuffer.left( end ) == "UNKNOWN COMMAND" ) {
+ /* Notify client that the sensor seems to be no longer
+ * available. */
+ req->client()->sensorLost( req->id() );
+ } else {
+ // Notify client of newly arrived answer.
+ req->client()->answerReceived( req->id(), mAnswerBuffer.left( end ) );
+ }
+ }
+ mProcessingFIFO.removeLast();
+ }
+ // chop off the processed part of the answer buffer
+ mAnswerBuffer.remove( 0, end + strlen( "\nksysguardd> " ) );
+ }
+
+ executeCommand();
+}
+
+void SensorAgent::executeCommand()
+{
+ /* This function is called whenever there is a chance that we have a
+ * command to pass to the daemon. But the command many only be send
+ * if the daemon is online and there is no other command currently
+ * being sent. */
+ if ( mDaemonOnLine && txReady() && !mInputFIFO.isEmpty() ) {
+ // take oldest request for input FIFO
+ SensorRequest* req = mInputFIFO.last();
+ mInputFIFO.removeLast();
+
+#if SA_TRACE
+ kdDebug(1215) << ">> " << req->request().ascii() << "(" << mInputFIFO.count()
+ << "/" << mProcessingFIFO.count() << ")" << endl;
+#endif
+ // send request to daemon
+ QString cmdWithNL = req->request() + "\n";
+ if ( writeMsg( cmdWithNL.ascii(), cmdWithNL.length() ) )
+ mTransmitting = true;
+ else
+ kdDebug(1215) << "SensorAgent::writeMsg() failed" << endl;
+
+ // add request to processing FIFO
+ mProcessingFIFO.prepend( req );
+ }
+}
+
+void SensorAgent::disconnectClient( SensorClient *client )
+{
+ for ( SensorRequest *req = mInputFIFO.first(); req; req = mInputFIFO.next() )
+ if ( req->client() == client )
+ req->setClient( 0 );
+ for ( SensorRequest *req = mProcessingFIFO.first(); req; req = mProcessingFIFO.next() )
+ if ( req->client() == client )
+ req->setClient( 0 );
+}
+
+SensorManager *SensorAgent::sensorManager()
+{
+ return mSensorManager;
+}
+
+void SensorAgent::setDaemonOnLine( bool value )
+{
+ mDaemonOnLine = value;
+}
+
+bool SensorAgent::daemonOnLine() const
+{
+ return mDaemonOnLine;
+}
+
+void SensorAgent::setTransmitting( bool value )
+{
+ mTransmitting = value;
+}
+
+bool SensorAgent::transmitting() const
+{
+ return mTransmitting;
+}
+
+void SensorAgent::setHostName( const QString &hostName )
+{
+ mHostName = hostName;
+}
+
+const QString &SensorAgent::hostName() const
+{
+ return mHostName;
+}
+
+
+SensorRequest::SensorRequest( const QString &request, SensorClient *client, int id )
+ : mRequest( request ), mClient( client ), mId( id )
+{
+}
+
+SensorRequest::~SensorRequest()
+{
+}
+
+void SensorRequest::setRequest( const QString &request )
+{
+ mRequest = request;
+}
+
+QString SensorRequest::request() const
+{
+ return mRequest;
+}
+
+void SensorRequest::setClient( SensorClient *client )
+{
+ mClient = client;
+}
+
+SensorClient *SensorRequest::client()
+{
+ return mClient;
+}
+
+void SensorRequest::setId( int id )
+{
+ mId = id;
+}
+
+int SensorRequest::id()
+{
+ return mId;
+}
+
+#include "SensorAgent.moc"