libsolidcontrol
networking.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
00088 connect( Solid::Networking::notifier(), SIGNAL( statusChanged( uint ) ), this, SLOT( networkStatusChanged( Networking::Status ) ) );
00089
00090 if ( socket )
00091 {
00092
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
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
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
00148 ;
00149 }
00150 break;
00151 case DisconnectWait:
00152 switch ( netStatus )
00153 {
00154 case Solid::Networking::Connected:
00155
00156 mState = SocketConnected;
00157 if ( mAutoDisconnectTimer )
00158 {
00159 mAutoDisconnectTimer->stop();
00160 }
00161 break;
00162 default:
00163
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
00182
00183
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
00201 case DisconnectWait:
00202
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
00218
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
00237 break;
00238 case QAbstractSocket::BoundState:
00239 case QAbstractSocket::ConnectedState:
00240 case QAbstractSocket::ListeningState:
00241
00242 mState = SocketConnected;
00243 break;
00244 case QAbstractSocket::UnconnectedState:
00245
00246 break;
00247 case QAbstractSocket::ClosingState:
00248
00249 mState = SocketUnconnected;
00250 break;
00251 }
00252 break;
00253 case AwaitingNetworkConnection:
00254 switch ( socketState )
00255 {
00256 case QAbstractSocket::ConnectedState:
00257
00258 mState = SocketConnected;
00259
00260 break;
00261 default:
00262
00263 ;
00264 }
00265 break;
00266 case SocketConnected:
00267 switch ( socketState )
00268 {
00269 case QAbstractSocket::UnconnectedState:
00270 case QAbstractSocket::ClosingState:
00271
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
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"