|
|
|
/*
|
|
|
|
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 <tdelocale.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 TQString &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 TQString &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 = TQString::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 = TQString::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 = TQString::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
|
|
|
|
TQString 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 TQString &hostName )
|
|
|
|
{
|
|
|
|
mHostName = hostName;
|
|
|
|
}
|
|
|
|
|
|
|
|
const TQString &SensorAgent::hostName() const
|
|
|
|
{
|
|
|
|
return mHostName;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SensorRequest::SensorRequest( const TQString &request, SensorClient *client, int id )
|
|
|
|
: mRequest( request ), mClient( client ), mId( id )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
SensorRequest::~SensorRequest()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void SensorRequest::setRequest( const TQString &request )
|
|
|
|
{
|
|
|
|
mRequest = request;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString 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"
|