realtimenetprots/sipfw/SIP/ConnectionMgr/src/CTransportTcp.cpp
changeset 0 307788aac0a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SIP/ConnectionMgr/src/CTransportTcp.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,610 @@
+// Copyright (c) 2002-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:
+// Name          : CTransportTcp.cpp
+// Part of       : ConnectionMgr
+// Version       : SIP/6.0 
+//
+
+
+
+
+#include "CTransportTcp.h"
+#include "CSipConnection.h"
+#include "CErrorHandler.h"
+#include "MTransactionFinder.h"
+#include "MTransportOwner.h"
+#include "MServerTaFactory.h"
+#include "CSender.h"
+#include "CSenderTcp.h"
+#include "CReceiverTcp.h"
+#include "CListener.h"
+#include "CTcpTransState.h"
+#include "CTcpTransConnected.h"
+#include "CTcpTransConnecting.h"
+#include "CommonConsts.h"
+#include "siperr.h"
+#include "NetworkInfo.h"
+#include "COwnerSettingsList.h"
+#include "CSocketContainer.h"
+#include "MSIPTransportRemovalObserver.h"
+#include <sipnattraversalcontroller.h>
+
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::NewL
+// -----------------------------------------------------------------------------
+//
+CTransportTcp* CTransportTcp::NewL(RSocketServ& aServer,
+				MTransactionFinder& aFinder, 
+				MServerTaFactory& aTaFactory,
+				MTransportOwner& aTransportOwner,
+				MTimerManager& aTimer,
+				const TSIPTransportParams& aTransportParams,
+				const TInetAddr& aRemoteAddr,
+				TUint aTOne,
+				CSIPServerResolver& aServerResolver,
+				RConnection& aConnection,
+				MSigCompController& aSigCompHandler,
+				TUint aLocalSendPort,
+				CNetworkInfo& aNetworkInfo,
+				COwnerSettingsList& aSettingsList,
+				CSIPNATTraversalController& aNATTraversal)
+	{
+	CTransportTcp* self = NewLC(aServer, aFinder, aTaFactory, 
+								aTransportOwner, aTimer, aTransportParams,
+								aRemoteAddr, aTOne, aServerResolver, 
+								aConnection, aSigCompHandler, aLocalSendPort,
+								aNetworkInfo, aSettingsList, aNATTraversal);
+	CleanupStack::Pop(self);
+	return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::NewLC
+// -----------------------------------------------------------------------------
+//
+CTransportTcp* CTransportTcp::NewLC(RSocketServ& aServer,
+				MTransactionFinder& aFinder, 
+				MServerTaFactory& aTaFactory,
+				MTransportOwner& aTransportOwner,
+				MTimerManager& aTimer,
+				const TSIPTransportParams& aTransportParams,
+				const TInetAddr& aRemoteAddr,
+				TUint aTOne,
+				CSIPServerResolver& aServerResolver,
+				RConnection& aConnection,
+				MSigCompController& aSigCompHandler,
+				TUint aLocalSendPort,
+				CNetworkInfo& aNetworkInfo,
+				COwnerSettingsList& aSettingsList,
+				CSIPNATTraversalController& aNATTraversal)
+	{
+	CTransportTcp* self = new (ELeave) CTransportTcp(aFinder, aTaFactory, 
+										aTransportOwner, aTransportParams,
+										aServerResolver, aSigCompHandler,
+										aNetworkInfo, aSettingsList, 
+										aNATTraversal);
+	CleanupStack::PushL(self);
+	self->ConstructL(aServer, 
+	                 aTimer, 
+	                 aRemoteAddr, 
+	                 aTOne, 
+	                 aConnection, 
+	                 aLocalSendPort);
+	return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::CTransportTcp
+// -----------------------------------------------------------------------------
+//
+CTransportTcp::CTransportTcp(MTransactionFinder& aFinder, 
+							 MServerTaFactory& aTaFactory,
+							 MTransportOwner& aTransportOwner,
+							 const TSIPTransportParams& aTransportParams,
+							 CSIPServerResolver& aServerResolver,
+							 MSigCompController& aSigCompHandler,							 
+							 CNetworkInfo& aNetworkInfo,
+							 COwnerSettingsList& aSettingsList,
+							 CSIPNATTraversalController& aNATTraversal) : 
+	CTransport(aFinder, aTaFactory, aTransportOwner,
+			   aServerResolver, aSigCompHandler,
+			   aTransportParams, aNetworkInfo, 
+			   aSettingsList, aNATTraversal),
+	iIsSending( EFalse )
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CTransportTcp::ConstructL( RSocketServ& aServer,
+							    MTimerManager& aTimer,
+    							const TInetAddr& aRemoteAddr,
+    							TUint aTOne,
+    							RConnection& aConnection,
+    							TUint aLocalSendPort )
+	{
+	iTimerValue = (64 * aTOne);
+	iSocketServ = &aServer;
+	iConnection = &aConnection;
+	iTimer = &aTimer;
+	iRemoteAddr = aRemoteAddr;
+	iConnectedState = CTcpTransportConnected::NewL( iTransportParams );
+	iConnectingState = CTcpTransportConnecting::NewL( iTransportParams );
+	iConnectingState->SetNeighborState( iConnectedState );
+	SetCurrentState( iConnectingState );
+	iErrorHandler =	CTransportErrorHandler::NewL( *this );
+	User::LeaveIfError( iSocket.Open( *iSocketServ, KAfInet, KSockStream,
+									  KProtocolInetTcp, *iConnection ) );
+
+    iSocketContainer = CSocketContainer::NewL( iSocket );
+    
+    // If local send port is defined, socket is binded to it								
+	if ( aLocalSendPort > 0 && aLocalSendPort != KDefaultSipPort )
+	    {	       
+	    iSocket.SetOpt( KSoReuseAddr, KSolInetIp, 1 );
+	                                                                                  
+	    TInetAddr address;
+    	iTransportOwner->GetLocalAddrL( address, &aRemoteAddr );
+    	address.SetPort( aLocalSendPort );
+    	TInt err = iSocket.Bind( address );
+    	if ( err == KErrInUse )
+    		{
+    		User::Leave( KErrSIPTransportFailure );
+    		}
+    	else
+    		{
+    		User::LeaveIfError( err );
+    		}
+	    }
+	    
+	iReceiver = CReceiverTcp::NewL( *this );
+	
+	iSender = CSenderTcp::NewL( *this, iSettingsList );
+	}
+
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::~CTransportTcp
+// -----------------------------------------------------------------------------
+//
+CTransportTcp::~CTransportTcp()
+	{
+	HandleShutdownCompletion();
+	StopTimer();
+	delete iErrorHandler;
+	delete iConnectedState;
+	delete iConnectingState;
+	delete iReceiver;
+	delete iSender;
+	delete iSocketContainer;
+	iNATTraversal.SocketIdle( EFalse, iSocket );
+	iSocket.Close();
+	}
+	
+// -----------------------------------------------------------------------------
+// CTransportTcp::HandleMessage
+// -----------------------------------------------------------------------------
+//
+TBool CTransportTcp::HandleMessage(const TSIPTransportParams& aParams,
+                                   RStringF aProtocol,
+								   const TInetAddr& aRemoteAddr,
+								   TUint /*aLocalPort*/,
+								   TBool /*aIsStrict*/)
+	{ 
+	return ( iCurrentState->HandleMessage(aProtocol, aRemoteAddr, this) &&
+	         Match( aParams ) );
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::SourcePort
+// -----------------------------------------------------------------------------
+//
+TUint CTransportTcp::SourcePort()
+	{
+	return iSocket.LocalPort();
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::SendToNetL
+// -----------------------------------------------------------------------------
+//
+void CTransportTcp::SendToNetL(const TSIPTransportParams& aParams,
+                               const TInetAddr& aAddress, 
+							   CSIPMessage& aMessage, 
+							   TBool /*aForceUDP*/,
+							   TUint aOrigTransport,
+							   TRequestStatus &aStatus)
+	{
+	HandleMixedAddressFamilysL( aMessage, aAddress );
+	
+	iCurrentState->SendToNetL(aParams,
+	                          aMessage,
+							  aAddress,
+							  aStatus,
+							  aOrigTransport,
+							  this);
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::CancelSend
+// -----------------------------------------------------------------------------
+//
+TBool CTransportTcp::CancelSend(TRequestStatus& aStatus)
+	{
+	return iCurrentState->CancelSend(aStatus, this);
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::WaitL
+// -----------------------------------------------------------------------------
+//
+void CTransportTcp::WaitL()
+	{
+	iCurrentState->Wait(this);
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::IsWaiting
+// -----------------------------------------------------------------------------
+//
+TBool CTransportTcp::IsWaiting(TUint /*aProtocol*/, TUint /*aPort*/)
+	{
+	return EFalse;	
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::Disconnect
+// -----------------------------------------------------------------------------
+//
+void CTransportTcp::Disconnect(const TInetAddr& /*aRemoteHost*/)
+	{
+	// If this is reserved or persistent transport, 
+	// only all send operations are cleared
+	if ( IsReservedTransport() || IsPersistent() )
+	    {
+	    iSender->CancelAllRequests( KErrSIPTransportFailure );
+	    }
+	else
+	    {
+	    Remove();
+	    }
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::Shutdown
+// -----------------------------------------------------------------------------
+//	     
+TBool CTransportTcp::Shutdown( 
+    TUint32 /*aTransportId*/,
+    MSIPTransportRemovalObserver* aRemovalObserver )
+    {
+    if ( aRemovalObserver )
+        {
+        SetShutdownObserver( aRemovalObserver );
+        iReceiver->Cancel();
+	    iSender->Cancel();
+        iReceiver->Shutdown();
+        return ETrue;
+        }
+    return EFalse;
+    }
+    
+// -----------------------------------------------------------------------------
+// CTransportTcp::PersistentRemoteAddr
+// -----------------------------------------------------------------------------
+// 
+TInetAddr* CTransportTcp::PersistentRemoteAddr( 
+    MSIPNATBindingObserver* aBindingObserver )
+    {
+    TInt index = iBindingObservers.FindInAddressOrder( aBindingObserver );
+    if ( index >= 0 && index < iBindingObservers.Count() )
+        {
+        return &iRemoteAddr;
+        }
+    return 0;
+    }
+    
+// -----------------------------------------------------------------------------
+// CTransportTcp::TimerExpiredL
+// -----------------------------------------------------------------------------
+//
+void CTransportTcp::TimerExpiredL(TTimerId /*aTimerId*/, TAny* /*aTimerParam*/)
+	{
+	// Reserved transport uses persistent tcp connection and therefore
+	// only send operations are cleared when timer expires
+	if ( IsReservedTransport() || IsPersistent() )
+	    {
+	    iSender->CancelAllRequests( KErrSIPTransportFailure );
+	    }
+	else
+	    {
+    	iCurrentState->TimerExpiredL( this );
+	    }
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::StartTimerL
+// -----------------------------------------------------------------------------
+//
+void CTransportTcp::StartTimerL()
+	{
+	iTimer->Stop(iMyTimerId);
+	iMyTimerId = iTimer->StartL(this, iTimerValue);
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::StopTimer
+// -----------------------------------------------------------------------------
+//
+void CTransportTcp::StopTimer()
+    {
+    iTimer->Stop(iMyTimerId);
+    }
+    
+// -----------------------------------------------------------------------------
+// CTransportTcp::CancelAllRequests
+// -----------------------------------------------------------------------------
+//
+void CTransportTcp::CancelAllRequests(CSIPConnection::TState aReason)
+	{
+	iCurrentState->CancelAllRequests(aReason, this);
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::SocketContainer
+// -----------------------------------------------------------------------------
+//
+CSocketContainer& CTransportTcp::SocketContainer() 
+    {
+    return *iSocketContainer;
+    }
+    
+// -----------------------------------------------------------------------------
+// CTransportTcp::SocketContainer
+// -----------------------------------------------------------------------------
+//
+CSocketContainer* CTransportTcp::SocketContainer( 
+    TUint /*aIPAddrFamily*/ )
+    {
+    return iSocketContainer;
+    }     
+    
+// -----------------------------------------------------------------------------
+// CTransportTcp::ReceivedDataL
+// -----------------------------------------------------------------------------
+//
+void CTransportTcp::ReceivedDataL(CSIPMessage* aMessage,
+								  const TInetAddr& aRemoteAddr,
+								  TInt aError,
+								  TBool aCompressed)
+	{
+	// As starting timer can leave, do it before passing ownership of aMessage
+	StartTimerL();
+	RecvL(aMessage, aRemoteAddr, aError, aCompressed);
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::ResetSocketL
+// -----------------------------------------------------------------------------
+//
+void CTransportTcp::ResetSocketL()
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::ContinueL
+// -----------------------------------------------------------------------------
+//
+void CTransportTcp::ContinueL()
+	{
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::StopL
+// -----------------------------------------------------------------------------
+//
+TBool CTransportTcp::StopL()
+	{
+	TBool removed( EFalse );
+	
+	if (iCurrentState == iConnectingState)
+		{
+		iTransportOwner->RemoveTransport(this);
+		removed = ETrue;
+		}
+		
+    return removed;
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::ConnectionOpenL
+// -----------------------------------------------------------------------------
+//
+TBool CTransportTcp::ConnectionOpenL()
+	{
+	iTransportOwner->TcpConnected(iRemoteAddr);
+	iCurrentState->ConnectionOpenL(this);
+	return ETrue;
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::SetCurrentState
+// -----------------------------------------------------------------------------
+//
+void CTransportTcp::SetCurrentState(CTcpTransportState* aState)
+	{
+	iCurrentState = aState;
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::ConnectSocket
+// -----------------------------------------------------------------------------
+//
+void CTransportTcp::ConnectSocket()
+    {
+    iReceiver->Connect( iRemoteAddr );
+    }
+    
+// -----------------------------------------------------------------------------
+// CTransportTcp::TransportOwner
+// -----------------------------------------------------------------------------
+//
+MTransportOwner* CTransportTcp::TransportOwner()
+	{
+	return iTransportOwner;
+	}
+	
+// -----------------------------------------------------------------------------
+// CTransportTcp::GetSocketContainerL
+// -----------------------------------------------------------------------------
+//	
+CSocketContainer& CTransportTcp::GetSocketContainerL( 
+    const TInetAddr& /*aRemoteAddr*/ )
+    {
+    return *iSocketContainer;
+    }
+    
+// -----------------------------------------------------------------------------
+// CTransportTcp::InformSendingStatus
+// -----------------------------------------------------------------------------
+//    
+void CTransportTcp::InformSendingStatus( const TInetAddr& /*aRemoteAddr*/ )
+    {
+    iNATTraversal.SocketIdle( !iIsSending, iSocket );
+    }
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::Sender
+// -----------------------------------------------------------------------------
+//
+CSender* CTransportTcp::Sender(const TSIPTransportParams& aParams,
+                               TUint aProtocol, 
+                               const TInetAddr& aRemoteAddr)
+	{
+	if ( Protocol() == aProtocol && 
+	     aRemoteAddr.CmpAddr( iRemoteAddr ) && 
+	     Match( aParams ) )
+		{
+		return iSender;
+		}
+	return 0;
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::Remove
+// -----------------------------------------------------------------------------
+//
+TInt CTransportTcp::Remove()
+	{
+	return iTransportOwner->RemoveTransport( this );
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::IapId
+// -----------------------------------------------------------------------------
+//
+TUint32 CTransportTcp::IapId()
+	{
+	return iTransportOwner->IapId();
+	}
+	
+// -----------------------------------------------------------------------------
+// CTransportTcp::Sending
+// -----------------------------------------------------------------------------
+//
+void CTransportTcp::Sending( TBool aIsSending )
+    {
+    iIsSending = aIsSending;
+    iNATTraversal.SocketIdle( !iIsSending, iSocket );
+    }
+	
+// -----------------------------------------------------------------------------
+// CTransportTcp::ReRouteL
+// -----------------------------------------------------------------------------
+//
+void CTransportTcp::ReRouteL(TUint aProtocol, 
+                             COutgoingData* aData)
+	{
+	iTransportOwner->ReRouteL(aProtocol, aData);
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::DisconnectedL
+// -----------------------------------------------------------------------------
+//
+TBool CTransportTcp::DisconnectedL()
+	{
+	HandleShutdownCompletion();	
+	
+	// Flow failure notification may lead to immediate self deletion
+	if ( !NotifyFlowFailure() )
+	    {
+	    iCurrentState->DisconnectedL( this );
+	    }
+	
+	return ETrue;
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::GetRemoteAddr
+// -----------------------------------------------------------------------------
+//
+void CTransportTcp::GetRemoteAddr(TInetAddr& aAddr)
+	{
+	aAddr = iRemoteAddr;
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::SigCompHandler
+// -----------------------------------------------------------------------------
+//
+MSigCompController* CTransportTcp::SigCompHandler()
+	{
+	return SigCompressionHandler();
+	}
+    
+// -----------------------------------------------------------------------------
+// CTransportTcp::GetSender
+// -----------------------------------------------------------------------------
+//   
+CSender* CTransportTcp::GetSender()
+    {
+    return iSender;
+    }
+
+// -----------------------------------------------------------------------------
+// CTransportTcp::SetShutdownObserver
+// -----------------------------------------------------------------------------
+//
+void CTransportTcp::SetShutdownObserver( 
+    MSIPTransportRemovalObserver* aRemovalObserver )
+    {
+    iShutdownObserver = aRemovalObserver;
+    }
+    
+// -----------------------------------------------------------------------------
+// CTransportTcp::HandleShutdownCompletion
+// -----------------------------------------------------------------------------
+//     
+void CTransportTcp::HandleShutdownCompletion()
+    {
+    if ( iShutdownObserver )
+        {
+        iShutdownObserver->RemovalCompleted( iTransportParams.TransportId() );
+        iShutdownObserver = 0;
+        }
+    }