--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/multimediacommsengine/tsrc/testdriver/testclient/net/src/CTcBaseConnection.cpp Tue Feb 02 01:04:58 2010 +0200
@@ -0,0 +1,373 @@
+/*
+* Copyright (c) 2004 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: Implementation
+*
+*/
+
+#include "CTcBaseConnection.h"
+#include "debuglog.h"
+#include "ErrorHandling.h"
+
+/// Accept queue length for listening sockets.
+const TInt KTcAcceptQueue( 2 );
+/// Try binding twenty times, at intervals of 0.1 sec
+const TInt KTcBindRetryCount( 20 );
+const TInt KTcBindDelay( 100000 );
+
+// Retry connect after delay if connecting fails
+const TInt KRetryDelay( 5000000 );
+
+CTcBaseConnection::~CTcBaseConnection()
+ {
+ LOG( _L("CTcBaseConnection::~CTcBaseConnection()") );
+ Close();
+ }
+
+CTcBaseConnection::CTcBaseConnection()
+ : CActive( CActive::EPriorityHigh )
+ {
+ CActiveScheduler::Add( this );
+ iTimer.CreateLocal();
+ }
+
+void CTcBaseConnection::RunL()
+ {
+ LOG( _L("CTcBaseConnection::RunL() iState = %d, iStatus = %d"), iState, iStatus.Int() );
+
+ // Take backup of the state for notifying AFTER state transition
+ TInt status( iStatus.Int() );
+ TState state( iState );
+
+ // Do state transition
+ switch( iState )
+ {
+ case EConnecting:
+ {
+ if( !status )
+ {
+ iState = EConnected;
+ }
+ else
+ {
+ iState = EIdle;
+
+ // Retry if connecting failed
+ if ( status == KErrCouldNotConnect)
+ {
+ iState = EWaitingRetry;
+ iTimer.After(iStatus,KRetryDelay);
+ SetActive();
+ return;
+ }
+ }
+ break;
+ }
+ case EWaitingRetry:
+ {
+ LOG( _L("CTcBaseConnection::RunL() retrying connect") );
+ ConnectL( iRemoteAddr );
+ return;
+ }
+ case ESending:
+ case EReceiving:
+ {
+ iState = EConnected;
+ break;
+ }
+
+ default:
+ {
+ // should not happen..
+ break;
+ }
+ }
+
+ Notify( state, status );
+ LOG( _L("CTcBaseConnection::RunL() end, iState = %d"), iState );
+ }
+
+void CTcBaseConnection::DoCancel()
+ {
+ LOG( _L("CTcBaseConnection::DoCancel() start") );
+ iSocket.CancelAll();
+
+ switch( iState )
+ {
+ case EConnecting:
+ {
+ iState = EIdle;
+ break;
+ }
+ case EWaitingRetry:
+ {
+ iTimer.Cancel();
+ break;
+ }
+ case ESending:
+ case EReceiving:
+ {
+ iState = EConnected;
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ LOG( _L("CTcBaseConnection::DoCancel() end") );
+ }
+
+void CTcBaseConnection::ConnectL()
+ {
+ LOG( _L("CTcBaseConnection::ConnectL() start") );
+ if( iState != EIdle )
+ {
+ User::Leave( KErrNotReady );
+ }
+
+ iState = EConnecting;
+
+ __ASSERT_ALWAYS( iSocketServ, User::Leave( KErrNotReady ) );
+
+ // Open data transfer socket
+ User::LeaveIfError( iSocket.Open( *iSocketServ ) );
+
+ // Bearer specific port setup and port selection
+ SetupPortL();
+
+ // Set local port
+ iSockAddr.SetPort( iLocalPort );
+
+ LOG( _L("CTcBaseConnection::ConnectL() binding port %d"), iLocalPort );
+ // Bind it to listening socket
+ TInt status( KErrInUse );
+ for( TInt i = 0; ( i < KTcBindRetryCount ) && ( status != KErrNone ); i++ )
+ {
+ status = iListeningSocket.Bind( iSockAddr );
+ if( status == KErrInUse )
+ {
+ LOG( _L("CTcBaseConnection::ConnectL() retrying after %dms"), KTcBindDelay / 1000 );
+ User::After( KTcBindDelay );
+ }
+ }
+ User::LeaveIfError( status );
+
+ LOG( _L("CTcBaseConnection::ConnectL() listening") );
+
+ // Set listening mode, we don't really need that much queue
+ User::LeaveIfError( iListeningSocket.Listen( KTcAcceptQueue ) );
+
+ LOG( _L("CTcBaseConnection::ConnectL() accepting") );
+ // Set listening socket to accept incoming
+ // connections to real communications socket
+ iListeningSocket.Accept( iSocket, iStatus );
+
+ // Now wait for a client to connect
+ SetActive();
+
+ if( iObserver )
+ {
+ iObserver->BearerCompletion( MTcBearerObserver::EListen, KErrNone );
+ }
+
+ LOG( _L("CTcBaseConnection::ConnectL() end") );
+ }
+
+void CTcBaseConnection::ConnectL( TInetAddr& aRemoteAddr )
+ {
+ LOG( _L("CTcBaseConnection::ConnectL() 2 start") );
+ if( iState != EIdle && iState != EWaitingRetry)
+ {
+ User::Leave( KErrNotReady );
+ }
+
+ iState = EConnecting;
+
+ __ASSERT_ALWAYS( iSocketServ, User::Leave( KErrNotReady ) );
+
+
+ SetupPort2L();
+
+ // Set local port
+ iSockAddr.SetPort( iLocalPort );
+
+ LOG( _L("CTcBaseConnection::ConnectL() binding port %d"), iLocalPort );
+ // Bind it to listening socket
+ TInt status( KErrInUse );
+ for( TInt i = 0; ( i < KTcBindRetryCount ) && ( status != KErrNone ); i++ )
+ {
+ status = iSocket.Bind( iSockAddr );
+ if( status == KErrInUse )
+ {
+ LOG( _L("CTcBaseConnection::ConnectL() retrying after %dms"), KTcBindDelay / 1000 );
+ User::After( KTcBindDelay );
+ }
+ }
+
+ LOG( _L("CTcBaseConnection::ConnectL() connecting") );
+ iSocket.Connect( aRemoteAddr, iStatus );
+
+ // Save address so that we can retry in RunL if connection times out
+ iRemoteAddr = aRemoteAddr;
+
+ // Now wait for connection establishemt
+ SetActive();
+
+ if( iObserver )
+ {
+ iObserver->BearerCompletion( MTcBearerObserver::EConnecting, KErrNone );
+ }
+
+ LOG( _L("CTcBaseConnection::ConnectL() 2 end") );
+ }
+
+void CTcBaseConnection::Close()
+ {
+ LOG( _L("CTcBaseConnection::Close() start") );
+
+ if( iState == EIdle )
+ {
+ // no need to do anything
+ LOG( _L("CTcBaseConnection::Close() end, already closed") );
+ return;
+ }
+
+ // Close listening socket if its open
+ if( iListeningSocket.SubSessionHandle() )
+ {
+ iListeningSocket.CancelAll();
+ iListeningSocket.Close();
+ }
+
+ // Cancel read/write requests and timeouts
+ Cancel();
+
+ // Close down data socket
+ iSocket.Close();
+
+ // Close timer
+ iTimer.Close();
+
+ iState = EIdle;
+ LOG( _L("CTcBaseConnection::Close() end") );
+ }
+
+void CTcBaseConnection::Send( const TDesC8& aDes )
+ {
+ LOG( _L("CTcBaseConnection::Send() start") );
+ // Make sure we're in correct state
+ __ASSERT_ALWAYS( iState == EConnected, Panic( KErrNotReady ) );
+ __ASSERT_ALWAYS( !IsActive(), Panic( KErrInUse ) );
+
+ // Start writing
+ iState = ESending;
+ iSocket.Write( aDes, iStatus );
+ SetActive();
+
+ LOG( _L("CTcBaseConnection::Send() end") );
+ }
+
+void CTcBaseConnection::Receive( TDes8& aDes )
+ {
+ LOG( _L("CTcBaseConnection::Receive() start") );
+ // Make sure we're in correct state
+ __ASSERT_ALWAYS( iState == EConnected, Panic( KErrNotReady ) );
+ __ASSERT_ALWAYS( !IsActive(), Panic( KErrInUse ) );
+
+ // Start reading
+ iState = EReceiving;
+ iSocket.Read( aDes, iStatus );
+ SetActive();
+
+ LOG( _L("CTcBaseConnection::Receive() end") );
+ }
+
+void CTcBaseConnection::ReceiveOneOrMore( TDes8& aDes )
+ {
+ LOG( _L("CTcBaseConnection::ReceiveOneOrMore() start") );
+ // Make sure we're in correct state
+ __ASSERT_ALWAYS( iState == EConnected, Panic( KErrNotReady ) );
+ __ASSERT_ALWAYS( !IsActive(), Panic( KErrInUse ) );
+
+ // Start reading
+ iState = EReceiving;
+ iSocket.RecvOneOrMore( aDes, 0, iStatus, iIgnoredLength );
+ SetActive();
+
+ LOG( _L("CTcBaseConnection::ReceiveOneOrMore() end") );
+ }
+
+void CTcBaseConnection::SetObserver( MTcBearerObserver* aObserver )
+ {
+ LOG( _L("CTcBaseConnection::SetObserver( %d )"), (TInt)aObserver );
+ iObserver = aObserver;
+ }
+
+void CTcBaseConnection::SetConnection( RSocketServ* aSocketServ, RConnection* aConnection )
+ {
+ iSocketServ = aSocketServ;
+ iConnection = aConnection;
+ }
+
+TInt CTcBaseConnection::LocalPort() const
+ {
+ return iLocalPort;
+ }
+
+void CTcBaseConnection::Notify( TState aState, TInt aStatus )
+ {
+ LOG( _L("CTcBaseConnection::Notify( %d, %d ) start"), aState, aStatus );
+ MTcBearerObserver::TOperation op;
+
+ switch( aState )
+ {
+ case EConnecting:
+ {
+ op = MTcBearerObserver::EConnect;
+ break;
+ }
+ case ESending:
+ {
+ op = MTcBearerObserver::ESend;
+ break;
+ }
+ case EReceiving:
+ {
+ op = MTcBearerObserver::EReceive;
+ break;
+ }
+
+ case EIdle:
+ case EConnected:
+ default:
+ {
+ op = MTcBearerObserver::EUnknown;
+ break;
+ }
+ }
+
+ if( iObserver )
+ {
+ iObserver->BearerCompletion( op, aStatus );
+ }
+ LOG( _L("CTcBaseConnection::Notify() end") );
+ }
+
+void CTcBaseConnection::SetupPort2L()
+ {
+ User::Leave( KErrNotSupported );
+ }
+