• Skip to content
  • Skip to link menu
KDE 4.1 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

libsolidcontrol

networking.cpp

Go to the documentation of this file.
00001 /*  This file is part of the KDE project
00002     Copyright (C) 2006-2007 Will Stephenson <wstephenson@kde.org>
00003     Copyright (C) 2006-2007 Kevin Ottens <ervin@kde.org>
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License version 2 as published by the Free Software Foundation.
00008 
00009     This library is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012     Library General Public License for more details.
00013 
00014     You should have received a copy of the GNU Library General Public License
00015     along with this library; see the file COPYING.LIB.  If not, write to
00016     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017     Boston, MA 02110-1301, USA.
00018 
00019 */
00020 
00021 #include <QtNetwork/QAbstractSocket>
00022 #include <QtCore/QTimer>
00023 
00024 #include <kglobal.h>
00025 
00026 #include "networking_p.h"
00027 #include "networking.h"
00028 #include "org_kde_solid_networking.h"
00029 
00030 K_GLOBAL_STATIC(Solid::Control::NetworkingPrivate, globalNetworkControl)
00031 
00032 Solid::Control::NetworkingPrivate::NetworkingPrivate() : iface( 
00033         new OrgKdeSolidNetworkingInterface( "org.kde.Solid.Networking",
00034             "/status",
00035             QDBusConnection::sessionBus(),
00036             this ) )
00037 {
00038 }
00039 
00040 Solid::Control::NetworkingPrivate::~NetworkingPrivate()
00041 {
00042 }uint Solid::Control::NetworkingPrivate::requestConnection( QObject * receiver, const char * member )
00043 {
00044     connect( this, SIGNAL( connectionResult( bool ) ), receiver, member );
00045     return iface->requestConnection();
00046 }
00047 
00048 void Solid::Control::NetworkingPrivate::releaseConnection()
00049 {
00050     iface->releaseConnection();
00051 }
00052 
00053 Solid::Control::Networking::Result Solid::Control::NetworkingPrivate::beginManagingSocket( QAbstractSocket * socket, int autoDisconnectTimeout )
00054 {
00055     mManagedSockets.insert( socket, new ManagedSocketContainer( socket, autoDisconnectTimeout ) );
00056     return Solid::Control::Networking::Accepted;
00057 }
00058 
00059 void Solid::Control::NetworkingPrivate::stopManagingSocket( QAbstractSocket * socket )
00060 {
00061     ManagedSocketContainer * removed = mManagedSockets.take( socket );
00062     delete removed;
00063 }
00064 
00065 Solid::Control::Networking::Result Solid::Control::Networking::requestConnection( QObject * receiver, const char * member )
00066 {
00067     return static_cast<Solid::Control::Networking::Result>( globalNetworkControl->requestConnection( receiver, member ) );
00068 }
00069 
00070 void Solid::Control::Networking::releaseConnection()
00071 {
00072     globalNetworkControl->releaseConnection();
00073 }
00074 
00075 /*=========================================================================*/
00076 
00077 
00078 Solid::Control::ManagedSocketContainer::ManagedSocketContainer( QAbstractSocket * socket, int autoDisconnectTimeout ) : mSocket( socket ), mAutoDisconnectTimer( 0 )
00079 {
00080     if ( autoDisconnectTimeout >= 0 )
00081     {
00082         mAutoDisconnectTimer = new QTimer( this );
00083         mAutoDisconnectTimer->setSingleShot( true );
00084         mAutoDisconnectTimer->setInterval( autoDisconnectTimeout );
00085         connect( mAutoDisconnectTimer, SIGNAL( timeout() ), SLOT( autoDisconnect() ) );
00086     }
00087     // react to network management events
00088     connect( Solid::Networking::notifier(), SIGNAL( statusChanged( uint ) ), this, SLOT( networkStatusChanged( Networking::Status ) ) );
00089 
00090     if ( socket )
00091     {
00092         // react to socket events
00093         connect( socket, SIGNAL( destroyed() ), SLOT( socketDestroyed() ) );
00094         connect( socket, SIGNAL( error( QAbstractSocket::SocketError ) ), SLOT( socketError( QAbstractSocket::SocketError ) ) );
00095         connect( socket, SIGNAL( stateChanged( QAbstractSocket::SocketState ) ), SLOT( socketStateChanged( QAbstractSocket::SocketState ) ) );
00096         // initialise our state from that of the socket
00097         switch ( socket->state() )
00098         {
00099             case QAbstractSocket::UnconnectedState:
00100                 mState = SocketUnconnected;
00101                 break;
00102             case QAbstractSocket::HostLookupState:
00103             case QAbstractSocket::ConnectingState:
00104                 mState = SocketConnecting;
00105                 break;
00106             case QAbstractSocket::ConnectedState:
00107             case QAbstractSocket::ClosingState:
00108                 mState = SocketConnected;
00109                 break;
00110             default:
00111                 mState = SocketUnconnected;
00112         }
00113     }
00114 }
00115 
00116 void Solid::Control::ManagedSocketContainer::networkStatusChanged( Solid::Networking::Status netStatus )
00117 {
00118     switch ( mState )
00119     {
00120         case SocketUnconnected:
00121             break;
00122         case SocketConnecting:
00123             break;
00124         case AwaitingNetworkConnection:
00125             switch ( netStatus )
00126             {
00127                 case Solid::Networking::Connected:
00128                     performConnectToHost();
00129                     break;
00130                 default:
00131                     //do nothing
00132                     ;
00133             }
00134             break;
00135         case SocketConnected:
00136             switch ( netStatus )
00137             {
00138                 case Solid::Networking::Unconnected:
00139                 case Solid::Networking::Disconnecting:
00140                     mState = DisconnectWait;
00141                     if ( mAutoDisconnectTimer )
00142                     {
00143                         mAutoDisconnectTimer->start();
00144                     }
00145                     break;
00146                 default:
00147                     // do nothing
00148                     ;
00149             }
00150             break;
00151         case DisconnectWait:
00152             switch ( netStatus )
00153             {
00154                 case Solid::Networking::Connected:
00155                     // RECOVERED
00156                     mState = SocketConnected;
00157                     if ( mAutoDisconnectTimer )
00158                     {
00159                         mAutoDisconnectTimer->stop();
00160                     }
00161                     break;
00162                 default:
00163                     // do nothing
00164                     ;
00165             }
00166             break;
00167     }
00168 }
00169 
00170 void Solid::Control::ManagedSocketContainer::socketError( QAbstractSocket::SocketError socketError )
00171 {
00172     switch ( mState )
00173     {
00174         case SocketUnconnected:
00175             break;
00176         case SocketConnecting:
00177             switch ( socketError )
00178             {
00179                 case QAbstractSocket::HostNotFoundError:
00180                 case QAbstractSocket::NetworkError:
00181                     // socket tried to resolve and failed
00182                     // Either the host doesn't exist at all
00183                     // or the resolve failed because we're offline, so request that we go online
00184                     if ( Solid::Networking::status() != Solid::Networking::Connected )
00185                     {
00186                         mState = AwaitingNetworkConnection;
00187                         globalNetworkControl->requestConnection();
00188                     }
00189                     else
00190                     {
00191                         mState = SocketUnconnected;
00192                     }
00193                     break;
00194                 default:
00195                     mState = SocketUnconnected;
00196             }
00197             break;
00198         case AwaitingNetworkConnection:
00199         case SocketConnected:
00200             // setup automatic reconnect now when/if we impl this
00201         case DisconnectWait:
00202             // maybe check the socket state that it thinks it is now unconnected too
00203             mState = SocketUnconnected;
00204             break;
00205     }
00206 }
00207 
00208 void Solid::Control::ManagedSocketContainer::socketStateChanged( QAbstractSocket::SocketState socketState )
00209 {
00210     switch ( mState )
00211     {
00212         case SocketUnconnected:
00213             switch ( socketState )
00214             {
00215                 case QAbstractSocket::HostLookupState:
00216                 case QAbstractSocket::ConnectingState:
00217                     // the socket is trying to connect, cache its connection parameter in case it
00218                     // fails and we want to reconnect it when the network is available.
00219                     mState = SocketConnecting;
00220                     if ( mSocket )
00221                     {
00222                         mPeerName = mSocket->peerName();
00223                         mPeerPort = mSocket->peerPort();
00224                         mSocketOpenMode = mSocket->openMode();
00225                     }
00226                     break;
00227                 default:
00228                     ;
00229             }
00230             break;
00231         case SocketConnecting:
00232             switch ( socketState )
00233             {
00234                 case QAbstractSocket::HostLookupState:
00235                 case QAbstractSocket::ConnectingState:
00236                     // still connecting, do nothing
00237                     break;
00238                 case QAbstractSocket::BoundState:
00239                 case QAbstractSocket::ConnectedState:
00240                 case QAbstractSocket::ListeningState:
00241                     // socket connected unaided
00242                     mState = SocketConnected;
00243                     break;
00244                 case QAbstractSocket::UnconnectedState:
00245                     // this state is preceded by ClosingState, so no action needed
00246                     break;
00247                 case QAbstractSocket::ClosingState:
00248                     // it's unlikely that an unconnected socket can go to this state, but...
00249                     mState = SocketUnconnected;
00250                     break;
00251             }
00252             break;
00253         case AwaitingNetworkConnection:
00254             switch ( socketState )
00255             {
00256                 case QAbstractSocket::ConnectedState:
00257                     // somehow the socket connected itself when it shouldn't have been able to.
00258                     mState = SocketConnected;
00259 
00260                     break;
00261                 default:
00262                     //do nothing
00263                     ;
00264             }
00265             break;
00266         case SocketConnected:
00267             switch ( socketState )
00268             {
00269                 case QAbstractSocket::UnconnectedState:
00270                 case QAbstractSocket::ClosingState:
00271                     // socket disconnected
00272                     mState = SocketUnconnected;
00273                     break;
00274                 case QAbstractSocket::ConnectingState:
00275                     mState = SocketConnected;
00276                     break;
00277                 default:
00278                     ;
00279             }
00280             break;
00281         case DisconnectWait:
00282             switch ( socketState )
00283             {
00284                 case QAbstractSocket::UnconnectedState:
00285                 case QAbstractSocket::ClosingState:
00286                     // socket disconnected anyway
00287                     mState = SocketUnconnected;
00288                     if ( mAutoDisconnectTimer )
00289                     {
00290                         mAutoDisconnectTimer->stop();
00291                     }
00292                     break;
00293                 default:
00294                     break;
00295             }
00296             break;
00297     }
00298 }
00299 
00300 void Solid::Control::ManagedSocketContainer::autoDisconnect()
00301 {
00302     if ( mAutoDisconnectTimer && mSocket )
00303         mSocket->disconnectFromHost();
00304 }
00305 
00306 void Solid::Control::ManagedSocketContainer::socketDestroyed()
00307 {
00308     mSocket = 0;
00309     delete mAutoDisconnectTimer;
00310     mAutoDisconnectTimer = 0;
00311     disconnect( globalNetworkControl );
00312 }
00313 
00314 void Solid::Control::ManagedSocketContainer::performConnectToHost()
00315 {
00316     if ( mSocket )
00317     {
00318         mSocket->connectToHost( mPeerName, mPeerPort, mSocketOpenMode );
00319     }
00320 }
00321 
00322 #include "networking_p.moc"
00323 #include "networking.moc"

libsolidcontrol

Skip menu "libsolidcontrol"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

API Reference

Skip menu "API Reference"
  • KWin
  •   KWin Libraries
  • Libraries
  •   libkworkspace
  •   libplasma
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal