Logo Search packages:      
Sourcecode: nateon version File versions  Download package

nateonconnection.cpp

/***************************************************************************
 *   Copyright (C) 2008 by SK Communications.                              *
 *   http://kldp.net/projects/nateon/                                      *
 *                                                                         *
 *   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 3 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include <kextsock.h>
#include <kdebug.h>
#include <klocale.h>
#include <kmessagebox.h>
#include <kapplication.h>
#include <kconfig.h>
#include <qmutex.h>
#include <qregexp.h>

#include "../currentaccount.h"
#include "../knateondebug.h"
#include "mimemessage.h"
#include "util/common.h"
#include "knateoncommon.h"
#include "nateonconnection.h"
#include "nomhttpproxy.h"

extern nmconfig stConfig;

NateonConnection::NateonConnection(QString sIdentifier)
:config(0),
m_pCurrentAccount(0),
m_nTrid(0),
m_sIdentifier(sIdentifier),
m_bInitialized(false),
m_nMissedPings(0),
m_bSendPings(false),
m_pSocket(0),
m_bWriteLocked(false),
m_Buffer(0),
bRunning( FALSE ),
 m_pHttpProxy(0),
 bMultiLine( false )
{
      config = kapp->config();
      
    // Create the socket
    m_pSocket = new KExtendedSocket();

    // Connect it up and set some defaults
    // 0x00 = anySocket | 0x600000 = bufferedSocket
    m_pSocket->setSocketFlags( 0x00 | 0x600000 );
    m_pSocket->enableRead( true );
      // m_pSocket->setTimeout( 30   );

    m_pingTimer.stop();

    // Connect the ping timer to the sendPing slot
    connect( &m_pingTimer, SIGNAL( timeout() ), SLOT( sendPing() ) );

      m_pRetryTimer.stop();
      connect( &m_pRetryTimer, SIGNAL( timeout() ), SLOT( slotRetry() ) );
      
        // Configure the multi packet buffer
      // multiPacketBuffer_.setAutoDelete( FALSE );
      
  // Configure mutex. (TODO: check if this is really needed anymore)
      mproxywriteLocked_ = new QMutex();
      
#ifdef KNATEONTEST
    ASSERT( m_pSocket != 0 );
#endif
      connect( &connectionTimer_, SIGNAL( timeout() ), this, SLOT( slotConnectionTimeout() ) );

      qCommand.setAutoDelete ( FALSE );
      qCommand.clear();

//    connect( this, SIGNAL( addQueue() ), SLOT( slotRunCommand() ) );
      connect( &tCommandTimeout, SIGNAL( timeout() ), SLOT( slotCommandTimeout() ) );

      nextCommand.clear();
      nextCommand.setAutoDelete( FALSE );
}


// The destructor
NateonConnection::~NateonConnection()
{
    // Disconnect from the server on exit
    if ( isConnected() )
    {
        disconnectFromServer();
    }

    // Delete the socket
    delete m_pSocket;
      delete mproxywriteLocked_;
#ifdef NETDEBUG
      kdDebug() << "DESTROYED Connection" << endl;
#endif
}


// Insert "%" values for certain regular expressions, i.e. "%20" for " ".
void NateonConnection::addPercents(QString &sWord) const
{
    sWord = sWord.replace(QRegExp(" "),"%20");
}


// If the connection is successful...
void NateonConnection::connectionSuccess()
{
      // setSendPings( true );
#ifdef NETDEBUG
    kdDebug() << "Connection: Socket connected successfully." << endl;
#endif
}


// Connect to the given server via the socket
00132 bool NateonConnection::connectToServer(const QString& server, const int& port)
{
#ifdef KNATEONTEST
      ASSERT( ( port >= 0 ) && ( port < 32768 ) );
#endif
#ifdef NETDEBUG
      kdDebug() << "Connection: Connect to server at " << server << ":" << port << "." << endl;
      kdDebug() << "Socket status is " << m_pSocket->socketStatus() << "." << endl;
#endif

      // This seams to solve some problems with re-connecting
      // to the switchboard if there is a timeout.
      m_pSocket->reset();
      
      // Check that we are disconnected (the socket is null)
      if ( !( ( m_pSocket->socketStatus() == KExtendedSocket::nothing )
                  || ( m_pSocket->socketStatus() == KExtendedSocket::done ) ) )
      {
#ifdef NETDEBUG
            kdDebug() << "Connection: Socket is not disconnected.  Already connected?" << endl;
#endif
            return false;
      }

      // Either connect directly or via the proxy based on the user's settings
      /*! 연결(방화벽) */
      config->setGroup( "Config_Connection" );
      /*! 프록시 사용 여부 */
      bool bUseProxy = config->readBoolEntry( "Use_Proxy", false );

      
      
      if ( bUseProxy )
      {
        /*!
         * 접속 시도 시간 10초
         */
        connectionTimer_.stop();
        connectionTimer_.start( 10000, true );
            return connectToServerViaProxy( server, port );
      }
      else
      {
        /*!
         * 접속 시도 시간 5초
         */
        connectionTimer_.stop();
        connectionTimer_.start( 5000, true );
            return connectToServerDirectly( server, port );
      }
}


// Connect to the given server, not using the proxy
bool NateonConnection::connectToServerDirectly(const QString& server, const int& port)
{
      disconnect( m_pSocket, SIGNAL( readyRead() ), this, SLOT( proxyDataReceived() ) );
      disconnect( m_pSocket, SIGNAL( readyRead() ), this, SLOT( dataReceived()) );
      disconnect( m_pSocket, SIGNAL( connectionSuccess( void ) ), this, SLOT( connectionSuccess( void ) ) );
      disconnect( m_pSocket, SIGNAL( connectionSuccess( void ) ), this, SLOT( proxyConnected( void ) ) );
      disconnect( m_pSocket, SIGNAL( closed( int ) ), this, SLOT( socketclosed( int ) ) );
      disconnect( m_pSocket, SIGNAL( connectionFailed( int ) ), this, SLOT( socketError( int ) ) );
      
      connect( m_pSocket, SIGNAL( readyRead() ), this, SLOT( dataReceived() ) );
      connect( m_pSocket, SIGNAL( connectionFailed( int ) ), this, SLOT( socketError( int ) ) );
      connect( m_pSocket, SIGNAL( connectionSuccess( void ) ), this, SLOT( connectionSuccess( void ) ) );
      connect( m_pSocket, SIGNAL( closed( int ) ), this, SLOT( socketclosed( int ) ) );
      
      // #ifdef KNATEONDEBUG_CONNECTION_SOCKET
#ifdef NETDEBUG
      kdDebug() << "Connection: Using direct connection." << endl;
#endif
      // #endif

      m_pSocket->setAddress( server, port );
      // Apparently async lookups don't work correctly under Qt3
      int nRet = m_pSocket->lookup();
#ifdef NETDEBUG
      kdDebug() << "Lookup Result : " << nRet << ", Server : " << server << ", Port : " << port << endl;
#endif
      if ( nRet != 0 )
            return nRet == 0;
      
      int connectionSuccess = m_pSocket->startAsyncConnect();
#ifdef NETDEBUG
      kdDebug() << "connectionSuccess : " << connectionSuccess << endl;
#endif
      return connectionSuccess == 0;
}


//Send different request(send authentication info, connect to the destination)
00224 bool NateonConnection::connectToServerViaProxy(const QString& sServer, const int& nPort)
{
      disconnect( m_pSocket, SIGNAL( readyRead() ), this, SLOT( proxyDataReceived() ) );
      disconnect( m_pSocket, SIGNAL( readyRead() ), this, SLOT( dataReceived()) );
      disconnect( m_pSocket, SIGNAL( connectionSuccess( void ) ), this, SLOT( connectionSuccess( void ) ) );
      disconnect( m_pSocket, SIGNAL( connectionSuccess( void ) ), this, SLOT( proxyConnected( void ) ) );
      disconnect( m_pSocket, SIGNAL( closed( int ) ), this, SLOT( socketclosed( int ) ) );
      disconnect( m_pSocket, SIGNAL( connectionFailed( int ) ), this, SLOT( socketError( int ) ) );
      
      connect( m_pSocket, SIGNAL( readyRead() ), this, SLOT( proxyDataReceived() ) );
      connect( m_pSocket, SIGNAL( connectionFailed( int ) ), this, SLOT( socketError( int ) ) );
      connect( m_pSocket, SIGNAL( connectionSuccess( void ) ), this, SLOT( proxyConnected( void ) ) );
      connect( m_pSocket, SIGNAL( closed( int ) ), this, SLOT( socketclosed( int ) ) );
      
#ifdef NETDEBUG
      kdDebug() << "Connection: Using proxy connection." << endl;
#endif
      
      config->setGroup( "Config_Connection" );

      int nProxyType = config->readNumEntry( "Proxy_Type", 0 );
      int nProxyPort;
      /*! sock4, sock5 */
      if ( ( nProxyType == 0 ) || ( nProxyType == 1 ) )
            nProxyPort = config->readNumEntry( "Proxy_Port", 1080 );
      else {
            /*! http proxy */
            nProxyPort = config->readNumEntry( "Proxy_Port", 6588 );
            m_pHttpProxy = new NOMHTTPProxy( sServer, nPort );
      }
      
      
      m_pCurrentAccount->setProxyType( (Account::PROXYTYPE) nProxyType );
      m_pCurrentAccount->setProxyServer( config->readEntry( "Proxy_Server", QString::null ) );
      m_pCurrentAccount->setProxyPort( nProxyPort );
      m_pCurrentAccount->setProxyID( config->readEntry( "Proxy_ID", QString::null ) );
      m_pCurrentAccount->setProxyPassword( config->readEntry( "Proxy_Password", QString::null ) );

      if( m_pCurrentAccount->getProxyServer() == QString::null ) return false;
      
      struct hostent *hostent=NULL;
      hostent = gethostbyname( sServer );
      if( hostent==NULL ) return false;

      //now only support ipv4

      //save server's ip address and port in struct sockaddr_in
      memcpy( &m_addr_destServer.sin_addr, hostent->h_addr, 4 );
      m_addr_destServer.sin_port = htons( nPort );

      //save server and port for later connection
      m_sDestServer = sServer;
      m_nDestPort = nPort;


      m_nProxyState = 0;

    kdDebug() << "Connecting Server : " << m_pCurrentAccount->getProxyServer() <<", Port : " << m_pCurrentAccount->getProxyPort() << endl;
    
      m_pSocket->setAddress( m_pCurrentAccount->getProxyServer(), m_pCurrentAccount->getProxyPort());
      
      //at present, use synchronous connection
      return m_pSocket->connect() == 0;
}


void NateonConnection::parseMultiLine( const QStringList& slCommand, const char *pData, Q_ULONG nDataLen )
{
    MimeMessage mimeMessage( pData );
    
    if ( strncmp( pData, "IMSG", 4 ) == 0 ) {
        parseMessage( "IMSG", slCommand, mimeMessage );
    } else if ( strncmp( pData, "INVT", 4 ) == 0 ) {
        parseBuffer( slCommand, pData );
    } else if ( strncmp( pData, "REQC", 4 ) == 0 ) {
        parseBuffer( slCommand, pData );
    } else {
        parseMessage( "", slCommand, mimeMessage );
    }

//     if ( strncmp( pData, "CONF", 4 ) == 0 ) {
//         parseMessage( "", slCommand, mimeMessage );
//     }
//     else if ( strncmp( pData, "CTOC", 4 ) == 0 ) {
//     }
//     else {
//         kdDebug() << QString::fromUtf8( pData ) << endl;
//     }
}


// Read data from the socket
00316 void NateonConnection::dataReceived()
{
#ifdef KNATEONTEST
      ASSERT( m_pSocket != 0 );
#endif

//     Q_ULONG nDataLen;
//     nDataLen = m_pSocket->bytesAvailable();

//     char *pData = ( char * )malloc( nDataLen + 1 );
//     memset( pData, 0x00, nDataLen + 1 );
//     Q_ULONG nBytesRead = m_pSocket->readBlock( pData, nDataLen );
//     if ( nBytesRead < 0 )
//         return;

//     resetPingTimer();

//     if (
//         strncmp( pData, "CONF", 4 ) == 0 ||
//         strncmp( pData, "CTOC", 4 ) == 0 ||
//         strncmp( pData, "GLST", 4 ) == 0 ||
//         strncmp( pData, "LIST", 4 ) == 0
//         ) {
//         bMultiLine = true;
//     }

//     if ( bMultiLine ) {

//         m_Buffer.add( pData, nBytesRead );
//         int nIndex = m_Buffer.findNewline();
//         if (nIndex == -1)
//             return;

//         char *pData2 = ( char * )m_Buffer.data();

//         char *pCommand = ( char * )malloc( nIndex + 1 );
//         memset( pCommand, 0x00, nIndex + 1 );
//         memcpy( pCommand, pData2, nIndex );

//         kdDebug() << "XX :[" << QString::fromUtf8( pCommand ) << "]" << endl;
        
//         QStringList slCommand = QStringList::split( " ", pCommand );
//         free( pCommand );
        
//         int nMessageLength = slCommand[ slCommand.count() - 1 ].toInt();

//         char *pBody = ( char * )malloc( nMessageLength + 1 );
//         memset( pBody, 0x00, nMessageLength + 1 );
//         memcpy( pBody, pData2 + ( nIndex + 2 ), nMessageLength );
        
//         if ( ( m_Buffer.length() - ( nIndex + 2 ) ) >= nMessageLength ) {
//             bMultiLine = false;
//             emit messageReceived(QString::fromUtf8( pData2 ));
//             parseMultiLine( slCommand, pBody, nMessageLength );
//         }
//         else {
//             bMultiLine = true;
//             return;
//         }
//     }
//     else {
//         bMultiLine = false;
//         QStringList slCommand = QStringList::split( " ", pData );
//         if ( slCommand[0] == "PONG" && m_bSendPings ) {
//             m_bPingReceived = true;
//             m_nMissedPings = 0;
//         }
//         else {
//             emit messageReceived(QString::fromUtf8( pData ));
//             parseCommand( slCommand );
//         }
//     }
    
      char rawblock[1024];
      QCString sBlock, sCommandLine;
      int nIndex, nBytesRemaining, nBytesRead, nMessageLength;
      QStringList slCommand;
      bool bIscompleteMessage = false;

      do
      {
            // Find out how much data remains in the socket
            nBytesRemaining = m_pSocket->bytesAvailable();

            // Read in a block from the socket
            memset( rawblock, 0x00, 1024 );
            nBytesRead = m_pSocket->readBlock( rawblock, 1024 );


            // If the noBytesRead is less than zero, it's an error code, so exit
            if ( nBytesRead < 0 )
            {
                  //KMessageBox::error(0, UTF8("adwaawawdaw"));
                  return;
            }

            // We've received some data, reset the ping timer
            resetPingTimer();

            // Add the block to the buffer
            m_Buffer.add( rawblock, nBytesRead );

            // If the buffer contains "\r\n" then there should be at least one full command in there.
            while ( true )
            { \
                  // Find the location of the end of the command
                  nIndex = m_Buffer.findNewline();

                  if (nIndex == -1) break;

                  // Pull off a command line
                  sCommandLine = m_Buffer.left( nIndex );

                  // don't know why it need this, commandLine should already be this length
                  sCommandLine = sCommandLine.left( nIndex );

                  // Convert the line to a QStringList command
                  slCommand = QStringList::split( " ", QString::fromUtf8( sCommandLine ) );
                  int *ckInt = new int( slCommand[1].toInt() );
                  const QString *nC = nextCommand.find( ckInt );
                  if ( nC != 0 )
                  {
#ifdef NETDEBUG
                        kdDebug() << "FFFF: [" << *nC << "]" << endl;
#endif
                        writeData( *nC );
                        nextCommand.remove( ckInt );
                  }
                  delete ckInt;
                  // Check if this is a BODY-LEN + BODY protocol type :(
                  if ( slCommand[0] == "CONF" || slCommand[0] == "CTOC" )
                  {
                        // Get message length (last parameter)
                        nMessageLength   = slCommand[ slCommand.count() - 1 ].toInt();
                        // Compare length with the size of the buffer
                        bIscompleteMessage = ((m_Buffer.length() - nIndex - 2) >= nMessageLength);

                        // Check if the rest of the message is in the buffer
                        if ( bIscompleteMessage  )
                        {
                              // Remove the command from the buffer
                              m_Buffer.remove( nIndex + 2 );

                              // Full message: send to network window
                              /*! 로그가 깨지는데 왜그럴까? */
                              emit messageReceived( sCommandLine.append("\n").append(  m_Buffer.left(nMessageLength) ) );

                              // Get the message from the buffer and create the mime message
                              // Note we can't parse Strings here, the message could contain binary p2p data.
                              // Unicode characters are translated in the MimeMessage constructor itself.
                              MimeMessage mimeMessage(m_Buffer.left( nMessageLength ));
                              // and parse it

                              QString sTemp( m_Buffer.left(4) );

                              /// CTOC에서 쪽지는 IMSG, 대화는 INVT 임. 분기가 필요해서 m_Buffer.left(4) 인자를 둠.
                              if ( sTemp == "IMSG" )
                              {
                                    parseMessage( m_Buffer.left(4), slCommand, mimeMessage );
                              } else if ( sTemp == "INVT" ) {
                                    parseBuffer(slCommand, QString( m_Buffer.left( nMessageLength ) ));
                              } else if ( sTemp == "REQC" ) {
                                    QString sBody;
                                    sBody = QString(m_Buffer.left( nMessageLength ));
                                    parseBuffer(slCommand, sBody);
                              } else {
                                    parseMessage( m_Buffer.left(4), slCommand, mimeMessage );
                              }
                              // delete from the buffer
                              m_Buffer.remove( nMessageLength );
                        }
                        // If the buffer doesn't contain the rest of the message, just wait until "dataReceived" is called again.
                        else
                        {
                              // Break out of the loop
                              break;
                        }
                  }
                  // Check if this is the other data type
                  else
                  {
                        // This is a regular command
#if 0
                        // Convert the line to a QStringList command
                        slCommand = QStringList::split( " ", QString::fromUtf8( sCommandLine ) );
#endif
                        // Remove the command from the buffer.
                        m_Buffer.remove( nIndex + 2 );

                        // Emit message for network window
                        emit messageReceived(QString::fromUtf8(sCommandLine));
                        // emit messageReceived( sCommandLine );

                        // We parse ping responses internally
                        if ( slCommand[0] == "PONG" && m_bSendPings )
                        {
                              m_bPingReceived = true;
                              m_nMissedPings = 0;
                        }
                        else
                        {
                              // Parse the command.
                              parseCommand( slCommand );
                        }
                  }
            }
      }
      while(nBytesRemaining > 0);
}


void NateonConnection::disconnectFromServer( bool isTransfer )
{
#ifdef NETDEBUG
    kdDebug() << "Connection: Send 'OUT'." << endl;
#endif

    // stop any more pings
    setSendPings( FALSE );

    // If the socket is connected...
    if ( isConnected() )
    {
        // Send "OUT"
        writeData("LOUT\r\n");
    }
#ifdef NETDEBUG
    kdDebug() << "Connection: Flush the socket." << endl;
#endif

    // Flush the socket
    m_pSocket->flush();

#ifdef NETDEBUG
    kdDebug() << "Connection: Close the socket." << endl;
#endif

    // Close the socket
    m_pSocket->closeNow();
    // Reset the socket
    m_pSocket->reset();

#ifdef NETDEBUG
    kdDebug() << "Connection: emit 'disconnected'." << endl;
#endif

    if ( !isTransfer ) emit disconnected();
}


// Return an acknowledgement number
int NateonConnection::getTrid()
{
    return m_nTrid++;
}


// Find out how much data is waiting in the buffer
unsigned int NateonConnection::getBufferSize()
{
    return m_Buffer.length();
}


// Get some amount of data from the buffer
QString NateonConnection::getDataFromBuffer(const int& nLength)
{
#ifdef KNATEONTEST
    uint oldBufferLength = m_Buffer.length();
#endif

    QString sData;
    sData = QString::fromUtf8( m_Buffer.left( nLength ) );

    // Remove the full message from the buffer
    m_Buffer.remove( nLength );

#ifdef KNATEONTEST
      ASSERT( (uint)( m_Buffer.length() ) == (uint)( oldBufferLength - nLength ) );
#endif
#ifdef NETDEBUG
    kdDebug() << m_sIdentifier << " <<< " << sData << endl;
#endif

    return sData;
}


// Get the IP address of this machine.
const QString NateonConnection::getLocalIP() const
{
#ifdef NETDEBUG
    kdDebug() << "Connection::getLocalIp()" << endl;
#endif

    QString sIp = "";
    const KSocketAddress *address;
    address = m_pSocket->localAddress();
    if ( address != 0 )
    {
        sIp = address->pretty();
        // Local address gives something like "1.2.3.4 port 5" in the english
        //  version, and "1.2.3.4-Portnammersomething 5" in the german version.
        // So, to get the port, replace any "-"'s with " " then get everything
        //  to the left of the first space.  That should work.
        sIp = sIp.replace( QRegExp("-"), " " );
#ifdef NETDEBUG
        kdDebug() << "C:    Raw IP is " << sIp << endl;
#endif
        if ( sIp.contains(" ") )
        {
            sIp = sIp.left( sIp.find(" ") );
        }
#ifdef NETDEBUG
        kdDebug() << "C:    IP is " << sIp << endl;
#endif
    }
#ifdef NETDEBUG
    else
    {
        kdDebug() << "Connection::getLocalIp(): WARNING - IP not found.  Local address was null?" << endl;
    }
#endif
      
#ifdef NETDEBUG
    kdDebug() << "C:    Done getLocalIp()." << endl;
#endif
    return sIp;
}


// Get whether we're sending pings or not
bool NateonConnection::getSendPings() const
{
    return m_bSendPings;
}


// Extract some information from a message (like "Name: Joe;" - extract the "Joe")
QString NateonConnection::getValueFromMessage(const QString& sField, const QString& sMessage, bool bGoToEndOfLine) const
{
    QString sValue;
    int      nFieldStart, nFieldEnd;
#ifdef KNATEONTEST
    ASSERT( sMessage.contains( sField ) );
#endif

    if ( !sMessage.contains( sField ) )
    {
        return "";
    }

    // Find the occurance of "field" in the message
    nFieldStart = sMessage.find( sField );
    nFieldEnd = sMessage.find( " ", nFieldStart );
    if ( nFieldEnd < 0 )
    {                            // For some reason, there's no space after the field.
        return "";
    }
    // Take everything to the right of the message beginning
    sValue = sMessage.right( sMessage.length() - nFieldEnd - 1 );
    // The value should be anything before returns or spaces
    sValue = sValue.left( sValue.find("\r\n") );
    if ( !bGoToEndOfLine )
    {
        sValue = sValue.left( sValue.find(" ") );
    }
    // Strip semicolons off the end of the value
    if ( sValue.right(1) == ";" )
    {
        sValue = sValue.left( sValue.length() - 1 );
    }
    return sValue;
}


// Whether or not the class is connected
bool NateonConnection::isConnected() const
{
    return ( m_pSocket->socketStatus() == KExtendedSocket::connected );
}


// Replace any "%" values with their regular values, i.e. "%20" to " ".
void NateonConnection::removePercents(QString &sWord) const
{
      sWord = sWord.replace( QRegExp( "%20" ), " " );
      sWord = sWord.replace( QRegExp( "%0D" ), "\r" );
      sWord = sWord.replace( QRegExp( "%0A" ), "\n" );
#if 0
      sWord = sWord.replace( QRegExp( "%20" ), " " );
      sWord = sWord.replace( QRegExp( "%21" ), "!" );
      sWord = sWord.replace( QRegExp( "%22" ), "\"" );
      sWord = sWord.replace( QRegExp( "%23" ), "#" );
      sWord = sWord.replace( QRegExp( "%24" ), "$" );
      sWord = sWord.replace( QRegExp( "%25" ), "%" );
      sWord = sWord.replace( QRegExp( "%26" ), "&" );
      sWord = sWord.replace( QRegExp( "%27" ), "'" );
      sWord = sWord.replace( QRegExp( "%28" ), "(" );
      sWord = sWord.replace( QRegExp( "%29" ), ")" );
      sWord = sWord.replace( QRegExp( "%2A" ), "*" );
      sWord = sWord.replace( QRegExp( "%2B" ), "+" );
      sWord = sWord.replace( QRegExp( "%2C" ), "," );
      sWord = sWord.replace( QRegExp( "%2D" ), "-" );
      sWord = sWord.replace( QRegExp( "%2E" ), "." );
      sWord = sWord.replace( QRegExp( "%2F" ), "/" );
      sWord = sWord.replace( QRegExp( "%30" ), "0" );
      sWord = sWord.replace( QRegExp( "%31" ), "1" );
      sWord = sWord.replace( QRegExp( "%32" ), "2" );
      sWord = sWord.replace( QRegExp( "%33" ), "3" );
      sWord = sWord.replace( QRegExp( "%34" ), "4" );
      sWord = sWord.replace( QRegExp( "%35" ), "5" );
      sWord = sWord.replace( QRegExp( "%36" ), "6" );
      sWord = sWord.replace( QRegExp( "%37" ), "7" );
      sWord = sWord.replace( QRegExp( "%38" ), "8" );
      sWord = sWord.replace( QRegExp( "%39" ), "9" );
      sWord = sWord.replace( QRegExp( "%3A" ), ":" );
      sWord = sWord.replace( QRegExp( "%3B" ), ";" );
      sWord = sWord.replace( QRegExp( "%3C" ), "<" );
      sWord = sWord.replace( QRegExp( "%3D" ), "=" );
      sWord = sWord.replace( QRegExp( "%3E" ), ">" );
      sWord = sWord.replace( QRegExp( "%3F" ), "?" );
      sWord = sWord.replace( QRegExp( "%40" ), "@" );
      sWord = sWord.replace( QRegExp( "%41" ), "A" );
      sWord = sWord.replace( QRegExp( "%42" ), "B" );
      sWord = sWord.replace( QRegExp( "%43" ), "C" );
      sWord = sWord.replace( QRegExp( "%44" ), "D" );
      sWord = sWord.replace( QRegExp( "%45" ), "E" );
      sWord = sWord.replace( QRegExp( "%46" ), "F" );
      sWord = sWord.replace( QRegExp( "%47" ), "G" );
      sWord = sWord.replace( QRegExp( "%48" ), "H" );
      sWord = sWord.replace( QRegExp( "%49" ), "I" );
      sWord = sWord.replace( QRegExp( "%4A" ), "J" );
      sWord = sWord.replace( QRegExp( "%4B" ), "K" );
      sWord = sWord.replace( QRegExp( "%4C" ), "L" );
      sWord = sWord.replace( QRegExp( "%4D" ), "M" );
      sWord = sWord.replace( QRegExp( "%4E" ), "N" );
      sWord = sWord.replace( QRegExp( "%4F" ), "O" );
      sWord = sWord.replace( QRegExp( "%50" ), "P" );
      sWord = sWord.replace( QRegExp( "%51" ), "Q" );
      sWord = sWord.replace( QRegExp( "%52" ), "R" );
      sWord = sWord.replace( QRegExp( "%53" ), "S" );
      sWord = sWord.replace( QRegExp( "%54" ), "T" );
      sWord = sWord.replace( QRegExp( "%55" ), "U" );
      sWord = sWord.replace( QRegExp( "%56" ), "V" );
      sWord = sWord.replace( QRegExp( "%57" ), "W" );
      sWord = sWord.replace( QRegExp( "%58" ), "X" );
      sWord = sWord.replace( QRegExp( "%59" ), "Y" );
      sWord = sWord.replace( QRegExp( "%5A" ), "Z" );
      sWord = sWord.replace( QRegExp( "%5B" ), "[" );
      sWord = sWord.replace( QRegExp( "%5C" ), "\\" );
      sWord = sWord.replace( QRegExp( "%5D" ), "]" );
      sWord = sWord.replace( QRegExp( "%5E" ), "^" );
      sWord = sWord.replace( QRegExp( "%5F" ), "_" );
      sWord = sWord.replace( QRegExp( "%60" ), "`" );
      sWord = sWord.replace( QRegExp( "%61" ), "a" );
      sWord = sWord.replace( QRegExp( "%62" ), "b" );
      sWord = sWord.replace( QRegExp( "%63" ), "c" );
      sWord = sWord.replace( QRegExp( "%64" ), "d" );
      sWord = sWord.replace( QRegExp( "%65" ), "e" );
      sWord = sWord.replace( QRegExp( "%66" ), "f" );
      sWord = sWord.replace( QRegExp( "%67" ), "g" );
      sWord = sWord.replace( QRegExp( "%68" ), "h" );
      sWord = sWord.replace( QRegExp( "%69" ), "i" );
      sWord = sWord.replace( QRegExp( "%6A" ), "j" );
      sWord = sWord.replace( QRegExp( "%6B" ), "k" );
      sWord = sWord.replace( QRegExp( "%6C" ), "l" );
      sWord = sWord.replace( QRegExp( "%6D" ), "m" );
      sWord = sWord.replace( QRegExp( "%6E" ), "n" );
      sWord = sWord.replace( QRegExp( "%6F" ), "o" );
      sWord = sWord.replace( QRegExp( "%70" ), "p" );
      sWord = sWord.replace( QRegExp( "%71" ), "q" );
      sWord = sWord.replace( QRegExp( "%72" ), "r" );
      sWord = sWord.replace( QRegExp( "%73" ), "s" );
      sWord = sWord.replace( QRegExp( "%74" ), "t" );
      sWord = sWord.replace( QRegExp( "%75" ), "u" );
      sWord = sWord.replace( QRegExp( "%76" ), "v" );
      sWord = sWord.replace( QRegExp( "%77" ), "w" );
      sWord = sWord.replace( QRegExp( "%78" ), "X" );
      sWord = sWord.replace( QRegExp( "%79" ), "y" );
      sWord = sWord.replace( QRegExp( "%7A" ), "z" );
      sWord = sWord.replace( QRegExp( "%7B" ), "{" );
      sWord = sWord.replace( QRegExp( "%7C" ), "|" );
      sWord = sWord.replace( QRegExp( "%7D" ), "}" );
      sWord = sWord.replace( QRegExp( "%7E" ), "~" );
#endif
}


// Initialize the object
bool NateonConnection::initialize()
{
    if ( m_bInitialized )
    {
#ifdef NETDEBUG
        kdDebug() << "Connection already initialized!" << endl;
#endif
        return false;
    }

    m_pCurrentAccount = CurrentAccount::instance();
    if ( m_pCurrentAccount == 0 )
    {
#ifdef NETDEBUG
        kdDebug() << "Connection: Couldn't get an instance of the current account." << endl;
#endif
        return false;
    }

    m_bInitialized = true;

    return m_bInitialized;
}


// If the connection to proxy is successful...
void NateonConnection::proxyConnected(void)
{
    char command[9];
    bzero(command,9);

    m_nProxyState = 1;
      
      switch( m_pCurrentAccount->getProxyType() )
      {
            // Socks4 Proxy
      case Account::TYPE_SOCKS4:
            
            command[0]='\x04';   //version num
            command[1]='\x01';   //\x01 stands for "Connect"
            memcpy(&command[2],&m_addr_destServer.sin_port,2);
            memcpy(&command[4],&m_addr_destServer.sin_addr,4);
            writeProxyData(command,9);
            break;
            
            // Socks5 Proxy
      case Account::TYPE_SOCKS5:
            
            //if both uid and password are not empty, the proxy may need authentication.
            if ( ( m_pCurrentAccount->getProxyUID() != QString::null )
                 && ( m_pCurrentAccount->getProxyPassword() != QString::null ) )
            {
                  // Version num
                  command[0]='\x05';
                  // METHOD number
                  command[1]='\x02';
                  // Need authentication
                  command[2]='\x02';
                  // Need not authentication
                  command[3]='\x00';
                  // Proxy will pick a METHOD from the upper two
                  
                  writeProxyData(command,4);
            }
            else                 //We assume that no authentication is needed
            {
                  command[0]='\x05';
                  command[1]='\x01';
                  command[2]='\x00';
                  
                  writeProxyData(command,3);
            }
            break;
            
      case Account::TYPE_HTTP: //Have some problems now, I'll commit later
        connectionSuccess();
            break;
      }
}


// Read proxy reply from the socket
void NateonConnection::proxyDataReceived(void)
{
    kdDebug() << "proxyDataReceived!!!" << endl;
    
    int nbytesRead,nbytesAvailable;
    char *buf=NULL;

    if((nbytesAvailable=m_pSocket->bytesAvailable())<=0)
    {
        qWarning("m_pSocket has no information to read.\n");
        return;
    }
    if((buf=new char [nbytesAvailable+1])==NULL)
    {
        qWarning("Can't allocate space.\n");
        return;
    }

    bzero(buf, nbytesAvailable+1);

    nbytesRead=m_pSocket->readBlock(buf, nbytesAvailable+1);
    if(nbytesRead<=0||nbytesRead>nbytesAvailable)
    {
        qWarning("Reading from socket error");
        return;
    }

    QStringList slCommand;
    switch(m_pCurrentAccount->getProxyType())
    {
      case Account::TYPE_SOCKS4:

            if(m_nProxyState==1)
            {
                  if( nbytesRead!=8 )
                  {
                        //Reply must have exact 8 bytes
                        setProxyState(PROXYERROR );
                        return;
                  }

                  if( buf[1]==90 ) //Request for connecting to the host granted
                  {
                        setProxyState(PROXYHOSTCONNECTED );
                  }
                  else
                  {
                        //buf[1]==91 stands for request rejected or failed
                        //92 stands for request rejected becasue SOCKS server cannot connect to identd on the client
                        //93 stands for request rejected because the client program and identd report different user-ids
                        setProxyState(PROXYFAIL );
                  }
            }
            break;

      case  Account::TYPE_HTTP:
        kdDebug() << "[" << buf << "]" << endl;
        
            if(strncmp(buf,"HTTP/1.",7)==0&&strncmp(buf+9,"200",3)==0) {
            kdDebug() << "[ H E A D E R ]" << endl;
            QStringList slCommandList = QStringList::split( "\n", buf );
            QStringList slTicket = QStringList::split( ":", slCommandList[1] );
            QString sTicket = slTicket[1].stripWhiteSpace();
            m_pHttpProxy->setTicket( sTicket.toUInt() );
            kdDebug() << "Get Command : [" << slCommandList[6] << "]" <<  endl;
            slCommand = QStringList::split( " ", slCommandList[6] );
        }
        else {
            slCommand = QStringList::split( " ", buf );
            kdDebug() << "[ B O D Y ]" << endl;
        }

        if ( slCommand.count() > 0 ) {
            // We parse ping responses internally
            if ( slCommand[0] == "PONG" && m_bSendPings ) {
                m_bPingReceived = true;
                m_nMissedPings = 0;
            }
            else {
                // Parse the command.
                parseCommand( slCommand );
            }
        }
        break;

      case  Account::TYPE_SOCKS5:

            socks5_reply(buf,nbytesRead);
            break;
    }
}


// Show a message that the proxy failed
void NateonConnection::proxyFailed()
{
    QString message;
    // Show a message to the user
    message = UTF8("There was a problem connecting to the proxy.");
    KMessageBox::error( 0, message );
    // Disconnect from the server
    disconnectFromServer();
}


// Resets the ping timer
void NateonConnection::resetPingTimer()
{
    if ( m_bSendPings )
    {
        m_pingTimer.stop();

        // 30s ping timer
        m_pingTimer.start( 10000 );
    }
}


// Send a command to the server
int NateonConnection::sendCommand(const QString& sPrefix, const QString &sText)
{
    int nTrid = getTrid();

    // Send the data to the server
    QString sCommand;
    sCommand = sPrefix;
    sCommand += " ";
    sCommand += QString::number( nTrid );
    sCommand += " ";
    sCommand += sText;
      
    writeData( sCommand );

    // Return the ack used
    return nTrid;
}


// Send a command to the server
int NateonConnection::sendBinaryCommand(const QString& sPrefix, const QByteArray &sText)
{
#ifdef KNATEONTEST
    ASSERT( sPrefix.length() == 3 );
#endif

    int      nTrid = getTrid();
    QString sTridString;
    // Get an acknowledgement number and convert it to a string
    sTridString.sprintf("%d", nTrid);

#ifdef KNATEONTEST
    ASSERT( sTridString.toInt() == nTrid );
#endif
#ifdef NETDEBUG
    kdDebug() << "MsnConnection: Sending " << sPrefix << " command (" << sTridString << ")." << endl;
#endif

    // Don't break the ascii-zero characters!
      // Copy at once.
    QString sFullHeader = sPrefix + " " + sTridString + " ";
    uint nCmdLength = sFullHeader.length() + sText.size();
    uint nPos = 0;

    QByteArray binCommand(nCmdLength);

    // This lame solution appears to be the only way to preserve the ascii-zero header bytes.
    for(uint i = 0; i < sFullHeader.length(); ++i) binCommand[nPos++] = sFullHeader[i].latin1();
    for(uint i = 0; i < sText.size();         ++i) binCommand[nPos++] = sText[i];

#ifdef NETDEBUG
    kdDebug() << "MsnConnection: p2p message size = " << binCommand.size() << endl;
#endif

    writeBinaryData(binCommand);

    // Return the ack used
    return nTrid;
}


// Send a "ping" to the server
void NateonConnection::sendPing()
{
    QString sMessage;

    if ( m_bPingReceived == false )
    {
        m_nMissedPings++;

          m_pingTimer.changeInterval ( 3000 );
          
        if ( m_nMissedPings == 1 )
        {
            sMessage += UTF8( "1 ping lost" );
        }
        else
        {
            sMessage += UTF8( "%1 pings lost" ).arg(m_nMissedPings);
        }

        emit statusMessage( sMessage, 2 );
    }
    else
    {
        emit statusMessage( UTF8( "Connection good" ), 1 );
    }

    m_bPingReceived = false;

    if ( m_nMissedPings == 3 )
    {
#if 1
        kdDebug() << "WARNING: 5 missed server pings, assuming disconnected" << endl;
#endif
          disconnectFromServer();
          emit pingError();
    }

    writeData( "PONG 0\r\n" );
}


// Set whether we're sending pings or not (also resets ping timer)
void NateonConnection::setSendPings( bool bSendPings )
{
    m_bSendPings = bSendPings;

    m_nMissedPings = 0;

    m_bPingReceived = true;

    if ( m_bSendPings )
    {
        sendPing();

        resetPingTimer();
    }
    else
    {
        m_pingTimer.stop();
    }
}


// Dealing different proxy state, implemented in class MsnNotificationConnection
void NateonConnection::setProxyState(PROXYSTATE state)
{
    switch(state)
    {
      case PROXYCONNECTED:

            break;

      case PROXYHOSTCONNECTED:

            m_nProxyState=0;
            if(m_pSocket!=0)
            {
                  disconnect( m_pSocket, SIGNAL( readyRead() ), this, SLOT( proxyDataReceived() ) );
                  disconnect( m_pSocket, SIGNAL( readyRead() ), this, SLOT( dataReceived()) );
                  disconnect( m_pSocket, SIGNAL( connectionSuccess( void ) ), this, SLOT( connectionSuccess( void ) ) );
                  disconnect( m_pSocket, SIGNAL( connectionSuccess( void ) ), this, SLOT( proxyConnected( void ) ) );
                  disconnect( m_pSocket, SIGNAL( closed( int ) ), this, SLOT( socketclosed( int ) ) );
                  disconnect( m_pSocket, SIGNAL( connectionFailed( int ) ), this, SLOT( socketError( int ) ) );
                  
                  connect( m_pSocket, SIGNAL( readyRead() ), this, SLOT( proxyDataReceived() ) );
                  connect( m_pSocket, SIGNAL( connectionFailed( int ) ), this, SLOT( socketError( int ) ) );
                  connect( m_pSocket, SIGNAL( connectionSuccess( void ) ), this, SLOT( proxyConnected( void ) ) );
                  connect( m_pSocket, SIGNAL( closed( int ) ), this, SLOT( socketclosed( int ) ) );
#if 0
                  disconnect(m_pSocket, SIGNAL(readyRead()), this, SLOT(proxyDataReceived()) );
                  disconnect(m_pSocket, SIGNAL(connectionSuccess(void) ), this, SLOT(proxyConnected(void)) );
                  connect(m_pSocket, SIGNAL(readyRead()), this, SLOT(dataReceived()) );
                  connect(m_pSocket, SIGNAL(connectionSuccess(void) ), this, SLOT( connectionSuccess(void)) );
#endif
            }
            connectionSuccess(); // Send version commands
            break;

      case PROXYERROR:
      case PROXYFAIL:
            m_nProxyState = 0;
            if(m_pSocket!=0)
            {
                  disconnect( m_pSocket, SIGNAL( readyRead() ), this, SLOT( proxyDataReceived() ) );
                  disconnect( m_pSocket, SIGNAL( readyRead() ), this, SLOT( dataReceived()) );
                  disconnect( m_pSocket, SIGNAL( connectionSuccess( void ) ), this, SLOT( connectionSuccess( void ) ) );
                  disconnect( m_pSocket, SIGNAL( connectionSuccess( void ) ), this, SLOT( proxyConnected( void ) ) );
                  disconnect( m_pSocket, SIGNAL( closed( int ) ), this, SLOT( socketclosed( int ) ) );
                  disconnect( m_pSocket, SIGNAL( connectionFailed( int ) ), this, SLOT( socketError( int ) ) );
                  
                  connect( m_pSocket, SIGNAL( readyRead() ), this, SLOT( dataReceived() ) );
                  connect( m_pSocket, SIGNAL( connectionFailed( int ) ), this, SLOT( socketError( int ) ) );
                  connect( m_pSocket, SIGNAL( connectionSuccess( void ) ), this, SLOT( connectionSuccess( void ) ) );
                  connect( m_pSocket, SIGNAL( closed( int ) ), this, SLOT( socketclosed( int ) ) );
#if 0
                  disconnect( m_pSocket, SIGNAL(readyRead()),this, SLOT(proxyDataReceived()) );
                  disconnect( m_pSocket, SIGNAL( connectionSuccess(void) ),this, SLOT( proxyConnected(void)) );
                  connect( m_pSocket, SIGNAL(readyRead()),this, SLOT(dataReceived()) );
                  connect( m_pSocket, SIGNAL( connectionSuccess(void) ),this, SLOT( connectionSuccess(void)) );
#endif
            }
            proxyFailed();
            break;
    }
}


// Detect a socket error
void NateonConnection::socketError(int error)
{
      Q_UNUSED( error );
      
#if 1
    kdDebug() << "Connection:WARNING - Received error " << error << " from the socket." << endl;
#endif
    disconnectFromServer();
}


// Send authentication info to the socks5 server
void NateonConnection::socks5_auth(void)
{
    QString uid=m_pCurrentAccount->getProxyUID();
    QString pwd=m_pCurrentAccount->getProxyPassword();

    int ulen = uid.length();
    int plen = pwd.length();
    char * command = new char[3+ulen+plen];
    sprintf((char *)command,"  %s %s",uid.local8Bit().data(),pwd.local8Bit().data());

    command[0]='\x01';           // Version of the subnegotiation, not the protocol
    command[1]=ulen;
    command[2+ulen] = plen;

    writeProxyData( command,3+ulen+plen );
    delete []command;
}


// Finally request to connect to the host via the socks5 proxy
void NateonConnection::socks5_connect(void)
{
    char command[10];
    bzero(command,10);

    command[0]='\x05';           // Protocol version
    command[1]='\x01';           // CONNECT
    command[2]='\x00';           // RESERVED, now is '\x00'
    command[3]='\x01';           // Indicates IP V4 address
                                 //4 bytes IP address
    memcpy( command+4, &m_addr_destServer.sin_addr,4 );
      //2 bytes port
    memcpy( command+8, &m_addr_destServer.sin_port,2 );

    writeProxyData(command, 10 );
}


// Send different request(send authentication info, connect to the destination)
// to the socks5 server according to its reply
void NateonConnection::socks5_reply(const char *buf,int nread)
{
    switch( m_nProxyState)
    {
      case 1:                  // Reply indicates wheather to use authentication

            if( nread!=2 )
            {
                  //Reply must have exact 2 bytes
                  setProxyState(PROXYERROR );
                  return;
            }

            switch( buf[1] )
            {
            case '\x00':     // No authentation needed

                  socks5_connect();
                  m_nProxyState=3;
                  return;

            case '\x02':     // Authentation needed

                  socks5_auth();
                  m_nProxyState=2;
                  return;

            case '\xff':     //NO ACCEPTABLE METHODS
            default:

                  //'\x03' to '\x7F'      IANA ASSIGNED
                  //'\x80' to '\xFE'      RESERVED FOR PRIVATE METHODS
                  setProxyState(PROXYFAIL);
                  return;
            }
            break;

      case 2:                  //Reply indicates whether the uid and password sent are correct

            if( nread!=2 )
            {
                  //Reply must have exact 2 bytes
                  setProxyState(PROXYERROR);
                  return;
            }

            if( buf[1]!='\00')   //auth fails
            {
                  setProxyState(PROXYFAIL );
                  return;
            }

            // uid and password are correct, and now start a connection to the messenger's host
            socks5_connect();
            m_nProxyState=3;
            break;

      case 3:                  // Reply indicates whether the proxy has made a connection to the host.

            if( nread!=10 )
            {
                  //Reply must have exact 10 bytes
                  setProxyState(PROXYERROR );
                  return;
            }

            if(buf[1]!='\00' )   //connection fails
            {
                  setProxyState(PROXYFAIL );
                  return;
            }

            // Connection to the host is established
            setProxyState(PROXYHOSTCONNECTED );
            break;

      default:
            m_nProxyState=0;
            break;
    }
}


// Write data to the socket
01333 void NateonConnection::writeData(const QString& sData)
{
    int nBytesWritten;

    while ( m_bWriteLocked )
    {
          sleep(1);
#ifdef NETDEBUG
        kdDebug() << "Connection: WRITE DATA IS LOCKED TO AVOID WRITING OVERLAPPING DATA TO THE SOCKET." << endl;
#endif
    }

    // Lock the writing of data.
    m_bWriteLocked = true;

    if ( isConnected() )
    {
          QCString unicode;
          if ( m_pCurrentAccount->getProxyType() == 2 ) {
                /*! HTTP Proxy */
                QString sHttp( m_pHttpProxy->getPOST( sData ) );
                unicode = sHttp.utf8();
          } else {
                unicode = sData.utf8();
          }
            nBytesWritten = m_pSocket->writeBlock( unicode.data(), unicode.length() );
    }
    // Unlock the writing of data.
    m_bWriteLocked = false;

    emit messageSent( QString::fromUtf8(sData) );
}


// Write data to the socket without conversions
void NateonConnection::writeBinaryData(const QByteArray& data)
{
#ifdef NETDEBUG
    kdDebug() << "Connection: Writing data to the socket." << endl;
    kdDebug() << "Check for a lock" << endl;
#endif
    int nBytesWritten;

    while ( m_bWriteLocked )
    {
#ifdef NETDEBUG
        kdDebug() << "Connection: WRITE DATA IS LOCKED TO AVOID WRITING OVERLAPPING DATA TO THE SOCKET." << endl;
#endif
    }
    // Lock the writing of data.
    m_bWriteLocked = true;

    if ( isConnected() )
    {

#ifdef NETDEBUG
        kdDebug() << m_sIdentifier << " >>> [P2P message data]" << endl;
#endif

        int nDataLength = 0;

        nDataLength = data.size();

        // NOTE: Assumes the caller used the right encoding already...!
        //       using .utf8() here breaks the ascii zero chars again.
        nBytesWritten = m_pSocket->writeBlock( data.data(), nDataLength );
#ifdef NETDEBUG
        if ( nBytesWritten != nDataLength )
        {
              kdDebug() << "Connection: WARNING - Wanted to write " << data.size() << " bytes to the socket, wrote " << nBytesWritten << "." << endl;
        }
#endif
    }
#ifdef NETDEBUG
    else
    {
            kdDebug() << "[2] Connection: WARNING - Attempting to write data to a disconnected socket." << endl;
    }
#endif
    // Unlock the writing of data.
    m_bWriteLocked = false;
    emit messageSent(QString(data));
}


// Write data to the socket dealing requests and replies with the proxy
void NateonConnection::writeProxyData(const char *buf,int len)
{
      mproxywriteLocked_->lock();
    m_pSocket->writeBlock(buf, len);

    //socket_->flush();
      mproxywriteLocked_->unlock();
}


/*!
  \fn NateonConnection::socketclosed()
*/
void NateonConnection::socketclosed(int nFlag)
{
    kdDebug() << "socketclosed : " << nFlag << endl;
    
    // Q_UNUSED( nFlag );
      disconnectFromServer();
}


#include "nateonconnection.moc"

void NateonConnection::sendCommand_noTid(const QString& sPrefix, const QString& sText)
{
    // Send the data to the server
    QString sCommand = sPrefix + sText;
    writeData( sCommand );

    // Return the ack used
    return;
}


const QString NateonConnection::getUserID() const
{
    return m_pCurrentAccount->getID();
}

void NateonConnection::slotConnectionTimeout()
{
    kdDebug() << "slotConnectionTimeout" << endl;
      m_pRetryTimer.stop();
      m_pRetryTimer.start( 3000, TRUE );
      
      disconnectFromServer();
}

void NateonConnection::slotRetry()
{
      if ( ( m_pSocket->socketStatus() == KExtendedSocket::lookupInProgress ) ||
           ( m_pSocket->socketStatus() == KExtendedSocket::connected ) ||
           ( m_pSocket->socketStatus() == KExtendedSocket::connecting ) )
      {
            m_pRetryTimer.stop();
      }
      else
      {
#ifdef NETDEBUG
            kdDebug() << ">>> Retry Connectting... " << endl;
#endif
            m_pSocket->startAsyncConnect();
            connectionTimer_.stop();
            connectionTimer_.start(5000, true);
            // m_pRetryTimer.start( 3000, TRUE );
      }
}

void NateonConnection::slotRunCommand()
{
      if ( bRunning )
            return;
      bRunning = TRUE;

      while( !qCommand.isEmpty() )
      {
            QString *sCommand = qCommand.dequeue();
            if ( sCommand == 0 )
                  break;
            QStringList slCommand = QStringList::split( " ", *sCommand );
            sConfirmCommand = slCommand[0];
            sConfirmTID = slCommand[1];
            writeData( *sCommand );
            bRunning = TRUE;
            tCommandTimeout.start( 3000 );
      }
}

void NateonConnection::slotCommandTimeout()
{
#ifdef NETDEBUG
      kdDebug() << "ERROR :" << sConfirmCommand << " " << sConfirmTID << "... " << " Not Received!!!" << endl;
#endif
      bRunning = FALSE;
      slotRunCommand();
}

void NateonConnection::addCommand(int nTID, const QString & sPrefix, const QString & sText)
{
      QString *sCommand = new QString();
      *sCommand = sPrefix;
      *sCommand += " ";
      *sCommand += QString::number( nTID );
      *sCommand += " ";
      *sCommand += sText;
      *sCommand += "\r\n";

      int *myInt = new int();
      *myInt = nTID;
      
      nextCommand.insert( myInt, sCommand );
}

void NateonConnection::sendCmd(const QString & sCommand)
{
      writeData( sCommand );
}



Generated by  Doxygen 1.6.0   Back to index