/*************************************************************************** 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 #include #include #include #include // for function sleep //#include /****** CONSTS ***********/ //const TQ_ULONG rBufferLen = 1024; KNutNet::KNutNet (const TQString upsAddress, const TQString upsName, const unsigned short port, unsigned int countRepeat, const unsigned int delay) : TQObject(), m_upsAddress(upsAddress), m_upsName(upsName), m_countRepeat(countRepeat), m_port(port), m_delay(delay) { //tqDebug ("KNutNet::KNutNet"); m_state = Idle; //idle is value m_numberVars = 0; m_numberRWVars = 0; m_numberIComms = 0; m_upsStatusVar = 0; m_nutProtocol = 0; m_nutVariables = 0; m_switchToTCP = false; m_description = false; // popis neni natazen - description is not loaded m_unConnectTimer = new TQTimer( this ); connect( m_unConnectTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotTimerReconnect()) ); m_error = NoError; m_commandSocket = new TQSocket( this ); connect( m_commandSocket, TQT_SIGNAL( hostFound()),this, TQT_SLOT( slotHostFound())); connect( m_commandSocket, TQT_SIGNAL( connected()),this,TQT_SLOT( slotConnected())); connect( m_commandSocket, TQT_SIGNAL( connectionClosed()),this, TQT_SLOT( slotConnectionClosed())); connect( m_commandSocket, TQT_SIGNAL( error(int)),this, TQT_SLOT( slotConnectionError(int))); } KNutNet::~KNutNet(){ TQCString inBuffer; TQString outBuffer; close(); // close connetion when is existed while (m_state == Closing ) { sleep (100); } // deleteVars() is made in close(); } void KNutNet::close (void) { // std::cout << "--KNutNet::close" << std::endl; TQCString inBuffer; TQString outBuffer; m_unConnectTimer->stop(); deleteVars(); if ((m_state == Connected) || (m_state == Connecting)) { m_state = Closing; if (m_state == Connected) { inBuffer="LOGOUT\n"; getUpsData (inBuffer,outBuffer); // getUpsDate makes "commandSocket->flush()" } if (m_commandSocket->bytesToWrite () > 0) sleep (1000); m_commandSocket->clearPendingData (); // data in output buffer will be errased m_commandSocket->close(); // closes the socket if ( m_commandSocket->state() == TQSocket::Closing ) { connect( m_commandSocket, TQT_SIGNAL(delayedCloseFinished()),this,TQT_SLOT(slotClosed()) ); } else { slotClosed(); } } } void KNutNet::slotClosed (void) { disconnect( m_commandSocket,TQT_SIGNAL(delayedCloseFinished()),this, TQT_SLOT(slotClosed()) ); m_state = Idle; } void KNutNet::open (void) { TQCString inBuffer; TQString outBuffer; if ((m_state == Connected) || (m_state == Connecting)) close(); // close connetion when is existed else { while (m_state == Closing ) { sleep (100); } } if (m_upsAddress != "") { if ( m_commandSocket->state() != TQSocket::Connecting ) { m_firstConnect=true; m_numberConnection=0; m_state = HostLookup; emit tryFirstConnection(m_countRepeat); // how many times we can try to connect with ups server /upsd/ // std::cout << "--KNutNet :: Open emit - tryFirstConnection" << std::endl; m_commandSocket->connectToHost(m_upsAddress,m_port); } } } void KNutNet::newUPS (const TQString upsAddress, const TQString upsName, const unsigned short port) { if ((m_state == Connected) || (m_state == Connecting)) { close(); while (m_state == Closing ) { sleep (100); } } m_upsAddress = upsAddress; m_upsName = upsName; m_port = port; m_state = Idle; m_numberVars = 0; m_numberRWVars = 0; m_numberIComms = 0; m_upsStatusVar = 0; m_nutProtocol = 0; m_nutVariables = 0; m_switchToTCP = false; m_error = NoError; //firstConnect=true; //numberConnection=0; } int KNutNet::getError ( void ) { return m_error; } int KNutNet::getState ( void ){ return m_state; } bool KNutNet::isDescription ( void ){ return m_description; } int KNutNet::getNutProtocol ( void ) { return m_nutProtocol; } int KNutNet::getNutVariables ( void ) { return m_nutVariables; } bool KNutNet::switchedToTCP ( void ) { return m_switchToTCP; } int KNutNet::getUpsVars ( void) { int returnValue; m_error=0; if (m_state == Connected) { // init vars and lists m_numberVars = 0; m_numberRWVars = 0; m_numberIComms = 0; deleteVars(); int countWaitRevision = 5; do { switch (m_nutProtocol) { case 1: returnValue = getUpsVars1(); break; case 2: returnValue = getUpsVars2(); break; default: return 0; } if ( readStatus() != KNutNet::WAIT) return returnValue; countWaitRevision--; if (countWaitRevision) sleep (2); } while (countWaitRevision); return NoListVars; //getUpsVars can't read list variables } else { return NotConnection; } } int KNutNet::getUpsValues (const bool allVars ) {// allVars = true vse; allVars = false jen activate m_error=0; // vynulujeme chyby if (m_state == Connected) { // init vars and lists switch (m_nutProtocol) { case 1: return getUpsValues1(allVars); break; case 2: return getUpsValues2(allVars); break; default: return 0; } } else { return NotConnection; } } int KNutNet::getDescription (bool always) { m_error=0; // vynulujeme chyby if (m_state == Connected) { switch (m_nutProtocol) { case 1: return getDescription1 (always); break; case 2: return getDescription2 (always); break; default: return 0; } } else return NotConnection; } int KNutNet::instantCommand (const TQString command, const TQString userName, const TQString password, const bool onlyCommand) { m_error=0; // vynulujeme chyby if (m_state == Connected) { TQString outBuffer; // funkce sendComm sama mastavi promenou error if (onlyCommand) { if (!(m_error = sendComm("INSTCMD", command, "",true))) { // netMutex=false; return 0; } else { // netMutex=false; return m_error; } } else { if (!(m_error = sendComm ("USERNAME", userName, ""))) { if (!(m_error = sendComm("PASSWORD", password, ""))) { if (!(m_error = sendComm("INSTCMD", command, "",true))) { // netMutex=false; return 0; } else { return m_error; // spatny prikaz } } //username else { return m_error; //spatne helso } } else { return m_error; // spatne jmeno } } } else return NotConnection; } int KNutNet::setVariable (const TQString variable, const TQString value, const TQString userName, const TQString password, const bool onlyVariable) { m_error=0; // vynulujeme chyby if (m_state == Connected) { TQString outBuffer; TQString setCommand; switch (m_nutProtocol) { case 1: setCommand = "SET"; break; case 2: setCommand = "SET VAR"; } if (onlyVariable) { if (!(m_error = sendComm(setCommand, variable, value, true))) { return 0; } else { return m_error; } } else { if (!(m_error = sendComm ("USERNAME", userName, ""))) { if (!(m_error = sendComm("PASSWORD", password, ""))) { if (!(m_error = sendComm(setCommand, variable, value, true))) { //netMutex=false; return 0; } else { return m_error; } } //username else { return m_error; } } else { return m_error; } } } else return NotConnection; } int KNutNet::readNumberVars (typeOfVar typVar) { // Vraci pocet promenych m_error=0; if (m_state == Connected) { switch (typVar) { case AllVars: return m_numberVars; break; case ROVars: return m_numberVars - m_numberRWVars; break; case RWVars: return m_numberRWVars; break; default: return -1; } } else return -1; } int KNutNet::readNumberComms (void) { // Vraci pocet prikazu m_error=0; if (m_state == Connected) return m_numberIComms; else return -1; } int KNutNet::readIComm (const int seqNumber, upsICommDef& upsIComm) { m_error =0; if (m_state == Connected) { if ((seqNumber < 1) || ((unsigned int)seqNumber > m_listIComms.size())) { m_error=CommNotFind; return m_error; } upsIComm = m_listIComms[seqNumber-1]; return 0; } else return NotConnection; } int KNutNet::readVars (const TQString name, struct upsVarDef& allVar) { m_error =0; if (m_state == Connected) { TQValueVector::const_iterator it; for (it = m_listVars.begin(); it != m_listVars.end(); it++) { if ((*it).upsVarName == name) { allVar = (*it); return 0; } } m_error=VarNotFind; return m_error; } else return NotConnection; } int KNutNet::readVars (const int seqNumber, struct upsVarDef& allVar, const typeOfVar typVar) { m_error =0; if (m_state == Connected) { int n = 1; TQValueVector::const_iterator it; for (it = m_listVars.begin(); it != m_listVars.end(); it++) { if ((typVar== AllVars) || ((typVar==ROVars) && ((*it).upsVarType)) || ((typVar==RWVars) && (!(*it).upsVarType))) { if (n == seqNumber) { allVar = (*it); return 0; } n++; } } m_error=VarNotFind; return m_error; } else return NotConnection; } TQString KNutNet::readStringVar (const TQString name) { m_error =0; if (m_state == Connected) { TQValueVector::const_iterator it; for (it = m_listVars.begin(); it != m_listVars.end(); it++) { if ((*it).upsVarName == name) return (*it).upsValue; } m_error = VarNotFind; return 0l; } else return 0l; } TQString KNutNet::readEnumValueVar (const TQString name, const int valueNumber) { m_error =0; if (m_state == Connected) { // #if defined (TDE_VERSION_MAJOR) // #if TDE_VERSION_MAJOR >= 3 TQValueVector::const_iterator it; // #else // TQValueList::ConstIterator it; // #endif // #else // TQValueList::ConstIterator it; // #endif for (it = m_listVars.begin(); it != m_listVars.end(); it++) { if ((*it).upsVarName == name) { if ((valueNumber < 1) || (valueNumber > (*it).upsVarMax)) { m_error=EnumValueNotFind; return 0l; } // vratime hodnotu return (*(*it).upsEnumValues)[valueNumber-1]; } } m_error = VarNotFind; return 0; } else return 0; } int KNutNet::readStatus(void) { m_error=0; return m_upsStatusVar; } int KNutNet::setActivate ( const TQString name ) { return activate (name,true); } int KNutNet::unSetActivate ( const TQString name ) { return activate (name,false); } int KNutNet::unSetActivateAll ( void ) { return activateAll (false); } int KNutNet::existName ( const TQString name ) { m_error =0; if (m_state == Connected) { TQValueVector::const_iterator it; for (it = m_listVars.begin(); it != m_listVars.end(); it++) { if ((*it).upsVarName == name) return 0; } m_error = VarNotFind; return m_error; } else return NotConnection; } /*************************************************************************/ /* */ /* PRIVATE FUNCTIONS */ /* */ /*************************************************************************/ int KNutNet::version (int countRepeat, const int delay) { TQCString inBuffer; TQString outBuffer; m_error =0; do { inBuffer="VER\n"; if (!(m_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) { TQString firstNumber= outBuffer.left(n); TQString 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) {m_error = UnknownFormatVer; return m_error;} int firstInt = firstNumber.toInt(&ok); if (!ok) {m_error = UnknownFormatVer; return m_error;} if ((firstInt == 0) || ((firstInt == 1) && (secondInt < 3))) { m_nutProtocol =1; m_nutVariables =1; } else { m_nutProtocol =2; m_nutVariables =2; } return 0; } else m_error = UnknownFormatVer; // n is <= 0 the second dot } else m_error = UnknownFormatVer; // n is <= 0 the first dot } m_error = UnknownAnswer; // i cannot specify number of protocol and number of variables return m_error; } countRepeat--; if (countRepeat) sleep (delay); } while ((countRepeat)); return m_error; } int KNutNet::getFirstUpsName (TQString& firstUpsName) { TQCString inBuffer; TQString outBuffer; TQString varOutBuffer; int lenString; m_error=0; inBuffer = "LIST UPS\n"; if (!(m_error=getUpsData (inBuffer,outBuffer,"END LIST UPS"))) { TQString inLine, upsNameRet, varName, value; int key, typeValue; bool beginList = false; TQTextIStream 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 = ""; m_error=NoUpsHere; return m_error; case ERR: m_error = upsTranslateError(value); return m_error; default: m_error=UnknownAnswer; return m_error; } }// end while } else {m_error=NoData; return m_error; } return 0; } int KNutNet::setKey (const TQString line) { TQString 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; } TQString KNutNet::parseValue (const TQString line) { if (line.isEmpty()) return ""; if (line[0] != "\"") { if ((m_posChar=line.find(' ')) == -1) return line; else return line.left(m_posChar+1); } else { int len = line.length(); TQString outString = ""; for (int i=1; i < len; i++) { if ( line[i] == "\\") { if ((i+1) > 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(TQString& line, TQString& upsName ,TQString& varName, TQString& value, int& typeValue, int& lenString) { int posChar; TQString 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 TQCString inBuffer, TQString& upsDescription) { TQString outBuffer; if (!(m_error=getUpsData (inBuffer,outBuffer))) { outBuffer=outBuffer.stripWhiteSpace (); TQString word1, word2, word3; if ((m_posChar = outBuffer.find(' ')) == -1) word1 = outBuffer; else { word1 = outBuffer.left(m_posChar); word2 = outBuffer.mid(m_posChar+1); } if (word1 == "DESC") { if ((m_posChar = word2.find('\"')) == -1) word3=""; else { word3 = word2.mid(m_posChar+1); if ((m_posChar = word3.find('\"')) != -1) word3=word3.left(m_posChar); } if (!word3.isEmpty()) upsDescription=word3; } else { if (word1 == "ERR" ) return upsTranslateError(word2); else return UnknownAnswer; } } else return m_error; return 0; } void KNutNet::cleanConnecting (void) { TQ_ULONG rMaxLen; TQCString recvBuffer(rBufferLen); TQ_LONG lengthInputData; int n = 0; while (m_commandSocket->bytesAvailable() > 0) { if ( (m_commandSocket->bytesAvailable()+1) > rBufferLen) rMaxLen = rBufferLen; else rMaxLen=m_commandSocket->bytesAvailable()+1; recvBuffer.resize(rMaxLen); if ((lengthInputData = m_commandSocket->readBlock(recvBuffer.data(),rMaxLen)) == -1) { } if (lengthInputData == 0) break; if (n > 20) break; else n++; } } int KNutNet::getUpsData (const TQCString sBuffer, TQString& rBuffer, const TQCString endString) { //rbufferLen a sbufferLen are maximal value of buffers TQCString recvBuffer(rBufferLen); TQ_LONG lengthInputData; TQ_ULONG dataAvailable; TQMutexLocker getUpsDataLocker( &m_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 (m_commandSocket->writeBlock(sBuffer.data(),sBuffer.length()) < 0 ) return SendErr; m_commandSocket->flush(); if (m_commandSocket->waitForMore(1000) == 0) { m_commandSocket->waitForMore(500); // workaround } bool endRecv = false; do { dataAvailable=m_commandSocket->bytesAvailable(); if (recvBuffer.size() < (dataAvailable+1) ) recvBuffer.resize(dataAvailable+1); if ((lengthInputData = m_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 environment is TQ_LONG defined like _int64 and //for other environments is TQ_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.data()) == -1) { //doesn't find right end of input data if (m_commandSocket->bytesAvailable() == 0) m_commandSocket->waitForMore(1000); if (m_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 TQString varName, const bool valueType, const int varMax, TQValueVector* enumValues) { TQValueVector::iterator it; for (it = m_listVars.begin(); it != m_listVars.end(); it++) { if ((*it).upsVarName == varName) { (*it).upsVarMax = varMax; (*it).upsValueType=valueType; (*it).upsEnumValues=enumValues; (*it).upsVarType=false; break; } } } void KNutNet::upsSetType (struct upsVarDef& upsVar, const TQString name, const TQString value) { if (((m_nutVariables = 2) && (name == "STATUS")) || ((m_nutVariables = 2) && (name == "ups.status"))) upsVar.upsVarActivate=true; else upsVar.upsVarActivate=false; upsVar.upsVarName = name; upsVar.upsVarType=true; upsVar.upsValueType=true; upsVar.upsVarMax=0; upsVar.upsValue=value; upsVar.upsDescription=""; upsVar.upsEnumValues=0L; } void KNutNet::deleteVars (void) { // #if defined (TDE_VERSION_MAJOR) // #if TDE_VERSION_MAJOR >= 3 TQValueVector::iterator it; // #else // TQValueList::Iterator it; // #endif // #else // TQValueList::Iterator it; // #endif for (it = m_listVars.begin(); it != m_listVars.end(); it++) { if ((*it).upsEnumValues != 0) { (*it).upsEnumValues->clear(); delete (*it).upsEnumValues; } } m_listVars.clear(); m_listIComms.clear(); } void KNutNet::genStatusFlags (TQString value) { m_upsStatusVar = 0; TQTextIStream inputStream(&value); TQString word; while (!inputStream.atEnd()) { inputStream >> word; if (word == "OFF") m_upsStatusVar +=OFF; if (word == "OL") m_upsStatusVar +=OL; if (word == "OB") m_upsStatusVar +=OB; if (word == "LB") m_upsStatusVar +=LB; if (word == "CAL") m_upsStatusVar +=CAL; if (word == "TRIM") m_upsStatusVar +=TRIM; if (word == "BOOST") m_upsStatusVar +=BOOST; if (word == "OVER") m_upsStatusVar +=OVER; if (word == "RB") m_upsStatusVar +=RB; if (word == "WAIT") m_upsStatusVar = WAIT; //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 //WAIT - 512 ups zada o strpeni // UPS asks for waiting } } int KNutNet::getDescription1 (bool always) { if (always || (! m_description)) { TQCString inBuffer; TQString outBuffer; TQValueVector::iterator itv; TQValueVector::iterator itc; for (itv = m_listVars.begin(); itv != m_listVars.end(); itv++) { //nacteme promenou inBuffer = "VARDESC " + (*itv).upsVarName + "\n"; if ((m_error = newDescription (inBuffer, (*itv).upsDescription))) { //netMutex.unlock(); // netMutex=false; return m_error; } } for (itc = m_listIComms.begin(); itc != m_listIComms.end(); itc++) { //nacteme promenou inBuffer = "INSTCMDDESC "+(*itc).upsCommName+"\n"; if ((m_error = newDescription (inBuffer, (*itc).upsDescription))) { //netMutex.unlock(); //netMutex=false; return m_error; } } //netMutex=false; m_description = true; } return 0; } int KNutNet::getDescription2 (bool always) { if (always || (! m_description)) { TQCString inBuffer; TQString outBuffer; TQString upsNameRet; TQString varName; TQString value; int typeValue; int lenString; TQValueVector::iterator itv; TQValueVector::iterator itc; for (itv = m_listVars.begin(); itv != m_listVars.end(); itv++) { //nacteme promenou inBuffer = "GET DESC " + m_upsName + " " + (*itv).upsVarName+"\n"; if (!(m_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: m_error=upsTranslateError(value); return m_error; default: m_error=UnknownAnswer; return m_error; } } else { m_error = NoData; return m_error; } } else { return m_error; } } for (itc = m_listIComms.begin(); itc != m_listIComms.end(); itc++) { //nacteme promenou inBuffer = "GET CMDDESC " + m_upsName + " " + (*itc).upsCommName+"\n"; if (!(m_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: m_error=upsTranslateError(value); return m_error; default: m_error=UnknownAnswer; return m_error; } } else { m_error = NoData; return m_error; } } else { return m_error; } } m_description = true; } return 0; } int KNutNet::getUpsVars1 ( void) { // getUpsVars nacte promene a jejich typ // vraci kod chyby nebo 0 pokud je vse v poradku TQCString inBuffer; TQString outBuffer; TQString varOutBuffer; upsVarDef upsVar; upsICommDef upsIComm; // init vars and lists if (!m_upsName.isEmpty()) { // pokud upsName neni je vzdy nastaveno na null inBuffer="LISTVARS "; inBuffer.append(m_upsName); inBuffer.append("\n"); } else inBuffer ="LISTVARS\n"; if (!(m_error=getUpsData (inBuffer,outBuffer))) { outBuffer=outBuffer.stripWhiteSpace (); if (outBuffer.length() > 0) { // precteme data TQTextIStream inputStream(&outBuffer); TQString 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; m_error = upsTranslateError(word); } else m_error=UnknownAnswer; return m_error; } break; case 2: count++; if ((word.length() > 0) && word.startsWith("@")) break; default: // pridame polozku do tabulky upsSetType(upsVar, word); m_listVars.push_back(upsVar); m_numberVars++; break; } } } else { m_error=NoData; return m_error; } } else return m_error; if ((m_error = getUpsValues1(true))) return m_error; // *********** RW VARIABLES if (!m_upsName.isEmpty()) { // pokud upsName neni je vzdy nastaveno na null inBuffer="LISTRW "; inBuffer.append(m_upsName); inBuffer.append("\n"); } else inBuffer ="LISTRW\n"; if (!(m_error=getUpsData (inBuffer,outBuffer))) { outBuffer=outBuffer.stripWhiteSpace(); if (!outBuffer.isEmpty()) { // precteme data TQTextIStream inputStream(&outBuffer); TQString 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; m_error = upsTranslateError(word); } else m_error=UnknownAnswer; return m_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 (!m_upsName.isEmpty()) { inBuffer.append("@"); // pokud upsName neni je vzdy nastaveno na null inBuffer.append(m_upsName); } inBuffer.append("\n"); if (!(m_error=getUpsData (inBuffer,varOutBuffer))) { varOutBuffer=varOutBuffer.stripWhiteSpace(); if ( !outBuffer.isEmpty() ) { TQTextIStream varInputStream(&varOutBuffer); TQString word1, word2, word3; varInputStream >> word1; varInputStream >> word2; varInputStream >> word3; if (word1 == "TYPE") { if ((word2.isEmpty()) || (word3.isEmpty())) { m_error=UnknownFormat; return m_error; } if (word2 == "ENUM") valueType=false; else { if (word2 =="STRING") valueType=true; else { m_error=UnknownFormat; return m_error; } } bool ok = true; varMax=word3.toInt(&ok); if (!ok) {m_error=UnknownFormat; return m_error;}; } // word1 = Type else { if (word1=="ERR") { m_error = upsTranslateError(word2); return m_error; } else { m_error = UnknownAnswer; return m_error; } } } else { m_error=NoData; return m_error; } } else return m_error; // ********** ENUM / STRING ****************** TQValueVector* enumString=0; if (!valueType) { // nacteme enum hodnoty inBuffer="ENUM "; inBuffer.append(word); // pokud existuje pridame jmeno UPS-ky if (!m_upsName.isEmpty()) { inBuffer.append("@"); inBuffer.append(m_upsName); } inBuffer.append("\n"); if (!(m_error=getUpsData (inBuffer,varOutBuffer,"END\n"))) { // varOutBuffer.stripWhiteSpace(); nemuze provest protoze bychom si odstranili konce radek if (!varOutBuffer.isEmpty()) { TQString inLine, word1, word2; TQTextIStream varInputStream(&varOutBuffer); int inCountLine=1; while (!(inLine = varInputStream.readLine()).isNull()) { inLine=inLine.stripWhiteSpace(); if ((m_posChar=inLine.find(' ')) == -1) word1=inLine; else { word1=inLine.left(m_posChar); inLine = inLine.mid(m_posChar+1); } if (word1.isEmpty()) { m_error = UnknownFormat; return m_error; } if (inCountLine == 1) { if ((m_posChar=inLine.find(' ')) == -1) word2=inLine; else word2=inLine.left(m_posChar); if (word1 =="ENUM") { if (word2 != word) { m_error = UnknownFormat; return m_error; } varMax=0; inCountLine++; enumString = new TQValueVector; enumString->clear(); } else { if (word1=="ERR") m_error=upsTranslateError(word2); // prevede chybu na jeji kod else m_error=UnknownAnswer; return m_error; } } else { if (word1 == "END") break; if (word1 != "OPTION") { m_error = UnknownFormat; return m_error; } if ((m_posChar = inLine.find('\"')) == -1) word2 = ""; else { word2 = inLine.mid(m_posChar+1); if ((m_posChar=word2.find('\"')) != -1) word2 = word2.left(m_posChar); } enumString->push_back(word2); varMax++; } } // end while } // buffer is not empty else { m_error = NoData ; return m_error; } } // getUpsData else return m_error; } // type of var else enumString = 0l; // nacteme stringovou promenou // ulozime promene setRWVars (word,valueType,varMax,enumString); m_numberRWVars++; break; } } // end while (!inputStream.atEnd()) } else { m_error = NoData ; return m_error; } } else return m_error; // *************** INSTANT COMMAND if (!m_upsName.isEmpty()) { // pokud upsName neni je vzdy nastaveno na null inBuffer="LISTINSTCMD "; inBuffer.append(m_upsName); inBuffer.append("\n"); } else inBuffer ="LISTINSTCMD\n"; if (!(m_error=getUpsData (inBuffer,outBuffer))) { outBuffer=outBuffer.stripWhiteSpace (); if ( !outBuffer.isEmpty() ) { // precteme data TQTextIStream inputStream(&outBuffer); TQString 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; m_error = upsTranslateError(word); } else m_error=UnknownAnswer; return m_error; } break; case 2: count++; if ((word.length() > 0) && word.startsWith("@")) break; default: // Zpracujeme polozku v tabulky upsIComm.upsCommName=word; upsIComm.upsDescription=""; m_listIComms.push_back(upsIComm); m_numberIComms++; break; } } } else { m_error=NoData; return m_error; } } else return m_error; return 0; } int KNutNet::getUpsVars2 ( void) { TQCString inBuffer; TQString outBuffer; TQString varOutBuffer; upsVarDef upsVar; upsICommDef upsIComm; int key; int typeValue; int lenString; int varMax=0; TQValueVector* enumString=0; inBuffer = "LIST VAR " + m_upsName + "\n"; if (!(m_error=getUpsData (inBuffer,outBuffer,"END LIST VAR"))) { TQString inLine, upsNameRet, varName, varNameRet, value; bool beginList = false; TQTextIStream varInputStream(&outBuffer); while (!(inLine = varInputStream.readLine()).isNull()) { key = parseLine (inLine, upsNameRet, varName, value, typeValue, lenString); switch (key) { case BEGIN_LIST_VAR: if (upsNameRet == m_upsName) beginList = true; break; case VAR: if (beginList ) { upsSetType(upsVar, varName, value); if (varName == "ups.status") genStatusFlags(value); inBuffer = "GET TYPE " + m_upsName + " " + varName +"\n"; if (!(m_error=getUpsData (inBuffer,varOutBuffer))) { key = parseLine (varOutBuffer, upsNameRet, varNameRet, value, typeValue, lenString); switch (key) { case TYPE: if (typeValue & RW_FLAG) { upsVar.upsVarMax = 0; upsVar.upsEnumValues=0L; if (typeValue & ENUM_FLAG) { upsVar.upsValueType=false; // nacteme enumValues inBuffer = "LIST ENUM " + m_upsName + " " + varName +"\n"; if (!(m_error=getUpsData (inBuffer,varOutBuffer,"END LIST ENUM"))) { bool beginEnumList = false; TQTextIStream 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 TQValueVector; enumString->clear(); upsVar.upsEnumValues=enumString; break; case ENUM: if (beginList ) { enumString->push_back(value); varMax++; } break; case ERR: m_error = upsTranslateError(value); return m_error; default: m_error=UnknownAnswer; return m_error; case END_LIST_ENUM: upsVar.upsVarMax=varMax; break; } } } } else { // Vse co nenini ENUM je STRING upsVar.upsValueType=true; upsVar.upsVarMax=lenString; } upsVar.upsVarType=false; m_numberRWVars++; } break; case ERR: m_error = upsTranslateError(value); return m_error; default: m_error=UnknownAnswer; return m_error; } } else { return m_error; } m_listVars.push_back(upsVar); m_numberVars++; } break; case END_LIST_VAR: break; case ERR: m_error = upsTranslateError(value); return m_error; default: m_error=UnknownAnswer; return m_error; } // end switch } // end while } else { return m_error; } // INSTANT COMMANDS inBuffer = "LIST CMD " + m_upsName + "\n"; if (!(m_error=getUpsData (inBuffer,outBuffer,"END LIST CMD"))) { TQString inLine, upsNameRet, varName, value; int key, typeValue; bool beginList = false; //std::cout << "CMD Buffer " << outBuffer << std::endl; TQTextIStream 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 == m_upsName) beginList = true; break; } case CMD: if (beginList ) { // Zpracujeme polozku v tabulky upsIComm.upsCommName=varName; upsIComm.upsDescription=""; m_listIComms.push_back(upsIComm); m_numberIComms++; } break; case END_LIST_CMD: break; case ERR: m_error = upsTranslateError(value); return m_error; default: m_error=UnknownAnswer; return m_error; } // end switch } // end while } else { return m_error; } return 0; } int KNutNet::getUpsValues1 (const bool allVars ) {// allVars = true vse; allVars = false jen activate TQString endChar; TQCString inBuffer; TQString outBuffer; TQValueVector::iterator it; // Nacte hodnotu promenych // reads value of variables emit getVarDesc (m_numberVars, 0); int numberVar = 0; for (it = m_listVars.begin(); it != m_listVars.end(); it++) { numberVar++; if ((allVars) || ((*it).upsVarActivate)) { //nacteme promenou inBuffer = "REQ "; inBuffer.append((*it).upsVarName); if (!m_upsName.isEmpty()) { // pokud upsName neni je vzdy nastaveno na null inBuffer.append("@"); inBuffer.append(m_upsName); } inBuffer.append("\n"); // if (!(error=getUpsData (inBuffer,outBuffer))) { m_error=getUpsData (inBuffer,outBuffer); // when outBuffer is empty sends and reads date again, but only the only time if ((!(m_error)) && (outBuffer.isEmpty())) m_error=getUpsData (inBuffer,outBuffer); if (!(m_error)) { endChar = ""; if ((outBuffer.length()>0) && (outBuffer.at(outBuffer.length()-2)==' ')) endChar=' '; outBuffer=outBuffer.stripWhiteSpace (); outBuffer += endChar; emit getVarDesc (m_numberVars, numberVar); if ( !outBuffer.isEmpty() ) { TQTextIStream inputStream(&outBuffer); TQString word1, word2, word3 ; inputStream >> word1; inputStream >> word2; if (inputStream.atEnd()) { // neexistuje treti cast VALUE if (word1 == "ERR") { // vracena chyba m_error=upsTranslateError(word2); return m_error; } else { // if ((word2 != "MODEL") && (word2 != "MFR")) { if (endChar != " ") { // if values of variable is empty, string is ended on char space m_error=UnknownFormat; return m_error; } } } inputStream >> word3; if (word1 == "ANS") { // answer - odpoved // odstranime pripadne jmeno upsky if ((m_posChar = word2.find('@')) != -1) word2 = word2.left(m_posChar); if ( word2 != (*it).upsVarName ) { m_error=UnknownAnswer; return m_error;// neni to odpoved na spravnou promennou } // test pro starsi format modulu, vraceli chybu v hodnote promene if ((m_error=upsOldTranslateError(word3))) { return m_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 m_error=UnknownAnswer; return m_error; } } else { m_error=NoData; return m_error; } } else { return m_error; } } } return 0; } int KNutNet::getUpsValues2 (const bool allVars ) {// allVars = true vse; allVars = false jen activate TQString varName; TQString upsNameRet; TQString value; int typeValue; int lenString; // reads value of variables TQCString inBuffer; TQString outBuffer; TQValueVector::iterator it; emit getVarDesc (m_numberVars, 0); int numberVar = 0; for (it = m_listVars.begin(); it != m_listVars.end(); it++) { numberVar++; if ((allVars) || ((*it).upsVarActivate)) { //reads variable inBuffer = "GET VAR "+m_upsName+" "+(*it).upsVarName+"\n"; // if (!(error=getUpsData (inBuffer,outBuffer))) { m_error=getUpsData (inBuffer,outBuffer); // when outBuffer is empty sends and reads date again, but only the only time if ((!(m_error)) && (outBuffer.isEmpty())) m_error=getUpsData (inBuffer,outBuffer); if (!(m_error)) { outBuffer=outBuffer.stripWhiteSpace (); emit getVarDesc (m_numberVars, numberVar); if ( !outBuffer.isEmpty() ) { int key = parseLine(outBuffer, upsNameRet, varName, value, typeValue, lenString); switch (key) { case VAR: if ( varName != (*it).upsVarName ) { m_error=UnknownAnswer; return m_error;// it isn't answer for right variable - neni to odpoved na spravnou promennou } (*it).upsValue=value; if ((((*it).upsVarName == "STATUS") && (m_nutVariables == 1)) || (((*it).upsVarName == "ups.status") && (m_nutVariables == 2))) { // dogenerujeme dalsi slova pro status genStatusFlags(value); } break; case ERR: m_error=upsTranslateError(value); return m_error; default: m_error=UnknownAnswer; return m_error; } } else { m_error= NoData; return m_error; } } else { return m_error; } } } return 0; } int KNutNet::sendComm (const TQString command, const TQString arg1, const TQString arg2, const bool useUpsName) { int localError; // nenastavi promenou error ale nenuluje ji TQCString inBuffer; TQString outBuffer; switch (m_nutProtocol) { case 1: inBuffer=command + " " + arg1; if (useUpsName && (!m_upsName.isEmpty())) // pokud upsName neni je vzdy prazdne inBuffer += "@"+m_upsName; if (!arg2.isEmpty()) inBuffer += " " + arg2; break; case 2: inBuffer = command + " "; if (useUpsName) inBuffer += m_upsName + " "; inBuffer.append(arg1); if (!arg2.isEmpty()) inBuffer += " \"" + arg2 +"\""; break; } inBuffer.append("\n"); if (!(localError=getUpsData (inBuffer,outBuffer))) { outBuffer=outBuffer.stripWhiteSpace(); TQTextIStream inputStream(&outBuffer); TQString 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 TQString name, const bool setActivate ) { m_error =0; if (m_state == Connected) { TQValueVector::iterator it; for (it = m_listVars.begin(); it != m_listVars.end(); it++) { if ((*it).upsVarName == name) { (*it).upsVarActivate = setActivate; return 0; } } m_error = VarNotFind; return m_error; } else return NotConnection; } int KNutNet::activateAll ( const bool setActivate ) { m_error =0; if (m_state == Connected) { TQValueVector::iterator it; for (it = m_listVars.begin(); it != m_listVars.end(); it++) { (*it).upsVarActivate = setActivate; } return 0; } else return NotConnection; } int KNutNet::upsTranslateError (const TQString 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 == "ALREADY-SET-USERNAME") return AlreadySetUsername; 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 TQString 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; //tqDebug ("--KNutNet::slotConnectionError"); m_state = ConnectError; m_unConnectTimer->stop(); if (error == TQSocket::ErrHostNotFound) { error = NoSuchHost; emit connectionError(error); return; } //connection was refused // no connection if ((error == TQSocket::ErrConnectionRefused) && (m_commandSocket->state()==TQSocket::Idle)) { if (m_firstConnect) { if (m_numberConnection < m_countRepeat) { m_numberConnection++; // tqDebug ("--KNutNet:: connect error - try connect on next time"); m_unConnectTimer->start( m_delay, TRUE ); } else { // i don't connect server error=CantConnect; // tqDebug("--KNutNet::emit - connection error "); emit connectionError(error); return; } } // end of if (firstConnection) else { // connecting is down, try repeated connection // tqDebug ("--KNutNet::no first connect connection error "); m_unConnectTimer->start( m_delay, TRUE ); } return; } if (error == TQSocket::ErrConnectionRefused) { error = ConnectionRefused; // std::cout << "--KNutNet::connection error ErrConnectionRefused " << TQSocket::Idle << " - " << error << std::endl; emit connectionError(error); return; } if (error == TQSocket::ErrSocketRead) { error = SocketReadErr; // std::cout << "--KNutNet::connection error TQSocket::ErrSocketRead " << error << std::endl; emit connectionError(error); return; } } void KNutNet::slotConnected(void) { int n; if ((n = version (m_countRepeat, m_delay)) == 0) { // 0 OK, 0> error if ((m_nutProtocol == 0) || (m_nutVariables == 0)) { // answer from upsd (VER) is unknown m_error=NutProtocolVarErr; m_state = Closing; m_commandSocket->close(); while (m_commandSocket->state() == TQSocket::Closing) { sleep (100); } m_state = ConnectError; return; } if ((m_nutProtocol == 2) && m_upsName.isEmpty()) { // if upsName is empty reads first ups name from upsd server if ((m_error =KNutNet::getFirstUpsName (m_upsName))) { // reading first upsName // upsd server doesn't support any ups m_state = Closing; m_commandSocket->close(); while (m_commandSocket->state() == TQSocket::Closing) { sleep (100); } m_state = ConnectError; } } m_state=Connected; } else { m_commandSocket->close(); } emit firstConnection(); // std::cout << "KNutNet::emit - firstConnection" << std::endl; } void KNutNet::slotHostFound(void) { // std::cout << "--KNutNet::slotHostFound" << std::endl; m_state = Connecting; emit hostFound(); } void KNutNet::slotConnectionClosed(void) { // std::cout << "--KNutNet::slotConnectionClosed" << std::endl; m_unConnectTimer->stop(); deleteVars(); m_state = Idle; emit connectionClosed(); } void KNutNet::slotTimerReconnect(void) { // std::cout << "--KNutNet::slotTimerReconnect" << std::endl; m_unConnectTimer->stop(); if (m_commandSocket->state()==TQSocket::Idle) { //std::cout << "--KNutNet::slotTimerReconnect TQSOcket::Idle" << std::endl; emit tryRepeatFirstConnection(m_numberConnection); // std::cout << "KNutNet::emit-tryRepeatFirstConnection" << std::endl; m_state=Connecting; if ( m_commandSocket->state() != TQSocket::Connecting ) m_commandSocket->connectToHost(m_upsAddress,m_port); } } #include "knutnet.moc"