realtimenetprots/sipfw/SampleApp/socketengine/Src/SIPExSocketEngine.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 
       
     2 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 // All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of "Eclipse Public License v1.0"
       
     6 // which accompanies this distribution, and is available
       
     7 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 //
       
     9 // Initial Contributors:
       
    10 // Nokia Corporation - initial contribution.
       
    11 //
       
    12 // Contributors:
       
    13 //
       
    14 // Description:
       
    15 //
       
    16 
       
    17 
       
    18 
       
    19 // INCLUDES
       
    20 #include    "SIPExSocketEngine.h"
       
    21 #include    "SIPExSocketWriter.h"
       
    22 #include    "SIPExSocketReader.h"
       
    23 #include    "SIPExTimeOutTimer.h"
       
    24 #include    <e32svr.h>
       
    25 #include    <commdbconnpref.h>
       
    26 
       
    27 // CONSTANTS
       
    28 const TInt KGamePort( 10011 );
       
    29 
       
    30 // -----------------------------------------------------------------------------
       
    31 // CSIPExSocketEngine::NewL
       
    32 // Creates the instance of class and returns it.
       
    33 // -----------------------------------------------------------------------------
       
    34 //
       
    35 EXPORT_C CSIPExSocketEngine* CSIPExSocketEngine::NewL( 
       
    36     MSIPExSocketEngineObserver& aObserver )
       
    37     {
       
    38     CSIPExSocketEngine* self = CSIPExSocketEngine::NewLC( aObserver );
       
    39     CleanupStack::Pop(self);
       
    40     return self;
       
    41     }
       
    42 
       
    43 // -----------------------------------------------------------------------------
       
    44 // CSIPExSocketEngine::NewLC
       
    45 // Creates the instance of class and pushes it to the CleanupStack and return
       
    46 // it.
       
    47 // -----------------------------------------------------------------------------
       
    48 //    
       
    49 EXPORT_C CSIPExSocketEngine* CSIPExSocketEngine::NewLC( 
       
    50     MSIPExSocketEngineObserver& aObserver )
       
    51     {
       
    52     CSIPExSocketEngine* self = new (ELeave) CSIPExSocketEngine( aObserver );
       
    53     CleanupStack::PushL(self);
       
    54     self->ConstructL();
       
    55     return self;
       
    56     }
       
    57 
       
    58 // -----------------------------------------------------------------------------
       
    59 // CSIPExSocketEngine::CSIPExSocketEngine
       
    60 // Calls base classes constructor with priority value. Add class to the 
       
    61 // active sheduler.
       
    62 // -----------------------------------------------------------------------------
       
    63 //
       
    64 CSIPExSocketEngine::CSIPExSocketEngine( MSIPExSocketEngineObserver& aObserver )
       
    65 :   CActive( EPriorityStandard ), iObserver( aObserver )
       
    66     {
       
    67     CActiveScheduler::Add( this );
       
    68     }
       
    69 
       
    70 // -----------------------------------------------------------------------------
       
    71 // CSIPExSocketEngine::~CSIPExSocketEngine
       
    72 // Cancels any outstanding requests and deletes members.
       
    73 // -----------------------------------------------------------------------------
       
    74 //
       
    75 EXPORT_C CSIPExSocketEngine::~CSIPExSocketEngine()
       
    76     {
       
    77     Cancel();
       
    78     
       
    79 	if ( iTimer )
       
    80 		{
       
    81 		iTimer->Cancel();
       
    82 		delete iTimer;
       
    83 		}
       
    84 
       
    85 	if ( iWriter )
       
    86 		{
       
    87 		iWriter->Cancel();
       
    88 		delete iWriter;
       
    89 		}
       
    90 
       
    91 	if ( iReader )
       
    92 		{
       
    93 		iReader->Cancel();
       
    94 		delete iReader;
       
    95 		}
       
    96 
       
    97     iListenSocket.Close();
       
    98     iDataSocket.Close();
       
    99     iConnection.Close();
       
   100     iSocketServer.Close();
       
   101     }
       
   102 
       
   103 // -----------------------------------------------------------------------------
       
   104 // CSIPExSocketEngine::ConstructL
       
   105 // The socketserver is connected and members created.
       
   106 // -----------------------------------------------------------------------------
       
   107 //
       
   108 void CSIPExSocketEngine::ConstructL()
       
   109     {
       
   110     iState = ENotConnected;
       
   111 
       
   112     iTimer = CSIPExTimeOutTimer::NewL( *this );
       
   113 
       
   114     // Open channel to Socket Server
       
   115 	User::LeaveIfError( iSocketServer.Connect() );
       
   116 
       
   117     iReader = CSIPExSocketReader::NewL( iDataSocket, *this );
       
   118     iWriter = CSIPExSocketWriter::NewL( iDataSocket, *this );
       
   119     }
       
   120 
       
   121 // -----------------------------------------------------------------------------
       
   122 // CSIPExSocketEngine::DoCancel
       
   123 // From CActive. Cancels any outstanding request according the engine state.
       
   124 // -----------------------------------------------------------------------------
       
   125 //
       
   126 void CSIPExSocketEngine::DoCancel()
       
   127     {    
       
   128     iTimer->Cancel();
       
   129 
       
   130     // Cancel appropriate request to socket
       
   131 	switch ( iState )
       
   132 		{
       
   133 	    case EConnecting:
       
   134 		    iDataSocket.CancelConnect();
       
   135 		    break;
       
   136 
       
   137         case EListening:
       
   138             iListenSocket.CancelAccept();
       
   139             break;
       
   140         
       
   141         default:
       
   142             break;
       
   143         }    
       
   144         
       
   145     iConnection.Close();
       
   146     }
       
   147 
       
   148 // -----------------------------------------------------------------------------
       
   149 // CSIPExSocketEngine::RunL
       
   150 // From CActive. Handles the state changes and notifing the observer.
       
   151 // -----------------------------------------------------------------------------
       
   152 //
       
   153 void CSIPExSocketEngine::RunL()
       
   154     {
       
   155     iTimer->Cancel();
       
   156 
       
   157     switch( iState )
       
   158         {
       
   159         case EConnecting:
       
   160             if( iStatus.Int() == KErrNone )
       
   161                 {
       
   162                 ChangeStateAndNotify( EConnected );
       
   163                 Read();
       
   164                 }
       
   165             else
       
   166                 {
       
   167                 ChangeStateAndNotify( ENotConnected );
       
   168                 }
       
   169             break;
       
   170 
       
   171         case EListening:
       
   172 			{
       
   173             iListenSocket.Close();
       
   174             if( iStatus.Int() == KErrNone )
       
   175                 {
       
   176                 ChangeStateAndNotify( EConnected );
       
   177                 Read();
       
   178                 }
       
   179             else
       
   180                 {
       
   181                 ChangeStateAndNotify( ENotConnected );
       
   182                 }
       
   183 			}
       
   184             break;
       
   185 
       
   186         case ETimedOut:
       
   187             if( iStatus.Int() == KErrNone )
       
   188                 {
       
   189                 iObserver.SocketState( ETimedOut );
       
   190                 iState = ENotConnected;
       
   191                 }
       
   192             else
       
   193                 {
       
   194                 ChangeStateAndNotify( ENotConnected );
       
   195                 }
       
   196             break;
       
   197 
       
   198         default:
       
   199             iObserver.SocketState( iStatus.Int() );
       
   200         }
       
   201     }
       
   202 
       
   203 // -----------------------------------------------------------------------------
       
   204 // CSIPExSocketEngine::ConnectL
       
   205 // Connects the socket to the remote host. Asynchronous.
       
   206 // -----------------------------------------------------------------------------
       
   207 //
       
   208 EXPORT_C void CSIPExSocketEngine::ConnectL( 
       
   209     const TUint32 aIapId, 
       
   210     const TInetAddr& aIPAddress )
       
   211     {
       
   212     if( iState != ENotConnected )
       
   213         {
       
   214         return;
       
   215         }
       
   216 
       
   217     // Make first sure that underlying interface is active
       
   218     StartInterfaceL( aIapId );
       
   219     
       
   220 	// Open a TCP socket
       
   221 	User::LeaveIfError( iDataSocket.Open( 
       
   222 	    iSocketServer, KAfInet, KSockStream, KProtocolInetTcp, iConnection ) );
       
   223     
       
   224     iAddress = aIPAddress;
       
   225 	iAddress.SetPort( KGamePort );
       
   226 
       
   227     // The Connect() allocate local address automatically if 
       
   228     // not bind yet.
       
   229     iDataSocket.Connect( iAddress, iStatus );
       
   230          
       
   231     iState = EConnecting;
       
   232     SetActive();
       
   233     iTimer->After( KTimeOut );
       
   234     }
       
   235 
       
   236 // -----------------------------------------------------------------------------
       
   237 // CSIPExSocketEngine::Write
       
   238 // Starts the asynchronous writing
       
   239 // -----------------------------------------------------------------------------
       
   240 //
       
   241 EXPORT_C void CSIPExSocketEngine::Write( const TDesC8& aTxt )
       
   242     {
       
   243     if( iState == EConnected && !iWriter->IsActive() )
       
   244         {
       
   245         iWriter->Write( aTxt );
       
   246         }
       
   247     }
       
   248 
       
   249 // -----------------------------------------------------------------------------
       
   250 // CSIPExSocketEngine::Read
       
   251 // Starts the asynchronous reading.
       
   252 // -----------------------------------------------------------------------------
       
   253 //
       
   254 EXPORT_C void CSIPExSocketEngine::Read()
       
   255     {
       
   256     if( iState == EConnected && !iReader->IsActive() )
       
   257         {
       
   258         iReader->Read();
       
   259         }
       
   260     }
       
   261 
       
   262 // -----------------------------------------------------------------------------
       
   263 // CSIPExSocketEngine::Stop
       
   264 // Cancelling any outstanding read/write request.
       
   265 // -----------------------------------------------------------------------------
       
   266 //
       
   267 EXPORT_C void CSIPExSocketEngine::Stop()
       
   268     {
       
   269     switch( iState )
       
   270         {
       
   271         case EConnected:
       
   272 			{
       
   273             iWriter->Cancel();
       
   274             iReader->Cancel();
       
   275             TRequestStatus status;
       
   276             iDataSocket.Shutdown( RSocket::EImmediate, status );
       
   277             User::WaitForRequest( status);
       
   278             iConnection.Close();
       
   279             ChangeStateAndNotify( ENotConnected );
       
   280 			}
       
   281             break;
       
   282         case EListening:
       
   283         case EConnecting:
       
   284             Cancel();
       
   285             break;
       
   286         default:
       
   287             break;
       
   288         }
       
   289     }
       
   290 
       
   291 // -----------------------------------------------------------------------------
       
   292 // CSIPExSocketEngine::StartListeningL
       
   293 // Resolves the local address and starts listening game port. Asynchronous.
       
   294 // -----------------------------------------------------------------------------
       
   295 //
       
   296 EXPORT_C TInetAddr& CSIPExSocketEngine::StartListeningL( const TUint32 aIapId )
       
   297     {
       
   298     StartInterfaceL( aIapId );
       
   299     ResolveLocalIPAddressL();
       
   300     iAddress.SetPort( KGamePort );
       
   301     User::LeaveIfError( iListenSocket.Open( 
       
   302             iSocketServer, KAfInet, KSockStream, KProtocolInetTcp ) );
       
   303     User::LeaveIfError( iDataSocket.Open( iSocketServer ) );
       
   304     User::LeaveIfError( iListenSocket.Bind( iAddress ) );
       
   305     
       
   306     User::LeaveIfError( iListenSocket.Listen( 1 ) );
       
   307 
       
   308     iListenSocket.Accept( iDataSocket, iStatus );    
       
   309     iState = EListening;
       
   310     SetActive();
       
   311 
       
   312     return iAddress;
       
   313     }
       
   314     
       
   315 // -----------------------------------------------------------------------------
       
   316 // CSIPExSocketEngine::StartInterfaceL
       
   317 // Activates PDP ctx
       
   318 // -----------------------------------------------------------------------------
       
   319 //
       
   320 void CSIPExSocketEngine::StartInterfaceL( const TUint32 aIapId )
       
   321     {
       
   322     if( !iConnection.SubSessionHandle() )
       
   323         { 
       
   324         User::LeaveIfError( iConnection.Open( iSocketServer ) );
       
   325         }
       
   326 
       
   327     TCommDbConnPref prefs;
       
   328     prefs.SetDialogPreference( ECommDbDialogPrefDoNotPrompt );
       
   329     prefs.SetDirection( ECommDbConnectionDirectionOutgoing );
       
   330     prefs.SetIapId( aIapId );
       
   331 
       
   332     User::LeaveIfError( iConnection.Start( prefs ) );
       
   333     }
       
   334 
       
   335 // -----------------------------------------------------------------------------
       
   336 // CSIPExSocketEngine::ResolveLocalIPAddressL
       
   337 // Resolves the local IP address.
       
   338 // -----------------------------------------------------------------------------
       
   339 //
       
   340 void CSIPExSocketEngine::ResolveLocalIPAddressL()
       
   341     {
       
   342     RHostResolver hostResolver;
       
   343     TNameEntry entry;
       
   344 
       
   345     User::LeaveIfError( hostResolver.Open( iSocketServer, KAfInet, 
       
   346                                           KProtocolInetTcp, iConnection ));
       
   347     CleanupClosePushL( hostResolver );
       
   348  
       
   349     User::LeaveIfError( hostResolver.GetByName( TPtrC(), entry ) );
       
   350     if ( !TInetAddr::Cast( entry().iAddr ).IsWildAddr() )
       
   351          {
       
   352          iAddress = TInetAddr::Cast( entry().iAddr );
       
   353          }
       
   354          
       
   355     CleanupStack::PopAndDestroy(); // hostResolver
       
   356     }
       
   357 
       
   358 // -----------------------------------------------------------------------------
       
   359 // CSIPExSocketEngine::TimerExpired
       
   360 // Callback from the timeout notifier. Completes the request with error code
       
   361 // KErrNone and state ETimedOut.
       
   362 // -----------------------------------------------------------------------------
       
   363 //
       
   364 void CSIPExSocketEngine::TimerExpired()
       
   365     {
       
   366     Cancel();
       
   367 	iState = ETimedOut;
       
   368 	
       
   369     TRequestStatus* status = &iStatus;		
       
   370     SetActive();
       
   371 	User::RequestComplete( status, KErrNone );
       
   372     }
       
   373 
       
   374 // -----------------------------------------------------------------------------
       
   375 // CSIPExSocketEngine::MessageReceived
       
   376 // Notifies the observer.
       
   377 // -----------------------------------------------------------------------------
       
   378 //
       
   379 void CSIPExSocketEngine::MessageReceived( TDesC8& aBuffer )
       
   380     {
       
   381     iObserver.SocketData( aBuffer );
       
   382     }
       
   383 
       
   384 // -----------------------------------------------------------------------------
       
   385 // CSIPExSocketEngine::ErrorInReading
       
   386 // Completes the request with error code.
       
   387 // -----------------------------------------------------------------------------
       
   388 //
       
   389 void CSIPExSocketEngine::ErrorInReading( TInt aError )
       
   390     {
       
   391     TRequestStatus* status = &iStatus;		
       
   392     SetActive();
       
   393 	User::RequestComplete( status, aError );
       
   394     }
       
   395 
       
   396 // From MWriterNotifier
       
   397 // -----------------------------------------------------------------------------
       
   398 // CSIPExSocketEngine::WriteDone
       
   399 // 
       
   400 // -----------------------------------------------------------------------------
       
   401 //
       
   402 void CSIPExSocketEngine::WriteDone()
       
   403     {
       
   404     // Nothing to do
       
   405     }
       
   406 
       
   407 // -----------------------------------------------------------------------------
       
   408 // CSIPExSocketEngine::ErrorInWriting
       
   409 // Completes the request with error code.
       
   410 // -----------------------------------------------------------------------------
       
   411 //
       
   412 void CSIPExSocketEngine::ErrorInWriting( TInt aError )
       
   413     {
       
   414     TRequestStatus* status = &iStatus;		
       
   415     SetActive();
       
   416 	User::RequestComplete( status, aError );
       
   417     }
       
   418 
       
   419 // -----------------------------------------------------------------------------
       
   420 // CSIPExSocketEngine::ChangeStateAndNotify
       
   421 // Changes new state and notifies observer.
       
   422 // -----------------------------------------------------------------------------
       
   423 //
       
   424 void CSIPExSocketEngine::ChangeStateAndNotify( TSocketEngineState aNewState )
       
   425     {
       
   426     iState = aNewState;
       
   427     iObserver.SocketState( iState );
       
   428     }
       
   429 
       
   430 // End of file