multimediacommsengine/tsrc/testdriver/testclient/net/src/CTcBaseConnection.cpp
changeset 0 1bce908db942
equal deleted inserted replaced
-1:000000000000 0:1bce908db942
       
     1 /*
       
     2 * Copyright (c) 2004 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:  Implementation
       
    15 *
       
    16 */
       
    17 
       
    18 #include "CTcBaseConnection.h"
       
    19 #include "debuglog.h"
       
    20 #include "ErrorHandling.h"
       
    21 
       
    22 /// Accept queue length for listening sockets.
       
    23 const TInt KTcAcceptQueue( 2 );
       
    24 /// Try binding twenty times, at intervals of 0.1 sec
       
    25 const TInt KTcBindRetryCount( 20 );
       
    26 const TInt KTcBindDelay( 100000 );
       
    27 
       
    28 // Retry connect after delay if connecting fails
       
    29 const TInt KRetryDelay( 5000000 );
       
    30 
       
    31 CTcBaseConnection::~CTcBaseConnection()
       
    32 	{
       
    33 	LOG( _L("CTcBaseConnection::~CTcBaseConnection()") );
       
    34 	Close();
       
    35 	}
       
    36 
       
    37 CTcBaseConnection::CTcBaseConnection()
       
    38 	: CActive( CActive::EPriorityHigh )
       
    39 	{
       
    40 	CActiveScheduler::Add( this );
       
    41 	iTimer.CreateLocal();
       
    42 	}
       
    43 
       
    44 void CTcBaseConnection::RunL()
       
    45 	{
       
    46 	LOG( _L("CTcBaseConnection::RunL() iState = %d, iStatus = %d"), iState, iStatus.Int() );
       
    47 
       
    48 	// Take backup of the state for notifying AFTER state transition
       
    49 	TInt status( iStatus.Int() );
       
    50 	TState state( iState );
       
    51 
       
    52 	// Do state transition
       
    53 	switch( iState )
       
    54 		{
       
    55 		case EConnecting:
       
    56 			{
       
    57 			if( !status )
       
    58 				{
       
    59 				iState = EConnected;
       
    60 				}
       
    61 			else
       
    62 				{
       
    63 				iState = EIdle;
       
    64 				
       
    65 				// Retry if connecting failed
       
    66 				if ( status == KErrCouldNotConnect)
       
    67 					{
       
    68 						iState = EWaitingRetry;
       
    69 						iTimer.After(iStatus,KRetryDelay);
       
    70 						SetActive();
       
    71 						return;
       
    72 					}
       
    73 				}
       
    74 			break;
       
    75 			}
       
    76 		case EWaitingRetry:
       
    77 		{
       
    78 			LOG( _L("CTcBaseConnection::RunL() retrying connect") );
       
    79 			ConnectL( iRemoteAddr );
       
    80 			return;
       
    81 		}
       
    82 		case ESending:
       
    83 		case EReceiving:
       
    84 			{
       
    85 			iState = EConnected;
       
    86 			break;
       
    87 			}
       
    88 
       
    89 		default:
       
    90 			{
       
    91 			// should not happen..
       
    92 			break;
       
    93 			}
       
    94 		}
       
    95 
       
    96 	Notify( state, status );
       
    97 	LOG( _L("CTcBaseConnection::RunL() end, iState = %d"), iState );
       
    98 	}
       
    99 
       
   100 void CTcBaseConnection::DoCancel()
       
   101 	{
       
   102 	LOG( _L("CTcBaseConnection::DoCancel() start") );
       
   103 	iSocket.CancelAll();
       
   104 	
       
   105 	switch( iState )
       
   106 		{
       
   107 		case EConnecting:
       
   108 			{
       
   109 			iState = EIdle;
       
   110 			break;
       
   111 			}
       
   112 		case EWaitingRetry:
       
   113 		{
       
   114 			iTimer.Cancel();
       
   115 			break;
       
   116 			}
       
   117 		case ESending:
       
   118 		case EReceiving:
       
   119 			{
       
   120 			iState = EConnected;
       
   121 			break;
       
   122 			}
       
   123 
       
   124 		default:
       
   125 			{
       
   126 			break;
       
   127 			}
       
   128 		}
       
   129 
       
   130 	LOG( _L("CTcBaseConnection::DoCancel() end") );
       
   131 	}
       
   132 
       
   133 void CTcBaseConnection::ConnectL()
       
   134 	{
       
   135 	LOG( _L("CTcBaseConnection::ConnectL() start") );
       
   136 	if( iState != EIdle )
       
   137 		{
       
   138 		User::Leave( KErrNotReady );
       
   139 		}
       
   140 
       
   141 	iState = EConnecting;
       
   142 	
       
   143 	__ASSERT_ALWAYS( iSocketServ, User::Leave( KErrNotReady ) );
       
   144 
       
   145 	// Open data transfer socket
       
   146 	User::LeaveIfError( iSocket.Open( *iSocketServ ) );
       
   147 
       
   148 	// Bearer specific port setup and port selection
       
   149 	SetupPortL();
       
   150 
       
   151 	// Set local port
       
   152 	iSockAddr.SetPort( iLocalPort );
       
   153 
       
   154 	LOG( _L("CTcBaseConnection::ConnectL() binding port %d"), iLocalPort );
       
   155 	// Bind it to listening socket
       
   156 	TInt status( KErrInUse );
       
   157 	for( TInt i = 0; ( i < KTcBindRetryCount ) && ( status != KErrNone ); i++ )
       
   158 		{
       
   159 		status = iListeningSocket.Bind( iSockAddr );
       
   160 		if( status == KErrInUse )
       
   161 			{
       
   162 			LOG( _L("CTcBaseConnection::ConnectL() retrying after %dms"), KTcBindDelay / 1000 );
       
   163 			User::After( KTcBindDelay );
       
   164 			}
       
   165 		}
       
   166 	User::LeaveIfError( status );
       
   167 
       
   168 	LOG( _L("CTcBaseConnection::ConnectL() listening") );
       
   169 
       
   170 	// Set listening mode, we don't really need that much queue
       
   171 	User::LeaveIfError( iListeningSocket.Listen( KTcAcceptQueue ) );
       
   172 
       
   173 	LOG( _L("CTcBaseConnection::ConnectL() accepting") );
       
   174 	// Set listening socket to accept incoming
       
   175 	// connections to real communications socket
       
   176 	iListeningSocket.Accept( iSocket, iStatus );
       
   177 
       
   178 	// Now wait for a client to connect
       
   179 	SetActive();
       
   180 
       
   181 	if( iObserver )
       
   182 		{
       
   183 		iObserver->BearerCompletion( MTcBearerObserver::EListen, KErrNone );
       
   184 		}
       
   185 
       
   186 	LOG( _L("CTcBaseConnection::ConnectL() end") );
       
   187 	}
       
   188 
       
   189 void CTcBaseConnection::ConnectL( TInetAddr& aRemoteAddr )
       
   190 	{
       
   191 	LOG( _L("CTcBaseConnection::ConnectL() 2 start") );
       
   192 	if( iState != EIdle && iState != EWaitingRetry)
       
   193 		{
       
   194 		User::Leave( KErrNotReady );
       
   195 		}
       
   196 
       
   197 	iState = EConnecting;
       
   198 	
       
   199 	__ASSERT_ALWAYS( iSocketServ, User::Leave( KErrNotReady ) );
       
   200 
       
   201 
       
   202     SetupPort2L();
       
   203 											   
       
   204 	// Set local port
       
   205 	iSockAddr.SetPort( iLocalPort );
       
   206 	
       
   207 	LOG( _L("CTcBaseConnection::ConnectL() binding port %d"), iLocalPort );
       
   208 	// Bind it to listening socket
       
   209 	TInt status( KErrInUse );
       
   210 	for( TInt i = 0; ( i < KTcBindRetryCount ) && ( status != KErrNone ); i++ )
       
   211 		{
       
   212 		status = iSocket.Bind( iSockAddr );
       
   213 		if( status == KErrInUse )
       
   214 			{
       
   215 			LOG( _L("CTcBaseConnection::ConnectL() retrying after %dms"), KTcBindDelay / 1000 );
       
   216 			User::After( KTcBindDelay );
       
   217 			}
       
   218 		}
       
   219 
       
   220 	LOG( _L("CTcBaseConnection::ConnectL() connecting") );
       
   221 	iSocket.Connect( aRemoteAddr, iStatus );
       
   222 	
       
   223 	// Save address so that we can retry in RunL if connection times out
       
   224 	iRemoteAddr = aRemoteAddr;
       
   225 
       
   226 	// Now wait for connection establishemt
       
   227 	SetActive();
       
   228 
       
   229 	if( iObserver )
       
   230 		{
       
   231 		iObserver->BearerCompletion( MTcBearerObserver::EConnecting, KErrNone );
       
   232 		}
       
   233 
       
   234 	LOG( _L("CTcBaseConnection::ConnectL() 2 end") );
       
   235 	}
       
   236 	
       
   237 void CTcBaseConnection::Close()
       
   238 	{
       
   239 	LOG( _L("CTcBaseConnection::Close() start") );
       
   240 	
       
   241 	if( iState == EIdle )
       
   242 		{
       
   243 		// no need to do anything
       
   244 		LOG( _L("CTcBaseConnection::Close() end, already closed") );
       
   245 		return;
       
   246 		}
       
   247 
       
   248 	// Close listening socket if its open
       
   249 	if( iListeningSocket.SubSessionHandle() )
       
   250 		{
       
   251 		iListeningSocket.CancelAll();
       
   252 		iListeningSocket.Close();
       
   253 		}
       
   254 		
       
   255 	// Cancel read/write requests and timeouts
       
   256 	Cancel();
       
   257 
       
   258 	// Close down data socket
       
   259 	iSocket.Close();
       
   260 	
       
   261 	// Close timer
       
   262 	iTimer.Close();
       
   263 
       
   264 	iState = EIdle;
       
   265 	LOG( _L("CTcBaseConnection::Close() end") );
       
   266 	}
       
   267 
       
   268 void CTcBaseConnection::Send( const TDesC8& aDes )
       
   269 	{
       
   270 	LOG( _L("CTcBaseConnection::Send() start") );
       
   271 	// Make sure we're in correct state
       
   272 	__ASSERT_ALWAYS( iState == EConnected, Panic( KErrNotReady ) );
       
   273 	__ASSERT_ALWAYS( !IsActive(), Panic( KErrInUse ) );
       
   274 
       
   275 	// Start writing
       
   276 	iState = ESending;
       
   277 	iSocket.Write( aDes, iStatus );
       
   278 	SetActive();
       
   279 
       
   280 	LOG( _L("CTcBaseConnection::Send() end") );
       
   281 	}
       
   282 
       
   283 void CTcBaseConnection::Receive( TDes8& aDes )
       
   284 	{
       
   285 	LOG( _L("CTcBaseConnection::Receive() start") );
       
   286 	// Make sure we're in correct state
       
   287 	__ASSERT_ALWAYS( iState == EConnected, Panic( KErrNotReady ) );
       
   288 	__ASSERT_ALWAYS( !IsActive(), Panic( KErrInUse ) );
       
   289 
       
   290 	// Start reading
       
   291 	iState = EReceiving;
       
   292 	iSocket.Read( aDes, iStatus );
       
   293 	SetActive();
       
   294 
       
   295 	LOG( _L("CTcBaseConnection::Receive() end") );
       
   296 	}
       
   297 
       
   298 void CTcBaseConnection::ReceiveOneOrMore( TDes8& aDes )
       
   299 	{
       
   300 	LOG( _L("CTcBaseConnection::ReceiveOneOrMore() start") );
       
   301 	// Make sure we're in correct state
       
   302 	__ASSERT_ALWAYS( iState == EConnected, Panic( KErrNotReady ) );
       
   303 	__ASSERT_ALWAYS( !IsActive(), Panic( KErrInUse ) );
       
   304 
       
   305 	// Start reading
       
   306 	iState = EReceiving;
       
   307 	iSocket.RecvOneOrMore( aDes, 0, iStatus, iIgnoredLength );
       
   308 	SetActive();
       
   309 
       
   310 	LOG( _L("CTcBaseConnection::ReceiveOneOrMore() end") );
       
   311 	}
       
   312 
       
   313 void CTcBaseConnection::SetObserver( MTcBearerObserver* aObserver )
       
   314 	{
       
   315 	LOG( _L("CTcBaseConnection::SetObserver( %d )"), (TInt)aObserver );
       
   316 	iObserver = aObserver;
       
   317 	}
       
   318 
       
   319 void CTcBaseConnection::SetConnection( RSocketServ* aSocketServ, RConnection* aConnection )
       
   320     {
       
   321     iSocketServ = aSocketServ;
       
   322     iConnection = aConnection;
       
   323     }
       
   324     
       
   325 TInt CTcBaseConnection::LocalPort() const
       
   326 	{
       
   327 	return iLocalPort;
       
   328 	}
       
   329 
       
   330 void CTcBaseConnection::Notify( TState aState, TInt aStatus )
       
   331 	{
       
   332 	LOG( _L("CTcBaseConnection::Notify( %d, %d ) start"), aState, aStatus );
       
   333 	MTcBearerObserver::TOperation op;
       
   334 
       
   335 	switch( aState )
       
   336 		{
       
   337 		case EConnecting:
       
   338 			{
       
   339 			op = MTcBearerObserver::EConnect;
       
   340 			break;
       
   341 			}
       
   342 		case ESending:
       
   343 			{
       
   344 			op = MTcBearerObserver::ESend;
       
   345 			break;
       
   346 			}
       
   347 		case EReceiving:
       
   348 			{
       
   349 			op = MTcBearerObserver::EReceive;
       
   350 			break;
       
   351 			}
       
   352 
       
   353 		case EIdle:
       
   354 		case EConnected:
       
   355 		default:
       
   356 			{
       
   357 			op = MTcBearerObserver::EUnknown;
       
   358 			break;
       
   359 			}
       
   360 		}
       
   361 
       
   362 	if( iObserver )
       
   363 		{
       
   364 		iObserver->BearerCompletion( op, aStatus );
       
   365 		}
       
   366 	LOG( _L("CTcBaseConnection::Notify() end") );
       
   367 	}
       
   368 
       
   369 void CTcBaseConnection::SetupPort2L()
       
   370     {
       
   371     User::Leave( KErrNotSupported );
       
   372     }
       
   373