Connection.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2005-2007 by Peter Dimov.
00004 
00005 This file is part of Calitko (http://www.calitko.org).
00006 
00007 Calitko is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or
00010 (at your option) any later version.
00011 
00012 Calitko is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Calitko; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 */
00022 
00023 #include "Qt.h"
00024 #include "Imports.h"
00025 #include "Connection.h"
00026 
00027 using namespace Protocols::Transports;
00028 
00029 namespace Protocols {
00030 namespace Transports {
00031 
00032 class ConnectionPrivate
00033 {
00034 public:
00035     NodeAddress         remoteNodeAddress;
00036     Connection::State   state;
00037 
00038     ConnectionPrivate()
00039      :  remoteNodeAddress(), state (Connection::DisconnectedState)
00040     {}
00041 } p;
00042 
00043 } // namespace Transports;
00044 } // namespace Protocols;
00045 
00046 Connection::State Connection::state() const
00047 { return p->state; }
00048 
00049 NodeAddress Connection::remoteNodeAddress() const
00050 { return p->remoteNodeAddress; }
00051 
00052 void Connection::setState (Connection::State state)
00053 { p->state = state; }
00054 
00055 void Connection::setRemoteNodeAddress (const NodeAddress &remoteNodeAddress)
00056 { p->remoteNodeAddress = remoteNodeAddress; }
00057 
00058 Connection::Connection()
00059     : p (new ConnectionPrivate)
00060 {
00061 }
00062 
00063 Connection::~Connection()
00064 {
00065     //Q_ASSERT (state() == DisconnectedState);
00066 }
00067 
00068 void Connection::connectToNode (NodeAddress nodeAddress)
00069 {
00070     Q_ASSERT (!nodeAddress.isNull());
00071     Q_ASSERT (p->state == DisconnectedState);
00072 
00073     p->remoteNodeAddress = nodeAddress;
00074     QHostAddress hostAddress = nodeAddress.hostAddress();
00075     if (hostAddress.isNull()) {
00076         setState (ResolvingHostNameState);
00077 qDebug() << "Resolving " << nodeAddress.hostName();
00078         QHostInfo::lookupHost (nodeAddress.hostName(), this,
00079                                SLOT (lookupFinished (QHostInfo)));
00080     } else {
00081         setState (ConnectingState);
00082         doConnectToNode (nodeAddress);
00083     }
00084 }
00085 
00086 void Connection::lookupFinished (QHostInfo hostInfo)
00087 {
00088     if (hostInfo.addresses().count() == 0) {
00089 qDebug() << "Name resolution failed for " << hostInfo.hostName();
00090         emit connectionFailed();
00091         setState (DisconnectedState);
00092     } else {
00093         setState (ConnectingState);
00094         // \todo We now only try the first IP. Should we try more? How long to wait?
00095         QHostAddress hostAddress = hostInfo.addresses().first();
00096 qDebug() << "Found address " << hostAddress.toString() << " for "<< hostInfo.hostName();
00097         // This call overwrites the hostName field of remoteNodeAddress:
00098         p->remoteNodeAddress.setHostAddress (hostAddress);
00099         // Call implementation:
00100         doConnectToNode (p->remoteNodeAddress);
00101     }
00102 }
00103 
00104 void Connection::disconnectFromNode()
00105 {
00106     setState (DisconnectingState);
00107     doDisconnectFromNode();
00108 }
00109 
00110 bool Connection::isSequential() const
00111 {
00112     return true;
00113 }