realtimenetprots/sipfw/SampleApp/socketengine/Src/SIPExSocketEngine.cpp
changeset 0 307788aac0a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SampleApp/socketengine/Src/SIPExSocketEngine.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,430 @@
+
+// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+
+
+// INCLUDES
+#include    "SIPExSocketEngine.h"
+#include    "SIPExSocketWriter.h"
+#include    "SIPExSocketReader.h"
+#include    "SIPExTimeOutTimer.h"
+#include    <e32svr.h>
+#include    <commdbconnpref.h>
+
+// CONSTANTS
+const TInt KGamePort( 10011 );
+
+// -----------------------------------------------------------------------------
+// CSIPExSocketEngine::NewL
+// Creates the instance of class and returns it.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSIPExSocketEngine* CSIPExSocketEngine::NewL( 
+    MSIPExSocketEngineObserver& aObserver )
+    {
+    CSIPExSocketEngine* self = CSIPExSocketEngine::NewLC( aObserver );
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPExSocketEngine::NewLC
+// Creates the instance of class and pushes it to the CleanupStack and return
+// it.
+// -----------------------------------------------------------------------------
+//    
+EXPORT_C CSIPExSocketEngine* CSIPExSocketEngine::NewLC( 
+    MSIPExSocketEngineObserver& aObserver )
+    {
+    CSIPExSocketEngine* self = new (ELeave) CSIPExSocketEngine( aObserver );
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPExSocketEngine::CSIPExSocketEngine
+// Calls base classes constructor with priority value. Add class to the 
+// active sheduler.
+// -----------------------------------------------------------------------------
+//
+CSIPExSocketEngine::CSIPExSocketEngine( MSIPExSocketEngineObserver& aObserver )
+:   CActive( EPriorityStandard ), iObserver( aObserver )
+    {
+    CActiveScheduler::Add( this );
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPExSocketEngine::~CSIPExSocketEngine
+// Cancels any outstanding requests and deletes members.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CSIPExSocketEngine::~CSIPExSocketEngine()
+    {
+    Cancel();
+    
+	if ( iTimer )
+		{
+		iTimer->Cancel();
+		delete iTimer;
+		}
+
+	if ( iWriter )
+		{
+		iWriter->Cancel();
+		delete iWriter;
+		}
+
+	if ( iReader )
+		{
+		iReader->Cancel();
+		delete iReader;
+		}
+
+    iListenSocket.Close();
+    iDataSocket.Close();
+    iConnection.Close();
+    iSocketServer.Close();
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPExSocketEngine::ConstructL
+// The socketserver is connected and members created.
+// -----------------------------------------------------------------------------
+//
+void CSIPExSocketEngine::ConstructL()
+    {
+    iState = ENotConnected;
+
+    iTimer = CSIPExTimeOutTimer::NewL( *this );
+
+    // Open channel to Socket Server
+	User::LeaveIfError( iSocketServer.Connect() );
+
+    iReader = CSIPExSocketReader::NewL( iDataSocket, *this );
+    iWriter = CSIPExSocketWriter::NewL( iDataSocket, *this );
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPExSocketEngine::DoCancel
+// From CActive. Cancels any outstanding request according the engine state.
+// -----------------------------------------------------------------------------
+//
+void CSIPExSocketEngine::DoCancel()
+    {    
+    iTimer->Cancel();
+
+    // Cancel appropriate request to socket
+	switch ( iState )
+		{
+	    case EConnecting:
+		    iDataSocket.CancelConnect();
+		    break;
+
+        case EListening:
+            iListenSocket.CancelAccept();
+            break;
+        
+        default:
+            break;
+        }    
+        
+    iConnection.Close();
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPExSocketEngine::RunL
+// From CActive. Handles the state changes and notifing the observer.
+// -----------------------------------------------------------------------------
+//
+void CSIPExSocketEngine::RunL()
+    {
+    iTimer->Cancel();
+
+    switch( iState )
+        {
+        case EConnecting:
+            if( iStatus.Int() == KErrNone )
+                {
+                ChangeStateAndNotify( EConnected );
+                Read();
+                }
+            else
+                {
+                ChangeStateAndNotify( ENotConnected );
+                }
+            break;
+
+        case EListening:
+			{
+            iListenSocket.Close();
+            if( iStatus.Int() == KErrNone )
+                {
+                ChangeStateAndNotify( EConnected );
+                Read();
+                }
+            else
+                {
+                ChangeStateAndNotify( ENotConnected );
+                }
+			}
+            break;
+
+        case ETimedOut:
+            if( iStatus.Int() == KErrNone )
+                {
+                iObserver.SocketState( ETimedOut );
+                iState = ENotConnected;
+                }
+            else
+                {
+                ChangeStateAndNotify( ENotConnected );
+                }
+            break;
+
+        default:
+            iObserver.SocketState( iStatus.Int() );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPExSocketEngine::ConnectL
+// Connects the socket to the remote host. Asynchronous.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPExSocketEngine::ConnectL( 
+    const TUint32 aIapId, 
+    const TInetAddr& aIPAddress )
+    {
+    if( iState != ENotConnected )
+        {
+        return;
+        }
+
+    // Make first sure that underlying interface is active
+    StartInterfaceL( aIapId );
+    
+	// Open a TCP socket
+	User::LeaveIfError( iDataSocket.Open( 
+	    iSocketServer, KAfInet, KSockStream, KProtocolInetTcp, iConnection ) );
+    
+    iAddress = aIPAddress;
+	iAddress.SetPort( KGamePort );
+
+    // The Connect() allocate local address automatically if 
+    // not bind yet.
+    iDataSocket.Connect( iAddress, iStatus );
+         
+    iState = EConnecting;
+    SetActive();
+    iTimer->After( KTimeOut );
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPExSocketEngine::Write
+// Starts the asynchronous writing
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPExSocketEngine::Write( const TDesC8& aTxt )
+    {
+    if( iState == EConnected && !iWriter->IsActive() )
+        {
+        iWriter->Write( aTxt );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPExSocketEngine::Read
+// Starts the asynchronous reading.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPExSocketEngine::Read()
+    {
+    if( iState == EConnected && !iReader->IsActive() )
+        {
+        iReader->Read();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPExSocketEngine::Stop
+// Cancelling any outstanding read/write request.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CSIPExSocketEngine::Stop()
+    {
+    switch( iState )
+        {
+        case EConnected:
+			{
+            iWriter->Cancel();
+            iReader->Cancel();
+            TRequestStatus status;
+            iDataSocket.Shutdown( RSocket::EImmediate, status );
+            User::WaitForRequest( status);
+            iConnection.Close();
+            ChangeStateAndNotify( ENotConnected );
+			}
+            break;
+        case EListening:
+        case EConnecting:
+            Cancel();
+            break;
+        default:
+            break;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPExSocketEngine::StartListeningL
+// Resolves the local address and starts listening game port. Asynchronous.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInetAddr& CSIPExSocketEngine::StartListeningL( const TUint32 aIapId )
+    {
+    StartInterfaceL( aIapId );
+    ResolveLocalIPAddressL();
+    iAddress.SetPort( KGamePort );
+    User::LeaveIfError( iListenSocket.Open( 
+            iSocketServer, KAfInet, KSockStream, KProtocolInetTcp ) );
+    User::LeaveIfError( iDataSocket.Open( iSocketServer ) );
+    User::LeaveIfError( iListenSocket.Bind( iAddress ) );
+    
+    User::LeaveIfError( iListenSocket.Listen( 1 ) );
+
+    iListenSocket.Accept( iDataSocket, iStatus );    
+    iState = EListening;
+    SetActive();
+
+    return iAddress;
+    }
+    
+// -----------------------------------------------------------------------------
+// CSIPExSocketEngine::StartInterfaceL
+// Activates PDP ctx
+// -----------------------------------------------------------------------------
+//
+void CSIPExSocketEngine::StartInterfaceL( const TUint32 aIapId )
+    {
+    if( !iConnection.SubSessionHandle() )
+        { 
+        User::LeaveIfError( iConnection.Open( iSocketServer ) );
+        }
+
+    TCommDbConnPref prefs;
+    prefs.SetDialogPreference( ECommDbDialogPrefDoNotPrompt );
+    prefs.SetDirection( ECommDbConnectionDirectionOutgoing );
+    prefs.SetIapId( aIapId );
+
+    User::LeaveIfError( iConnection.Start( prefs ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPExSocketEngine::ResolveLocalIPAddressL
+// Resolves the local IP address.
+// -----------------------------------------------------------------------------
+//
+void CSIPExSocketEngine::ResolveLocalIPAddressL()
+    {
+    RHostResolver hostResolver;
+    TNameEntry entry;
+
+    User::LeaveIfError( hostResolver.Open( iSocketServer, KAfInet, 
+                                          KProtocolInetTcp, iConnection ));
+    CleanupClosePushL( hostResolver );
+ 
+    User::LeaveIfError( hostResolver.GetByName( TPtrC(), entry ) );
+    if ( !TInetAddr::Cast( entry().iAddr ).IsWildAddr() )
+         {
+         iAddress = TInetAddr::Cast( entry().iAddr );
+         }
+         
+    CleanupStack::PopAndDestroy(); // hostResolver
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPExSocketEngine::TimerExpired
+// Callback from the timeout notifier. Completes the request with error code
+// KErrNone and state ETimedOut.
+// -----------------------------------------------------------------------------
+//
+void CSIPExSocketEngine::TimerExpired()
+    {
+    Cancel();
+	iState = ETimedOut;
+	
+    TRequestStatus* status = &iStatus;		
+    SetActive();
+	User::RequestComplete( status, KErrNone );
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPExSocketEngine::MessageReceived
+// Notifies the observer.
+// -----------------------------------------------------------------------------
+//
+void CSIPExSocketEngine::MessageReceived( TDesC8& aBuffer )
+    {
+    iObserver.SocketData( aBuffer );
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPExSocketEngine::ErrorInReading
+// Completes the request with error code.
+// -----------------------------------------------------------------------------
+//
+void CSIPExSocketEngine::ErrorInReading( TInt aError )
+    {
+    TRequestStatus* status = &iStatus;		
+    SetActive();
+	User::RequestComplete( status, aError );
+    }
+
+// From MWriterNotifier
+// -----------------------------------------------------------------------------
+// CSIPExSocketEngine::WriteDone
+// 
+// -----------------------------------------------------------------------------
+//
+void CSIPExSocketEngine::WriteDone()
+    {
+    // Nothing to do
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPExSocketEngine::ErrorInWriting
+// Completes the request with error code.
+// -----------------------------------------------------------------------------
+//
+void CSIPExSocketEngine::ErrorInWriting( TInt aError )
+    {
+    TRequestStatus* status = &iStatus;		
+    SetActive();
+	User::RequestComplete( status, aError );
+    }
+
+// -----------------------------------------------------------------------------
+// CSIPExSocketEngine::ChangeStateAndNotify
+// Changes new state and notifies observer.
+// -----------------------------------------------------------------------------
+//
+void CSIPExSocketEngine::ChangeStateAndNotify( TSocketEngineState aNewState )
+    {
+    iState = aNewState;
+    iObserver.SocketState( iState );
+    }
+
+// End of file