--- /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