/***************************************************************************
                          knutnet.cpp  -  description
                             -------------------
    begin                : Ne led 12 2003
    copyright            : (C) 2003 by Daniel Prynych
    email                : Daniel.Prynych@alo.cz
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "knutnet.h"

#include <qtextstream.h>
#include <qstring.h>
#include <qcstring.h>
#include <qtimer.h>



//#include <sys/socket.h>
//#include <sys/types.h>
//#include <sys/time.h>
//#include <arpa/inet.h>
//#include <netdb.h>
//#include <netinet/in.h>
//#include <unistd.h>
//#include <errno.h>
//#include <fcntl.h>

#include <unistd.h>  // for function sleep

//#include <iostream>



/****** CONSTS ***********/

const Q_ULONG rBufferLen = 1024;



KNutNet::KNutNet (const QString tUpsAddress, const QString tUpsName, const unsigned short tPort, unsigned int tCountRepeat, const unsigned  int tDelay)
        : QObject(), upsAddress(tUpsAddress), upsName(tUpsName), countRepeat(tCountRepeat), port(tPort), delay(tDelay)  {

  state = Idle;
  numberVars = 0;
  numberRWVars = 0;
  numberIComms = 0;
  upsStatusVar = 0;
  nutProtocol = 0;
  nutVariables = 0;
  switchToTCP = false;
  
  description = false; // popis neni natazen  - description is not load

  unConnectTimer = new QTimer( this );
  connect( unConnectTimer, SIGNAL(timeout()), this, SLOT(slotTimerReconnect()) );

  error = NoError;

  commandSocket = new QSocket( this );
  connect( commandSocket, SIGNAL( hostFound()),this, SLOT( slotHostFound()));
  connect( commandSocket, SIGNAL( connected()),this,SLOT( slotConnected()));
  connect( commandSocket, SIGNAL( connectionClosed()),this, SLOT( slotConnectionClosed()));
  connect( commandSocket, SIGNAL( error(int)),this, SLOT( slotConnectionError(int)));
  }


KNutNet::~KNutNet(){
  QCString  inBuffer;
  QString  outBuffer;

  close(); // close connetion when is existed
    while (state == Closing ) {
      sleep (100);
      }
//  deleteVars() is made in close();
  }

  
void KNutNet::close (void) {
// std::cout << "--KNutNet::close"  << std::endl;
  QCString  inBuffer;
  QString  outBuffer;

  unConnectTimer->stop();
  deleteVars();
  if ((state == Connected) || (state == Connecting)) {
    state = Closing;
    if (state == Connected) {
      inBuffer="LOGOUT\n";
      getUpsData (inBuffer,outBuffer);
      // getUpsDate makes "commandSocket->flush()"
      }
    commandSocket->close(); // closes the socket
    if ( commandSocket->state() == QSocket::Closing ) {
      connect( commandSocket, SIGNAL(delayedCloseFinished()),this,SLOT(slotClosed()) );
      }
    else {
      slotClosed();
      }   
    }
  }
  
void KNutNet::slotClosed (void) {

  disconnect( commandSocket,SIGNAL(delayedCloseFinished()),this, SLOT(slotClosed()) );
//  disconnect( SIGNAL(delayedCloseFinished()),commandSocket, SLOT(slotClosed()) );
  state = Idle;
  }
  
    
void KNutNet::open (void) {

//std::cout << "--KNutNet::open"  << std::endl;
  QCString  inBuffer;
  QString  outBuffer;

  if ((state == Connected) || (state == Connecting)) close(); // close connetion when is existed
  else {
    while (state == Closing ) {
      sleep (100);
      }
    }
  if (upsAddress != "") {
    if ( commandSocket->state() != QSocket::Connecting ) {
      firstConnect=true;
      numberConnection=0;
      state = HostLookup;
      emit tryFirstConnection(countRepeat); // how many times we can try to connect with ups server /upsd/
//    std::cout << "--KNutNet :: Open emit - tryFirstConnection" << std::endl;
      commandSocket->connectToHost(upsAddress,port);
      }
    }
  }
  

void KNutNet::newUPS (const QString tUpsAddress, const QString tUpsName, const unsigned short tPort) {
    
  if ((state == Connected) || (state == Connecting)) { 
    close();
    while (state == Closing ) {
      sleep (100);
      }
    }
    
  upsAddress = tUpsAddress;
  upsName = tUpsName;
  port = tPort;
  
  state = Idle;
  numberVars = 0;
  numberRWVars = 0;
  numberIComms = 0;
  upsStatusVar = 0;
  nutProtocol = 0;
  nutVariables = 0;
  switchToTCP = false;

  error = NoError;
  //firstConnect=true;
  //numberConnection=0;
  }
  
  
      
int KNutNet::getError ( void ) { return error; }

int KNutNet::getState ( void ){ return state; }

bool KNutNet::isDescription ( void ){ return description; }
      
int KNutNet::getNutProtocol ( void ) { return nutProtocol; }

int KNutNet::getNutVariables ( void ) { return nutVariables; }

bool KNutNet::switchedToTCP ( void ) { return switchToTCP; }


int KNutNet::getUpsVars ( void) {
  error=0;
  if (state == Connected) {

    // init vars and lists
    numberVars = 0;
    numberRWVars = 0;
    numberIComms = 0;
    deleteVars();
    switch (nutProtocol) {
      case 1:
        return getUpsVars1();
      break;
      case 2:
        return getUpsVars2();
      break;
      default:
      return 0;  
      }  
    }
  else {
    return NotConnection;
    }
  }


int KNutNet::getUpsValues (const bool allVars ) {// allVars = true vse; allVars = false jen activate

  error=0; // vynulujeme chyby
  if (state == Connected) {
    // init vars and lists
    switch (nutProtocol) {
      case 1:
        return getUpsValues1(allVars);
      break;
      case 2:
        return getUpsValues2(allVars);
      break;
      default:
      return 0;
      }
    }
  else {
    return NotConnection;
    }
  }  



int KNutNet::getDescription (bool always) {

  error=0; // vynulujeme chyby
  if (state == Connected) {
    switch (nutProtocol) {
      case 1:
        return getDescription1 (always);
      break;
      case 2:
        return getDescription2 (always);
      break;
      default:
        return 0;
      }
    }  
  else return NotConnection;
  }


int KNutNet::instantCommand (const QString command, const QString userName, const QString password, const bool onlyCommand) {
  error=0; // vynulujeme chyby
  if (state == Connected) {
    QString outBuffer;

    // funkce sendComm sama mastavi promenou error
    if (onlyCommand) {
      if (!(error = sendComm("INSTCMD", command, "",true))) {
//        netMutex=false;
        return 0;
        }
      else { 
//        netMutex=false;
        return error;
        }
      }
    else {
      if (!(error = sendComm ("USERNAME", userName, ""))) {
        if (!(error = sendComm("PASSWORD", password, ""))) {
          if (!(error = sendComm("INSTCMD", command, "",true))) {
//            netMutex=false;
            return 0;
            }
          else { 
            return error;
            }
          } //username
        else { 
          return error;
	  }
        }
      else {
	return error;
	}
      }
    }
  else return NotConnection;
  }


int KNutNet::setVariable (const QString variable, const QString value, const QString userName, const QString password, const bool onlyVariable) {
  error=0; // vynulujeme chyby
  if (state == Connected) {
    QString outBuffer;
    QString setCommand;

    switch (nutProtocol) {
      case 1: setCommand = "SET";
         break;
      case 2: setCommand = "SET VAR";
      }
    if (onlyVariable) {
      if (!(error = sendComm(setCommand, variable, value, true))) {
        return 0;
        }
      else { 
	return error;
	}
      }
    else {
      if (!(error = sendComm ("USERNAME", userName, ""))) {
        if (!(error = sendComm("PASSWORD", password, ""))) {
          if (!(error = sendComm(setCommand, variable, value, true))) {
            //netMutex=false;
            return 0;
            }
          else {
	    return error;
	    }
          } //username
        else {
	  return error;
	  }
        }
      else {
	 return error;
	 }
      }
    }
  else return NotConnection;
  }


int KNutNet::readNumberVars (typeOfVar typVar) {
//  Vraci pocet promenych
  error=0;
  if (state == Connected) {
    switch (typVar) {
      case AllVars:
        return numberVars;
        break;
      case ROVars:
        return numberVars - numberRWVars;
        break;
      case RWVars:
        return numberRWVars;
        break;
      default:
        return -1;
      }
    }
  else return -1;
  }

int KNutNet::readNumberComms (void) {
//  Vraci pocet prikazu
  error=0;
  if (state == Connected) return numberIComms;
  else return -1;
  }


int KNutNet::readIComm (const int seqNumber, struct upsIComm& iComm) {
  error =0;
  if (state == Connected) {
    if ((seqNumber < 1) || ((unsigned int)seqNumber > listIComms.size())) {
      error=CommNotFind;
      return error;
      }
    iComm = listIComms[seqNumber-1];
    return 0;
    }
  else return NotConnection;
  }  


int KNutNet::readVars (const QString name, struct upsVar& allVar) {
  error =0;
  if (state == Connected) {
      QValueVector<upsVar>::const_iterator it;
    for (it = listVars.begin(); it != listVars.end(); it++) {
       if ((*it).upsVarName == name) {
         allVar = (*it);
         return 0;
         }
       }
     error=VarNotFind;
     return error;
    }
  else return NotConnection;
  }

  int KNutNet::readVars (const int seqNumber, struct upsVar& allVar, const typeOfVar typVar) {
  error =0;
  if (state == Connected) {
    int n = 1;
    QValueVector<upsVar>::const_iterator it;

    for (it = listVars.begin(); it != listVars.end(); it++) {
      if ((typVar== AllVars) || ((typVar==ROVars) && ((*it).upsVarType)) ||
        ((typVar==RWVars) && (!(*it).upsVarType))) {
        if (n == seqNumber) {
          allVar = (*it);
          return 0;
          }
        n++;
        }
      }
    error=VarNotFind;
    return error;
    }
  else return NotConnection;
  }  


QString KNutNet::readStringVar (const QString name) {
  
  error =0;
  if (state == Connected) {
      QValueVector<upsVar>::const_iterator it;
    for (it = listVars.begin(); it != listVars.end(); it++) {
      if ((*it).upsVarName == name) return (*it).upsValue;
      }
    error = VarNotFind;
    return 0l;  
    }
  else return 0l;
}


QString KNutNet::readEnumValueVar (const QString name, const int valueNumber) {
  error =0;
  if (state == Connected) {
//    #if defined  (KDE_VERSION_MAJOR)
//      #if KDE_VERSION_MAJOR >= 3
        QValueVector<upsVar>::const_iterator it;
//      #else
//        QValueList<upsVar>::ConstIterator it;
//      #endif
//    #else
//      QValueList<upsVar>::ConstIterator it;
//    #endif


    for (it = listVars.begin(); it != listVars.end(); it++) {
      if ((*it).upsVarName == name) {
        if ((valueNumber < 1) || (valueNumber > (*it).upsVarMax)) {
          error=EnumValueNotFind;
          return 0l;
          }
        // vratime hodnotu
        return (*(*it).upsEnumValues)[valueNumber-1];
        }
      }
    error = VarNotFind;
    return 0l;
    }
  else return 0l;
  }


int KNutNet::readStatus(void) {
  error=0;
  return upsStatusVar;
  }

  
int KNutNet::setActivate ( const QString name ) {
  return activate (name,true);
  }


int KNutNet::unSetActivate ( const QString name ) {
  return activate (name,false);
  }


int KNutNet::unSetActivateAll ( void ) {
  return activateAll (false);
  }
                  

int KNutNet::existName ( const QString name ) {
  error =0;
  if (state == Connected) {
        QValueVector<upsVar>::const_iterator it;
    for (it = listVars.begin(); it != listVars.end(); it++) {
      if ((*it).upsVarName == name) return 0;
      }
    error = VarNotFind;
    return error;
    }
  else return NotConnection;
  }

/*************************************************************************/  
/*                                                                       */
/*                           PRIVATE FUNCTIONS                           */
/*                                                                       */
/*************************************************************************/


int KNutNet::version (int countRepeat, const int delay) {
  QCString  inBuffer;
  QString  outBuffer;

  error =0;
  do {
    inBuffer="VER\n";
    if (!(error=getUpsData (inBuffer,outBuffer))) {
      outBuffer=outBuffer.stripWhiteSpace ();

      if (outBuffer.length() > 0) {
        outBuffer = outBuffer.mid(outBuffer.find("upsd")+4);
        int n = outBuffer.find(".");
        if (n > 0) {
          QString firstNumber= outBuffer.left(n);
          QString secondNumber= outBuffer.mid(n+1);
          int n = secondNumber.find(".");
          if (n > 0) {
            bool ok;
            secondNumber = secondNumber.left(n);
            int secondInt = secondNumber.toInt(&ok);
            if (!ok) {error = UnknownFormatVer; return error;}
            int firstInt = firstNumber.toInt(&ok);
            if (!ok) {error = UnknownFormatVer; return error;}
            if ((firstInt == 0) || ((firstInt == 1)  && (secondInt < 3))) {
              nutProtocol =1;
              nutVariables =1;
              }
            else {
              nutProtocol =2;
              nutVariables =2;
              }
            return 0;
            }
          else error = UnknownFormatVer; // n is <= 0 the second dot
          }
        else error = UnknownFormatVer; // n is <= 0 the first dot
        }
      error = UnknownAnswer; // i cannot specify number of protocol and number of variables
      return error;
      }
    countRepeat--;
    if (countRepeat) sleep (delay);
    }
  while ((countRepeat));
  return error;
  }

  

int KNutNet::getFirstUpsName (QString& firstUpsName) {
  QCString  inBuffer;
  QString  outBuffer;
  QString  varOutBuffer;
  int lenString;
  
  error=0;
  inBuffer = "LIST UPS\n";
  if (!(error=getUpsData (inBuffer,outBuffer,"END LIST UPS"))) {

    QString inLine, upsNameRet, varName, value;
    int key, typeValue;
    bool beginList = false;
    QTextIStream varInputStream(&outBuffer);
    while (!(inLine = varInputStream.readLine()).isNull()) {
      key = parseLine (inLine, upsNameRet, varName, value, typeValue, lenString);
      switch (key) {
        case BEGIN_LIST_UPS: {
          beginList = true;;
          break;
          }
        case UPS:
         if (beginList ) {
           firstUpsName = upsNameRet;
           return 0;
           }
        case END_LIST_UPS:
          firstUpsName = "";
            error=NoUpsHere;
            return error;
        case ERR:
          error = upsTranslateError(value);
          return error;
        default:
          error=UnknownAnswer;
          return error;
        }
      }// end while
    }
  else {error=NoData; return error; }
  return 0;
  }



int KNutNet::setKey (const QString line) {
  QString myLine=line.stripWhiteSpace();
  if (myLine == "OK") return OK;
  if (myLine == "ERR") return ERR;
  if (myLine == "BEGIN") return BEGIN;
  if (myLine == "END") return END;
  if (myLine == "VAR") return VAR;
  if (myLine == "TYPE") return TYPE;
  if (myLine == "DESC") return DESC;
  if (myLine == "CMDDESC") return CMDDESC;
  if (myLine == "UPSDESC") return CMDDESC;
  if (myLine == "UPS") return UPS;
  if (myLine == "LIST") return LIST;
  if (myLine == "RW") return RW;
  if (myLine == "CMD") return CMD;
  if (myLine == "ENUM") return ENUM;
  if (myLine == "STARTTLS") return STARTTLS;
  return NONE;
  }

QString KNutNet::parseValue (const QString line) {
  
 // QString line = tLine.stripWhiteSpace();
  if (line.isEmpty()) return "";
  if (line[0] != "\"") {
    if ((posChar=line.find(' ')) == -1) return line;
    else return line.left(posChar+1);
    }
  else {
    int len = line.length();
    QString outString = "";
    for (int i=1; i < len; i++) {
      if ( line[i] == "\\") {
        if ((i+1) <len) {
          if ((line[i+1] == "\"") || (line[i+1] == "\"")) {
            outString +=line[i+1];
            i++;
            }
          else i +=2;  
          }
        outString +=line[i];
        continue;
        }
      if (line [i] == "\"") {
        return outString;
        }
      outString += line[i];    
      }
    return outString;
    }
  return "";
  }

int KNutNet::parseTypeValue (QString line, int& lenString ) {
  int ret=0;
  QString word;

  lenString = 0;
  if (line.isEmpty()) return 0;
  QTextIStream inputStream(&line);
  while (!inputStream.atEnd()) {
    inputStream >> word;
    if (word == "RW") ret += RW_FLAG;
    if (word == "ENUM") ret += ENUM_FLAG;
    if (word.find("STRING:") != -1) {
      word = word.mid(7);
      ret += STRING_FLAG;
      lenString = word.toInt();
      }
    }
  return ret;
  }

        
int KNutNet::parseLine(QString& line, QString& upsName ,QString& varName, QString& value, int& typeValue, int& lenString) {
  int posChar;
  QString word1, word2, word3;
  int key1, key2, key3;
        
  line = line.stripWhiteSpace();

  upsName = "";
  varName = "";
  value = "";
  typeValue =0;
  
  if (line.isEmpty()) return NONE;
  
  if ((posChar=line.find(' ')) == -1) {
    if (setKey(line) == OK) return OK;
    else return NONE;
    }
  else {
    key1 = setKey( line.left(posChar));
    line = line.mid(posChar+1);

    switch (key1) {

      case NONE:
        return key1;
      case OK:
        return key1;
      case ERR:
        value = parseValue(line);
        return key1;
      default:
        if ((posChar=line.find(' ')) == -1) return NONE;
        word2 = line.left(posChar);
        key2 = setKey( word2);
        line = line.mid(posChar+1);

        switch (key1) {
          case BEGIN:
            if ((key2 == LIST) && (setKey(line) == UPS)) return BEGIN_LIST_UPS;
          break;
          case END:
            if ((key2 == LIST) && (setKey(line) == UPS)) return END_LIST_UPS;
          break;
          case UPS:
            upsName = word2;
            value = parseValue(line);
            return key1;
          case CMD:
            upsName = word2;
            varName = parseValue(line);
            return key1;
          }

        if ((posChar=line.find(' ')) == -1) return NONE;

        word3 = line.left(posChar);
        key3 = setKey( word3);
        line = line.mid(posChar+1);
    
        switch (key1) {
          case VAR:
            upsName = word2;
            varName = word3;
            value = parseValue(line);
            return VAR;
          case TYPE:
            upsName = word2;
            varName = word3;
            typeValue = parseTypeValue(line,lenString);
            return TYPE;
          case ENUM:
            upsName = word2;
            varName = word3;
            value = parseValue(line);
            return ENUM;
          case DESC:
            upsName = word2;
            varName = word3;
            value = parseValue(line);
            return DESC;
          case CMDDESC:
            upsName = word2;
            varName = word3;
            value = parseValue(line);
            return CMDDESC;
          case BEGIN:
            if (key2 != LIST) return NONE;
            if (key3 == VAR) {
              upsName=line.stripWhiteSpace();
              return BEGIN_LIST_VAR;
              }
            if (key3 == RW) {
              upsName=line.stripWhiteSpace();
              return BEGIN_LIST_RW;
              }
            if (key3 == CMD) {
              upsName=line.stripWhiteSpace();
              return BEGIN_LIST_CMD;
              }
            if (key3 == ENUM) {
              if ((posChar=line.find(' ')) == -1) return NONE;
              upsName = line.left(posChar);
              line=line.mid(posChar+1);
              varName = line.stripWhiteSpace();
              return BEGIN_LIST_ENUM;
              }
            return NONE;  
          case END:
            if (key2 != LIST) return NONE;
            if (key3 == VAR) {
              upsName=line.stripWhiteSpace();
              return END_LIST_VAR;
              }
            if (key3 == RW) {
              upsName=line.stripWhiteSpace();
              return END_LIST_RW;
              }
            if (key3 == CMD) {
              upsName=line.stripWhiteSpace();
              return END_LIST_CMD;
              }
            if (key3 == ENUM) {
              if ((posChar=line.find(' ')) == -1) return NONE;
              upsName = line.left(posChar);
              line=line.mid(posChar+1);
              varName = line.stripWhiteSpace();
              return END_LIST_ENUM;
              }
            return NONE;
          default:
            return NONE;
          }  
      }
    }  
  }    


int KNutNet::newDescription (const QCString  inBuffer, QString& upsDescription) {
  QString  outBuffer;

  if (!(error=getUpsData (inBuffer,outBuffer))) {
    outBuffer=outBuffer.stripWhiteSpace ();
    QString word1, word2, word3;

    if ((posChar = outBuffer.find(' ')) == -1)
      word1 = outBuffer;
    else {
      word1 = outBuffer.left(posChar);
      word2 = outBuffer.mid(posChar+1);
      }
    if (word1 == "DESC") {
      if ((posChar = word2.find('\"')) == -1) word3="";
      else
        {
        word3 = word2.mid(posChar+1);
        if ((posChar = word3.find('\"')) != -1) word3=word3.left(posChar);
        }
      if (!word3.isEmpty()) upsDescription=word3;
      }
    else {
      if (word1 == "ERR" ) return upsTranslateError(word2);
      else return UnknownAnswer;
      }
    }
  else return error;
  return 0;
  }


void KNutNet::cleanConnecting (void) {
  Q_ULONG rMaxLen; 
  QCString  recvBuffer(rBufferLen);
  Q_LONG lengthInputData;

  int n = 0;
  while (commandSocket->bytesAvailable() > 0) {
    
    if ( (commandSocket->bytesAvailable()+1) > rBufferLen) rMaxLen = rBufferLen;
    else rMaxLen=commandSocket->bytesAvailable()+1;
    
    recvBuffer.resize(rMaxLen);
    if ((lengthInputData = commandSocket->readBlock(recvBuffer.data(),rMaxLen)) == -1) {
      }
     if (lengthInputData == 0) break;
     if (n > 20) break; else n++;
    }  
  }  
  

int KNutNet::getUpsData (const QCString sBuffer, QString& rBuffer, const QCString endString) {

  //rbufferLen a sbufferLen are maximal value of buffers
  QCString  recvBuffer(rBufferLen);
  Q_LONG lengthInputData;
  Q_ULONG dataAvailable;

  
  QMutexLocker getUpsDataLocker( &getUpsDataMutex );

  cleanConnecting();
  // first we clean input TCP buffer

  //cleans buffer 
  rBuffer=""; // clean main input buffer;
  
      
  // after write block, runs command flush for sending data to server inmediately
  if (commandSocket->writeBlock(sBuffer.data(),sBuffer.length()) < 0 ) return SendErr;
  commandSocket->flush();

  if (commandSocket->waitForMore(1000) == 0) {
    commandSocket->waitForMore(500); // workaround 
    }
  bool endRecv = false;
  do {
    dataAvailable=commandSocket->bytesAvailable();
    if (recvBuffer.size() < (dataAvailable+1) ) recvBuffer.resize(dataAvailable+1);
    if ((lengthInputData = commandSocket->readBlock(recvBuffer.data(),dataAvailable)) == -1) return RecvErr;
    
//correct for X86_64  by Alexey Sidorov    
    recvBuffer[(int)lengthInputData]='\0';
    //    recvBuffer[lengthInputData]='\0';  
    
    //Problem is that
    //for 64bit enviroment is Q_LONG defined like _int64 and
    //for other enviroment is Q_LONG defined like long      
    
    
    
    
    rBuffer.append(recvBuffer.data()); // adds reading data to main input buffer
    if (endString.isEmpty()) endRecv = false;
    else {
      if (recvBuffer.findRev(endString) == -1)  {
//doesn't find right end of input data
        if (commandSocket->bytesAvailable() == 0) commandSocket->waitForMore(1000); 
        if (commandSocket->bytesAvailable() > 0)  endRecv=true; // makes other cyckle og while
          else endRecv=false;
        }
//finds right end of input data
      else endRecv = false; // we have found what we want to find
      }    
    } while (endRecv);
  return 0;   // all is OK
  }

  
  
    void KNutNet::setRWVars (const QString varName, const bool valueType, const int varMax, QValueVector<QString>* enumValues) {
      QValueVector<upsVar>::iterator it;
   
   for (it = listVars.begin(); it != listVars.end(); it++) {
     if ((*it).upsVarName == varName) {
       (*it).upsVarMax = varMax;
       (*it).upsValueType=valueType;
       (*it).upsEnumValues=enumValues;
       (*it).upsVarType=false;
       break;
       }
    }
  }

void KNutNet::upsSetType (struct upsVar& uVar, const QString name, const QString value) {
  if (((nutVariables = 2) && (name == "STATUS")) || ((nutVariables = 2) && (name == "ups.status")))
    uVar.upsVarActivate=true;
  else uVar.upsVarActivate=false;
  uVar.upsVarName = name;
  uVar.upsVarType=true;
  uVar.upsValueType=true;
  uVar.upsVarMax=0;
  uVar.upsValue=value;
  uVar.upsDescription="";
  uVar.upsEnumValues=0L;
}


void KNutNet::deleteVars (void) {
//  #if defined  (KDE_VERSION_MAJOR)
//    #if KDE_VERSION_MAJOR >= 3
      QValueVector<upsVar>::iterator it;
//    #else
//      QValueList<upsVar>::Iterator it;
//    #endif
//  #else
//    QValueList<upsVar>::Iterator it;
//  #endif
  for (it = listVars.begin(); it != listVars.end(); it++) {
    if ((*it).upsEnumValues != 0) {
      (*it).upsEnumValues->clear();
      delete (*it).upsEnumValues;
      }
    }
  listVars.clear();
  listIComms.clear();     
  }

void KNutNet::genStatusFlags (QString value) {
  upsStatusVar = 0;
  QTextIStream inputStream(&value);
  QString word;
  while (!inputStream.atEnd()) {
    inputStream >> word;
    if (word == "OFF") upsStatusVar +=OFF;
    if (word == "OL") upsStatusVar +=OL;
    if (word == "OB") upsStatusVar +=OB;
    if (word == "LB") upsStatusVar +=LB;
    if (word == "CAL") upsStatusVar +=CAL;
    if (word == "TRIM") upsStatusVar +=TRIM;
    if (word == "BOOST") upsStatusVar +=BOOST;
    if (word == "OVER") upsStatusVar +=OVER;
    if (word == "RB") upsStatusVar +=RB;
    //OFF     -  1 ups je vypnuta
    //OL      -  2 ups je bezi na sit
    //OB      -  4 ups bezi na baterie
    //LB      -  8 baterie je vybyta (pokud je zaroven OB dojde k shutdownu)
    //CAL     - 16 je spustena kalibrace
    //OVER    -128 ups je pretizena
    //RB      -256 ups pozaduje vymenu baterie
    }
  }  


int KNutNet::getDescription1 (bool always) {

  if (always || (! description)) {
    QCString  inBuffer;
    QString  outBuffer;

     QValueVector<upsVar>::iterator itv;
     QValueVector<upsIComm>::iterator itc;
     for (itv = listVars.begin(); itv != listVars.end(); itv++) {
      //nacteme promenou
      inBuffer = "VARDESC " + (*itv).upsVarName + "\n";
      if ((error = newDescription (inBuffer, (*itv).upsDescription))) {
        //netMutex.unlock();
//        netMutex=false;
        return error;
        }
      }
    for (itc = listIComms.begin(); itc != listIComms.end(); itc++) {
      //nacteme promenou
      inBuffer = "INSTCMDDESC "+(*itc).upsCommName+"\n";
      if ((error = newDescription (inBuffer, (*itc).upsDescription))) {
        //netMutex.unlock();
        //netMutex=false;
        return error;
        }
      }
    //netMutex=false;
    description = true;
    }
  return 0;
  }



int KNutNet::getDescription2 (bool always) {

  if (always || (! description)) {
    QCString  inBuffer;
    QString  outBuffer;
    QString upsNameRet;
    QString varName;
    QString value;
    int typeValue;
    int lenString;

     QValueVector<upsVar>::iterator itv;
     QValueVector<upsIComm>::iterator itc;
     for (itv = listVars.begin(); itv != listVars.end(); itv++) {
      //nacteme promenou
      inBuffer = "GET DESC " + upsName + " " + (*itv).upsVarName+"\n";

      if (!(error=getUpsData (inBuffer,outBuffer))) {
        outBuffer=outBuffer.stripWhiteSpace ();
        if ( !outBuffer.isEmpty() ) {
          int key = parseLine(outBuffer, upsNameRet, varName, value, typeValue, lenString);
          switch (key) {
            case DESC:
              (*itv).upsDescription = value;
               break;
            case ERR:
              error=upsTranslateError(value);
              return error;
            default:
              error=UnknownAnswer;
              return error;
            }
          }
        else {
	  error = NoData;
	  return error;
	  }
        }
      else {
	return error;
	}
      }
    for (itc = listIComms.begin(); itc != listIComms.end(); itc++) {
      //nacteme promenou
      inBuffer = "GET CMDDESC " + upsName + " " + (*itc).upsCommName+"\n";
      if (!(error=getUpsData (inBuffer,outBuffer))) {
        outBuffer=outBuffer.stripWhiteSpace ();
        if ( !outBuffer.isEmpty() ) {
          int key = parseLine(outBuffer, upsNameRet, varName, value, typeValue, lenString);
          switch (key) {
            case CMDDESC:
              (*itc).upsDescription = value;
               break;
            case ERR:
              error=upsTranslateError(value);
              return error;
            default:
              error=UnknownAnswer;
              return error;
            }
          }
        else {
	  error = NoData;
	   return error;
	   }
        }
      else {
	return error;
	}
      }
    description = true;
    }
  return 0;
  }



int KNutNet::getUpsVars1 ( void) {
// getUpsVars nacte promene a jejich typ
// vraci kod chyby nebo 0 pokud je vse v poradku
  QCString  inBuffer;
  QString  outBuffer;
  QString  varOutBuffer;
  struct upsVar uVars;
  upsIComm uIComm;

  // init vars and lists
  if (!upsName.isEmpty()) { // pokud upsName neni je vzdy nastaveno na null
    inBuffer="LISTVARS ";
    inBuffer.append(upsName);
    inBuffer.append("\n");
    }
  else inBuffer ="LISTVARS\n";

  if (!(error=getUpsData (inBuffer,outBuffer))) {
    outBuffer=outBuffer.stripWhiteSpace ();
    if (outBuffer.length() > 0) {
    // precteme data
      QTextIStream inputStream(&outBuffer);
      QString word;
      int count =1 ;
      while (!inputStream.atEnd()) {
        inputStream >> word;
        switch (count) {
          case 1:
          // vyndame prvni polozku
          if (word == "VARS") count++;
          else {
            if (word == "ERR") {
              inputStream >> word;
              error = upsTranslateError(word);
              }
            else error=UnknownAnswer;
            return error;
            }
          break;
        case 2:
          count++;
          if ((word.length() > 0) && word.startsWith("@")) break;
          default:
          // pridame polozku do tabulky
          upsSetType(uVars, word);
              listVars.push_back(uVars);
          numberVars++;
          break;
          }
        }
      }
    else { error=NoData; return error; }
    }
  else return error;

  if ((error = getUpsValues1(true))) return error;
  
  // *********** RW VARIABLES
  if (!upsName.isEmpty()) { // pokud upsName neni je vzdy nastaveno na null
    inBuffer="LISTRW ";
    inBuffer.append(upsName);
    inBuffer.append("\n");
    }
  else inBuffer ="LISTRW\n";

  if (!(error=getUpsData (inBuffer,outBuffer))) {
    outBuffer=outBuffer.stripWhiteSpace();
    if (!outBuffer.isEmpty()) {
    // precteme data
      QTextIStream inputStream(&outBuffer);
      QString word;
      int count =1 ;
      bool valueType;
      int varMax;
      while (!inputStream.atEnd()) {
        inputStream >> word;
        switch (count) {
          case 1:
          // vyndame prvni polozku
           if (word == "RW") count++;
           else {
             if (word == "ERR") {
               inputStream >> word;
               error = upsTranslateError(word);
               }
             else error=UnknownAnswer;
             return error;
             }
          break;
          case 2:
          count++;
          if ((word.length() > 0) && word.startsWith("@")) break;
          default:
          // Zpracujeme polozku v tabulce
          // zjistime informaci o promene
          inBuffer="VARTYPE ";
          inBuffer.append(word);
          if (!upsName.isEmpty()) {
            inBuffer.append("@"); // pokud upsName neni je vzdy nastaveno na null
            inBuffer.append(upsName);
            }
          inBuffer.append("\n");
          if (!(error=getUpsData (inBuffer,varOutBuffer))) {
            varOutBuffer=varOutBuffer.stripWhiteSpace();
            if ( !outBuffer.isEmpty() ) {
              QTextIStream varInputStream(&varOutBuffer);
              QString word1, word2, word3;
              varInputStream >> word1;
              varInputStream >> word2;
              varInputStream >> word3;
              if (word1 == "TYPE") {
                if ((word2.isEmpty()) || (word3.isEmpty())) {
                  error=UnknownFormat;
                  return error;
                  }
                if (word2 == "ENUM") valueType=false;
                else {
                  if (word2 =="STRING") valueType=true;
                  else {
                    error=UnknownFormat;
                    return error;
                    }
                  }
                bool ok = true;
                varMax=word3.toInt(&ok);
                if (!ok) {error=UnknownFormat; return error;};
                } // word1 = Type
              else {
                if (word1=="ERR") {
                  error = upsTranslateError(word2);
                  return error;
                  }
                else {
                  error = UnknownAnswer;
                  return error;
                  }
                }
              }
            else { error=NoData; return error; }
            }
          else return error;
          // ********** ENUM / STRING ******************

          QValueVector<QString>* enumString=0;
          if (!valueType) {
          // nacteme enum hodnoty
            inBuffer="ENUM ";
            inBuffer.append(word);
            // pokud existuje pridame jmeno UPS-ky
            if (!upsName.isEmpty()) {
              inBuffer.append("@");
              inBuffer.append(upsName);
              }
            inBuffer.append("\n");
            if (!(error=getUpsData (inBuffer,varOutBuffer,"END\n"))) {
//               varOutBuffer.stripWhiteSpace();  nemuze provest protoze bychom si odstranili konce radek
              if (!varOutBuffer.isEmpty()) {
                QString inLine, word1, word2;
                QTextIStream varInputStream(&varOutBuffer);
                int inCountLine=1;
                while (!(inLine = varInputStream.readLine()).isNull()) {
                  inLine=inLine.stripWhiteSpace();

                  if ((posChar=inLine.find(' ')) == -1) word1=inLine;
                  else {
                    word1=inLine.left(posChar);
                    inLine = inLine.mid(posChar+1);
                    }
                  if (word1.isEmpty()) { error = UnknownFormat; return error; }
                  if (inCountLine == 1) {
                  if ((posChar=inLine.find(' ')) == -1) word2=inLine;
                  else word2=inLine.left(posChar);
                    if (word1 =="ENUM") {
                      if (word2 != word) { error = UnknownFormat; return error; }
                      varMax=0;
                      inCountLine++;
                      enumString = new QValueVector<QString>;
                      enumString->clear();
                      }
                    else {
                      if (word1=="ERR")
                        error=upsTranslateError(word2); // prevede chybu na jeji kod
                      else error=UnknownAnswer;
                      return error;
                      }
                    }
                  else {
                    if (word1 == "END") break;
                    if (word1 != "OPTION") { error = UnknownFormat; return error; }
                    if ((posChar = inLine.find('\"')) == -1) word2 = "";
                    else {
                      word2 = inLine.mid(posChar+1);
                      if ((posChar=word2.find('\"')) != -1) word2 = word2.left(posChar);
                      }
                    enumString->push_back(word2);
                    varMax++;
                    }
                  } // end while
                } // buffer is not empty
              else { error = NoData ; return error; }
              } // getUpsData
            else return error;
            } // type of var
          else  enumString = 0l;
          // nacteme stringovou promenou
          // ulozime promene
          setRWVars (word,valueType,varMax,enumString);
          numberRWVars++;
          break;
          }
        } // end  while (!inputStream.atEnd())
      }
    else { error = NoData ; return error; }
    }
  else return error;

  // *************** INSTANT COMMAND
  if (!upsName.isEmpty()) { // pokud upsName neni je vzdy nastaveno na null
    inBuffer="LISTINSTCMD ";
    inBuffer.append(upsName);
    inBuffer.append("\n");
    }
  else inBuffer ="LISTINSTCMD\n";

  if (!(error=getUpsData (inBuffer,outBuffer))) {
    outBuffer=outBuffer.stripWhiteSpace ();
    if ( !outBuffer.isEmpty() ) {
      // precteme data
      QTextIStream inputStream(&outBuffer);
      QString word;
      int count =1 ;
      while (!inputStream.atEnd()) {
        inputStream >> word;
        switch (count) {
          case 1:
          // vyndame prvni polozku
           if (word == "INSTCMDS") count++;
           else {
             if (word == "ERR") {
               inputStream >> word;
               error = upsTranslateError(word);
               }
             else error=UnknownAnswer;
             return error;
             }
          break;
          case 2:
          count++;
          if ((word.length() > 0) && word.startsWith("@")) break;
          default:
          // Zpracujeme polozku v tabulky
          uIComm.upsCommName=word;
          uIComm.upsDescription="";
          listIComms.push_back(uIComm);
          numberIComms++;
          break;
          }
        }
      }
    else { error=NoData; return error; }
    }
  else return error;
  return 0;
  }



int KNutNet::getUpsVars2 ( void) {
  QCString  inBuffer;
  QString  outBuffer;
  QString  varOutBuffer;
  struct upsVar uVars;
  upsIComm uIComm;
  int key;
  int typeValue;
  int lenString;
  int varMax=0;

  QValueVector<QString>* enumString=0;
  inBuffer = "LIST VAR " + upsName + "\n";
  if (!(error=getUpsData (inBuffer,outBuffer,"END LIST VAR"))) {
    QString inLine, upsNameRet, varName, varNameRet, value;
    bool beginList = false;
    QTextIStream varInputStream(&outBuffer);
    while (!(inLine = varInputStream.readLine()).isNull()) {
      key = parseLine (inLine, upsNameRet, varName, value, typeValue, lenString);
      switch (key) {
        case BEGIN_LIST_VAR:
          if (upsNameRet == upsName) beginList = true;
        break;
        case VAR:
         if (beginList ) {
           upsSetType(uVars, varName, value);

           if (varName == "ups.status") genStatusFlags(value);
           inBuffer = "GET TYPE " + upsName + " " + varName +"\n";
           if (!(error=getUpsData (inBuffer,varOutBuffer))) {
             key = parseLine (varOutBuffer, upsNameRet, varNameRet, value, typeValue, lenString);
             switch (key) {
               case TYPE:
                if (typeValue & RW_FLAG) {
                  uVars.upsVarMax = 0;
                  uVars.upsEnumValues=0L;
                  if (typeValue & ENUM_FLAG) {
                    uVars.upsValueType=false;
                    // nacteme enumValues
                    inBuffer = "LIST ENUM " + upsName + " " + varName +"\n";
                    if (!(error=getUpsData (inBuffer,varOutBuffer,"END LIST ENUM"))) {
                      bool beginEnumList = false;
                      QTextIStream varInputStream(&varOutBuffer);
                      while (!(inLine = varInputStream.readLine()).isNull()) {
                        key = parseLine (inLine, upsNameRet, varName, value, typeValue, lenString);
                        switch (key) {
                          case BEGIN_LIST_ENUM:
                            beginEnumList = true;
                            varMax=0;
                                 enumString = new QValueVector<QString>;
                            enumString->clear();
                            uVars.upsEnumValues=enumString;
                          break;
                          case ENUM:
                            if (beginList ) {
                                  enumString->push_back(value);
                              varMax++;
                              }
                          break;
                          case ERR:
                            error = upsTranslateError(value);
                          return error;
                          default:
                            error=UnknownAnswer;
                          return error;
                          case END_LIST_ENUM:
                          uVars.upsVarMax=varMax;
                          break;
                          }
                        }
                      }
                    }
                  else {
                    // Vse co nenini ENUM je STRING
                    uVars.upsValueType=true;
                    uVars.upsVarMax=lenString;
                    }
                  uVars.upsVarType=false;
                  numberRWVars++;
                  }
                 break;
               case ERR:
                 error = upsTranslateError(value);
                 return error;
               default:
                 error=UnknownAnswer;
                 return error;
               }
             }
           else { return error; }
               listVars.push_back(uVars);
           numberVars++;
           }
          break;
        case END_LIST_VAR:
          break;
        case ERR:
          error = upsTranslateError(value);
          return error;
        default:
          error=UnknownAnswer;
          return error;
        } // end switch
      } // end while
    }
  else { return error; }
  // INSTANT COMMANDS

  inBuffer = "LIST CMD " + upsName + "\n";
  if (!(error=getUpsData (inBuffer,outBuffer,"END LIST CMD"))) {

    QString inLine, upsNameRet, varName, value;
    int key, typeValue;
    bool beginList = false;
//std::cout << "CMD Buffer " << outBuffer  << std::endl;
    
    QTextIStream varInputStream(&outBuffer);
    while (!(inLine = varInputStream.readLine()).isNull()) {
      key = parseLine (inLine, upsNameRet, varName, value, typeValue, lenString);
//std::cout << "CMD Line " << inLine  << std::endl;
      
      switch (key) {
        case BEGIN_LIST_CMD: {
          if (upsNameRet == upsName) beginList = true;
          break;
          }
        case CMD:
         if (beginList ) {
           // Zpracujeme polozku v tabulky
           uIComm.upsCommName=varName;
           uIComm.upsDescription="";
               listIComms.push_back(uIComm);
           numberIComms++;
           }
         break;
        case END_LIST_CMD:
          break;
        case ERR:
          error = upsTranslateError(value);
          return error;
        default:
          error=UnknownAnswer;
          return error;
        } // end switch
      } // end while
    }
  else { return error; }
  return 0;
  }



int KNutNet::getUpsValues1 (const bool allVars ) {// allVars = true vse; allVars = false jen activate
    QString endChar;
    QCString  inBuffer;
    QString  outBuffer;
    QValueVector<upsVar>::iterator it;
    
  // Nacte hodnotu promenych
  // reads value of variables
    
    
    emit getVarDesc (numberVars, 0);

    int numberVar  = 0;
    for (it = listVars.begin(); it != listVars.end(); it++) {
      numberVar++;
      if ((allVars) || ((*it).upsVarActivate)) {
        //nacteme promenou
        inBuffer = "REQ ";
        inBuffer.append((*it).upsVarName);
        if (!upsName.isEmpty()) { // pokud upsName neni je vzdy nastaveno na null
          inBuffer.append("@");
          inBuffer.append(upsName);
          }
        inBuffer.append("\n");
//        if (!(error=getUpsData (inBuffer,outBuffer))) {
        error=getUpsData (inBuffer,outBuffer);
        // when outBuffer is empty sends and reads date again, but only the only time
        if ((!(error)) && (outBuffer.isEmpty())) error=getUpsData (inBuffer,outBuffer);
        if (!(error)) {
          
          endChar = "";
          if ((outBuffer.length()>0) && (outBuffer.at(outBuffer.length()-2)==' ')) endChar=' ';
          
          outBuffer=outBuffer.stripWhiteSpace ();
          outBuffer += endChar;
          emit getVarDesc (numberVars, numberVar);

          if ( !outBuffer.isEmpty() ) {
            QTextIStream inputStream(&outBuffer);
            QString word1, word2, word3 ;
            inputStream >> word1;
            inputStream >> word2;
            if (inputStream.atEnd()) { // neexistuje treti cast VALUE
              if (word1 == "ERR") {
                // vracena chyba
                error=upsTranslateError(word2);
                return error;
                }
              else {
//                if ((word2 != "MODEL") && (word2 != "MFR")) {   
                if (endChar != " ") { // if values of variable is empty, string is ended on char space
                  error=UnknownFormat;
                  return error;
                  }
                }
              }
            inputStream >> word3;
            if (word1 == "ANS") {
              // answer - odpoved
              // odstranime pripadne jmeno upsky
              if ((posChar = word2.find('@')) != -1) word2 = word2.left(posChar);
              if ( word2 != (*it).upsVarName ) {
                error=UnknownAnswer;
                return error;// neni to odpoved na spravnou promenou
                }
              // test pro starsi format modulu vraceli chybu v hodnote promene
              if ((error=upsOldTranslateError(word3))) {
                return error;
                }
              // zalozime hodnotu do vectoru;
              (*it).upsValue=word3;
              if ((*it).upsVarName == "STATUS") {
                // dogenerujeme dalsi slova pro status
                word3 += inputStream.readLine();
                genStatusFlags(word3);
                }
              }
            else {
              // neznama odpoved - neni ANS ani ERR
              error=UnknownAnswer;
              return error;
              }
            }
          else {
	    error=NoData;
	    return error;
	    }
          }
        else {
	  return error;
	  }
        }
      }
    return 0;
  }



int KNutNet::getUpsValues2 (const bool allVars ) {// allVars = true vse; allVars = false jen activate
  QString varName;
  QString upsNameRet;
  QString value;
  int typeValue;
  int lenString;
  
  // reads value of variables
  QCString  inBuffer;
  QString  outBuffer;
  QValueVector<upsVar>::iterator it;
  emit getVarDesc (numberVars, 0);
   int numberVar  = 0;
  for (it = listVars.begin(); it != listVars.end(); it++) {
    numberVar++;
    if ((allVars) || ((*it).upsVarActivate)) {
      //reads variable
      inBuffer = "GET VAR "+upsName+" "+(*it).upsVarName+"\n";
//      if (!(error=getUpsData (inBuffer,outBuffer))) {
      error=getUpsData (inBuffer,outBuffer);
      // when outBuffer is empty sends and reads date again, but only the only time
      if ((!(error))  &&  (outBuffer.isEmpty())) error=getUpsData (inBuffer,outBuffer);
      if (!(error)) {
        outBuffer=outBuffer.stripWhiteSpace ();
        emit getVarDesc (numberVars, numberVar);
        if ( !outBuffer.isEmpty() ) {
          int key = parseLine(outBuffer, upsNameRet, varName, value, typeValue, lenString);
          switch (key) {
            case VAR:
              if ( varName != (*it).upsVarName ) {
                error=UnknownAnswer;
                return error;// it isn't answer for right variable - neni to odpoved na spravnou promenou
                }
              (*it).upsValue=value;
              if ((((*it).upsVarName == "STATUS") && (nutVariables == 1)) || (((*it).upsVarName == "ups.status") && (nutVariables == 2))) {
                // dogenerujeme dalsi slova pro status
                genStatusFlags(value);
                }
              break;  
            case ERR:
              error=upsTranslateError(value);
              return error;
            default:
              error=UnknownAnswer;
              return error;
            }
          }
        else {
          error= NoData;
          return error;
          }
        }
      else {
        return error;
        }
      }
    }
  return 0;
  }


int KNutNet::sendComm (const QString command, const QString arg1, const QString arg2, const bool useUpsName) {
  int localError;
// nenastavi promenou error ale nenuluje ji
  QCString inBuffer;
  QString outBuffer;

  switch (nutProtocol) {
    case 1:
      inBuffer=command + " " + arg1;
      if (useUpsName && (!upsName.isEmpty())) // pokud upsName neni je vzdy prazdne
        inBuffer += "@"+upsName;
   if (!arg2.isEmpty()) inBuffer += " " + arg2;
    break;
    case 2:
    inBuffer = command + " ";
    if (useUpsName) inBuffer += upsName + " ";
    inBuffer.append(arg1);
   if (!arg2.isEmpty()) inBuffer += " \"" + arg2 +"\"";
   break;
    }
  inBuffer.append("\n");
  
  if (!(localError=getUpsData (inBuffer,outBuffer))) {
    outBuffer=outBuffer=outBuffer.stripWhiteSpace ();
    QTextIStream inputStream(&outBuffer);
    QString word1, word2;
    inputStream >> word1;
    inputStream >> word2;
    if (word1.isEmpty()) return UnknownAnswer; // zadna odpoved
    if (word1 != "OK") {
      // neni rovno OK
      if (word1 == "ERR") return upsTranslateError (word2);
      else return UnknownAnswer;
      }
    else return 0;
    }
  else return localError;
  }
  

int KNutNet::activate ( const QString name, const bool setActivate  ) {
  error =0;
  if (state == Connected) {
    QValueVector<upsVar>::iterator it;
    for (it = listVars.begin(); it != listVars.end(); it++) {
      if ((*it).upsVarName == name) {
        (*it).upsVarActivate = setActivate;
        return 0;
        }
      }
    error = VarNotFind;
    return error;
    }
  else return NotConnection;
  }

int KNutNet::activateAll ( const bool setActivate  ) {
  error =0;
  if (state == Connected) {
    QValueVector<upsVar>::iterator it;
    for (it = listVars.begin(); it != listVars.end(); it++) {
      (*it).upsVarActivate = setActivate;
      }
    return 0;
    }
  else return NotConnection;
  }

  
int KNutNet::upsTranslateError (const QString string) {
  if (string == "VAR-NOT-SUPPORTED") return VarNotSupported;
  if (string == "VAR-UNKNOWN") return VarUnknown;

  if (string == "ACCESS-DENIED") return AccessDenied;
  if (string == "PASSWORD-REQUIRED") return PasswordRequired;
  if (string == "PASSWORD-INCORRECT") return PasswordIncorrect;
  if (string == "UNKNOWN-UPS") return UnknownUps;
  if (string == "ALREADY-LOGGED_IN") return AlreadyLoggedIn;
  if (string == "ALREADY-SET-PASSWORD") return AlreadySetPassword;
  if (string == "UNKNOWN-COMMAND") return UnknownCommand;

  if (string == "UNKNOWN-INSTCMD") return UnknownInstCmd;
  if (string == "CMD-NOT-SUPPORTED") return CmdNotSupported;

  if (string == "INVALID-VALUE") return InvalidValue;

  if (string == "NO-RESPONSE") return NoResponse;
  if (string == "UNKNOWN-REPLY") return UnknownReply;
  if (string == "NOT-IMPLEMENTED") return NotImplemented;
  if (string == "COMMAND-FAILED") return CommandFailed;

  if (string == "MISSING-ARGUMENT") return MissingArgument;
  if (string == "DATA-STALE") return DataStale;
  if (string == "UNKNOWN-TYPE") return UnknownType;

  if (string == "DRIVER-NOT-CONNECTED") return DriverNotConnected;

  if (string == "") return UnknownFormat;
  
  return UnknownErr;
  }

int KNutNet::upsOldTranslateError (const QString string) {
  if (string == "NOT-SUPPORTED") return VarNotSupported;
  if (string == "UNKNOWN") return VarUnknown;
  if (string == "DATA-STALE") return DataStale;
  return 0; // nebylo nalezeno
  }

//--------------------Socket----------------


void KNutNet::slotConnectionError(int error) {
//std::cout << "--KNutNet::slotConnectionError"  << std::endl;

  
  state = ConnectError;
  unConnectTimer->stop();
  if (error == QSocket::ErrHostNotFound) {
    error = NoSuchHost;
 //   std::cout << "--KNutNet::QSocket::ErrHostNotFound " << error << std::endl;
    emit connectionError(error);
    return;
    }
                        //connection was refused                                  //  no connection
  if ((error == QSocket::ErrConnectionRefused) && (commandSocket->state()==QSocket::Idle)) {
    if (firstConnect) {
      if (numberConnection < countRepeat) {
        numberConnection++;
    //std::cout << "--KNutNet:: connect error - try connect on next time" << std::endl;
        unConnectTimer->start( delay, TRUE );
        }
      else  {
        // i don't connect server
        error=CantConnect;
//        std::cout << "--KNutNet::emit - connection error " << error << std::endl;
        emit connectionError(error);
        return;
        }
      } // end of if (firstConnection)
    else {
      // connecting is down, try repeated connection
      
//    std::cout << "--KNutNet::no first connect connection error " << error << std::endl;
      unConnectTimer->start( delay, TRUE );
      }
    return;  
    }
  if (error == QSocket::ErrConnectionRefused) {
    error = ConnectionRefused;
//    std::cout << "--KNutNet::connection error ErrConnectionRefused " << error << std::endl;
    emit connectionError(error);
    return;
    }
  if (error ==   QSocket::ErrSocketRead) {
    error = SocketReadErr;
//    std::cout << "--KNutNet::connection error QSocket::ErrSocketRead " << error << std::endl;
    emit connectionError(error);
    return;
    }
  }


void KNutNet::slotConnected(void) {
//std::cout << "--KNutNet::slotConnected"  << std::endl;
  int n;

    if ((n = version (countRepeat, delay)) == 0) { // 0 OK, 0> error
      if ((nutProtocol == 0) || (nutVariables == 0)) { // answer from upsd (VER) is unknown
        error=NutProtocolVarErr;
        state = Closing;
        commandSocket->close();
        while (commandSocket->state() == QSocket::Closing) {
          sleep (100);
          }
        state = ConnectError;

        return;
        }
      if ((nutProtocol == 2) && upsName.isEmpty()) {
      // if upsName is empty reads first ups name from upsd server 
        if ((error =KNutNet::getFirstUpsName (upsName))) { // reading first upsName
          // upsd server doesn't support any ups
          state = Closing;
          commandSocket->close();
          while (commandSocket->state() == QSocket::Closing) {
            sleep (100);
            }
          state = ConnectError;
          
          }
        }
        state=Connected;
      } 
    else {
        commandSocket->close();
      }
    emit firstConnection();      
//  std::cout << "KNutNet::emit - firstConnection" << std::endl;
  }

void KNutNet::slotHostFound(void) {
  
//  std::cout << "--KNutNet::slotHostFound"  << std::endl;
  state = Connecting;
  emit hostFound();
  }  
  

void KNutNet::slotConnectionClosed(void) {
  
//  std::cout << "--KNutNet::slotConnectionClosed" << std::endl;
  
  unConnectTimer->stop();
  deleteVars();
  state = Idle;
  emit connectionClosed();
  }


    
void KNutNet::slotTimerReconnect(void) {
//  std::cout << "--KNutNet::slotTimerReconnect"  << std::endl;

 unConnectTimer->stop();
  if (commandSocket->state()==QSocket::Idle) {
  //std::cout << "--KNutNet::slotTimerReconnect QSOcket::Idle" << std::endl;
     emit tryRepeatFirstConnection(numberConnection);
   //  std::cout << "KNutNet::emit-tryRepeatFirstConnection" << std::endl;
    state=Connecting;
    if ( commandSocket->state() != QSocket::Connecting )
      commandSocket->connectToHost(upsAddress,port);
    }
  }
  

#include "knutnet.moc"


syntax highlighted by Code2HTML, v. 0.9.1