realtimenetprots/sipfw/SIP/ConnectionMgr/src/CTransportUdp.cpp
changeset 0 307788aac0a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SIP/ConnectionMgr/src/CTransportUdp.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,787 @@
+// 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          : CTransportUdp.cpp
+// Part of       : ConnectionMgr
+// Version       : SIP/4.0 
+//
+
+
+
+
+#include "CTransportUdp.h"
+#include "CSipConnection.h"
+#include "CErrorHandler.h"
+#include "CReceiver.h"
+#include "CSenderUdp.h"
+#include "CSIPServerResolver.h"
+#include "sipviaheader.h"
+#include "siphostport.h"
+#include "sipmessage.h"
+#include "sipresponse.h"
+#include "Lwtimer.h"
+#include "SipLogs.h"
+#include "CResHandler.h"
+#include "utf.h"
+#include "CommonConsts.h"
+#include "sipstrings.h"
+#include "sipstrconsts.h"
+#include "siperr.h"
+#include "NetworkInfo.h"
+#include "COwnerSettingsList.h"
+#include "CSocketContainer.h"
+#include "MSocketUsagePermissionObserver.h"
+#include <sipnattraversalcontroller.h>
+
+
+const TInt KTransportUsersGranularity = 2;
+
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::NewL
+// -----------------------------------------------------------------------------
+//
+CTransportUdp* CTransportUdp::NewL( 
+    RSocketServ& aServer, 
+    TUint aPort,
+    MTransactionFinder& aFinder, 
+    MServerTaFactory& aTaFactory,
+    MTransportOwner& aTransportOwner,
+    MTimerManager& aTimerManager,
+    CSIPServerResolver& aServerResolver,
+    RConnection& aConnection,
+    MSigCompController& aSigCompHandler,
+    TUint aICMPErrorWaitTime,
+    CNetworkInfo& aNetworkInfo,
+    COwnerSettingsList& aSettingsList,
+    const TSIPTransportParams& aTransportParams,
+    CSIPNATTraversalController& aNATTraversal,
+    TBool aOnlyForReceiving )
+	{
+	CTransportUdp* self = NewLC( aServer, aPort, aFinder, aTaFactory, 
+						     	 aTransportOwner, aTimerManager, 
+						     	 aServerResolver, aConnection, aSigCompHandler,
+						    	 aICMPErrorWaitTime, aNetworkInfo,
+						    	 aSettingsList, aTransportParams,
+						    	 aNATTraversal, aOnlyForReceiving );
+	CleanupStack::Pop( self );
+	return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::NewLC
+// -----------------------------------------------------------------------------
+//
+CTransportUdp* CTransportUdp::NewLC( 
+    RSocketServ& aServer, 
+    TUint aPort,
+    MTransactionFinder& aFinder, 
+    MServerTaFactory& aTaFactory,
+    MTransportOwner& aTransportOwner,
+    MTimerManager& aTimerManager,
+    CSIPServerResolver& aServerResolver,
+    RConnection& aConnection,
+    MSigCompController& aSigCompHandler,
+    TUint aICMPErrorWaitTime,
+    CNetworkInfo& aNetworkInfo,
+    COwnerSettingsList& aSettingsList,
+    const TSIPTransportParams& aTransportParams,
+    CSIPNATTraversalController& aNATTraversal,
+    TBool aOnlyForReceiving )
+	{
+	CTransportUdp* self = new ( ELeave ) CTransportUdp( aServer, 
+	                                                    aPort,
+	                                                    aFinder, 
+	                                                    aTaFactory, 
+													    aTransportOwner,
+													    aTimerManager,
+													    aServerResolver,
+													    aConnection,
+													    aSigCompHandler,
+													    aICMPErrorWaitTime,
+													    aNetworkInfo,
+													    aSettingsList,
+													    aTransportParams,
+													    aNATTraversal,
+													    aOnlyForReceiving );
+	CleanupStack::PushL( self );
+	self->ConstructL();
+	return self;
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::CTransportUdp
+// -----------------------------------------------------------------------------
+//
+CTransportUdp::CTransportUdp( 
+    RSocketServ& aServer,
+    TUint aPort, 
+    MTransactionFinder& aFinder, 
+    MServerTaFactory& aTaFactory,
+    MTransportOwner& aTransportOwner,
+    MTimerManager& aTimerManager,
+    CSIPServerResolver& aServerResolver,
+    RConnection& aConnection,
+    MSigCompController& aSigCompHandler,
+    TUint aICMPErrorWaitTime,
+    CNetworkInfo& aNetworkInfo,
+    COwnerSettingsList& aSettingsList,
+    const TSIPTransportParams& aTransportParams,
+    CSIPNATTraversalController& aNATTraversal,
+    TBool aOnlyForReceiving ) 
+        :
+	CTransport( aFinder, aTaFactory, aTransportOwner, aServerResolver,
+	            aSigCompHandler, aTransportParams, aNetworkInfo, 
+	            aSettingsList, aNATTraversal ),
+	iSocketServ( &aServer ),
+	iConnection( &aConnection ),
+	iSourcePort( aPort ),
+	iTimerManager( aTimerManager ),
+	iList( CResponseHandler::iOffset ),
+	iListIter( iList ),
+	iICMPErrorWaitTime( aICMPErrorWaitTime ),
+	iTransportUsers( KTransportUsersGranularity ),
+	iOnlyForReceiving( aOnlyForReceiving ),
+	iIsSending( EFalse )
+	{		
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::ConstructL()
+	{
+	iErrorHandler =	CTransportErrorHandler::NewL( *this );
+	
+    RefreshSocketContainerL( KAfInet );
+    RefreshSocketContainerL( KAfInet6 );	                                   	
+	
+	iSender = CSenderUdp::NewL( *this, iSettingsList );
+	
+	iTransportUsers.AppendL( iTransportParams.TransportId() );
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::~CTransportUdp
+// -----------------------------------------------------------------------------
+//
+CTransportUdp::~CTransportUdp()
+	{
+    if ( iSocketUsagePermissionObserver )
+	    {
+	    iSocketUsagePermissionObserver->UsagePermissionChanged( iIPv4Socket, EFalse );
+	    iSocketUsagePermissionObserver->UsagePermissionChanged( iIPv6Socket, EFalse );
+	    }
+	
+	iNATTraversal.SocketIdle( EFalse, iIPv4Socket );
+	iNATTraversal.SocketIdle( EFalse, iIPv6Socket );
+	
+	CResponseHandler* listItem;
+	iListIter.SetToFirst();
+	while ( ( listItem = iListIter++ ) != 0 )
+		{
+		iList.Remove( *listItem );
+		delete listItem;
+		}
+	delete iErrorHandler;
+	delete iIPv4Receiver;
+	delete iIPv6Receiver;
+	delete iSender;
+	delete iIPv4SocketContainer;
+	delete iIPv6SocketContainer;
+	iNATTraversal.SocketIdle( EFalse, iIPv4Socket );
+	iIPv4Socket.Close();
+	iNATTraversal.SocketIdle( EFalse, iIPv6Socket );
+	iIPv6Socket.Close();
+	iTransportUsers.Close();
+	}
+	
+// -----------------------------------------------------------------------------
+// CTransportUdp::Handle
+// -----------------------------------------------------------------------------
+//
+TBool CTransportUdp::Handle( TUint32 aTransportId )
+    {
+    // Only interested about "protected" transports
+    return ( ( aTransportId > 0 ) && 
+             ( iTransportUsers.Find( aTransportId ) != KErrNotFound ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::HandleMessage
+// -----------------------------------------------------------------------------
+//
+TBool CTransportUdp::HandleMessage( const TSIPTransportParams& aParams,
+                                    RStringF aProtocol,
+								    const TInetAddr& /*aRemoteAddr*/,
+								    TUint aLocalPort,
+								    TBool aIsStrict )
+    {
+    // If not strict comparison, receiveonly mode has no significance
+	return ( aProtocol == SIPStrings::StringF( SipStrConsts::EUDP ) && 
+	         Match( aParams ) &&
+	         ( aLocalPort == 0 || iSourcePort == aLocalPort ) &&
+	         ( !aIsStrict || !iOnlyForReceiving ) );
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::ResetSocketL
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::ResetSocketL()
+	{
+	iIPv4Socket.Close();
+	CSocketContainer* tmp = CreateSocketContainerL( KAfInet, iIPv4Socket );
+	delete iIPv4SocketContainer;
+	iIPv4SocketContainer = tmp;
+	
+	iIPv6Socket.Close();
+	tmp = CreateSocketContainerL( KAfInet6, iIPv6Socket );
+	delete iIPv6SocketContainer;
+	iIPv6SocketContainer = tmp;	
+	}
+		
+// -----------------------------------------------------------------------------
+// CTransportUdp::StopL
+// -----------------------------------------------------------------------------
+//
+TBool CTransportUdp::StopL()
+	{
+	if ( iIPv4Receiver )
+	    {
+	    iIPv4Receiver->Cancel();
+	    }	
+	if ( iIPv6Receiver )
+	    {
+	    iIPv6Receiver->Cancel();
+	    }
+	iSender->Cancel();
+		
+	// If there's binding observers, notify that old socket
+	// cannot be used anymore
+	return NotifyFlowFailure();
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::ContinueL
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::ContinueL()
+	{
+	WaitL();
+	iSender->SendNextL();
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::SourcePort
+// -----------------------------------------------------------------------------
+//
+TUint CTransportUdp::SourcePort()
+	{
+	return iSourcePort;
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::WaitL
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::WaitL()
+	{
+	if ( iIPv4Receiver )
+	    {
+	    iIPv4Receiver->Listen();
+	    }
+	if ( iIPv6Receiver )
+	    {
+	    iIPv6Receiver->Listen();
+	    }
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::SendToNetL
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::SendToNetL( const TSIPTransportParams& aParams,
+                                const TInetAddr& aAddress, 
+							    CSIPMessage& aMessage,
+							    TBool aForceUDP,
+							    TUint aOrigTransport,
+							    TRequestStatus &aStatus )
+	{
+	RefreshSocketContainerL( CSender::IpAddrType( aAddress ) );
+	HandleMixedAddressFamilysL( aMessage, aAddress );
+	
+	iSender->SendL(
+	    aParams, 
+	    aMessage, 
+	    aAddress, 
+	    aOrigTransport, 
+	    aStatus, 
+	    EFalse, 
+	    aForceUDP );
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::SendToNetL
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::SendToNetL( const TSIPTransportParams& aParams,
+                                const TInetAddr& aAddress,
+							    CSIPMessage& aMessage,
+							    TRequestStatus &aStatus )
+	{
+	RefreshSocketContainerL( CSender::IpAddrType( aAddress ) );
+	HandleMixedAddressFamilysL( aMessage, aAddress );
+	
+	iSender->SendL( 
+	    aParams, 
+	    aMessage, 
+	    aAddress, 
+	    0, 
+	    aStatus, 
+	    EFalse, 
+	    EFalse );
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::SendToNetL
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::SendToNetL( const TSIPTransportParams& aParams,
+                                const TInetAddr& aAddress, 
+                                TTransactionId aId, 
+							    CSIPMessage& aMessage, 
+							    TRequestStatus &aStatus )
+	{
+	RefreshSocketContainerL( CSender::IpAddrType( aAddress ) );
+	HandleMixedAddressFamilysL( aMessage, aAddress );
+	
+	CResponseHandler* listItem = 0;
+	iListIter.SetToFirst();
+	while ( ( listItem = iListIter++ ) != 0 )
+		{
+		if(listItem->Handle( aId ) ) 
+			{
+			listItem->SendL( aParams, 
+			                 static_cast<CSIPResponse&>( aMessage ), 
+			                 aAddress, 
+			                 aStatus );
+			return;
+			}
+		}
+	CResponseHandler* responsehandler =
+		CResponseHandler::NewL( *this, iTimerManager, *iServerResolver, aId,
+							    iICMPErrorWaitTime );
+	iList.AddLast( *responsehandler );
+	responsehandler->SendL( aParams, 
+	                        static_cast<CSIPResponse&>( aMessage ), 
+	                        aAddress, 
+	                        aStatus);
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::CancelSend
+// -----------------------------------------------------------------------------
+//
+TBool CTransportUdp::CancelSend( TRequestStatus& aStatus )
+	{
+	return iSender->FindAndCancel( aStatus );
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::CancelAllRequests
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::CancelAllRequests( CSIPConnection::TState aReason )
+	{
+	iSender->CancelAllRequests( aReason );
+	}
+    
+// -----------------------------------------------------------------------------
+// CTransportUdp::CancelResponseSend
+// -----------------------------------------------------------------------------
+//
+TBool CTransportUdp::CancelResponseSend( 
+    TTransactionId aId, 
+    TBool aCancelAlso2xxResponses )
+	{
+	CResponseHandler* listItem = 0;
+	iListIter.SetToFirst();
+	while ( ( listItem = iListIter++ ) != 0 )
+		{
+		if ( listItem->Handle( aId ) )
+			{
+			return listItem->CancelAll( aId, aCancelAlso2xxResponses );
+			}
+		}
+	return EFalse;
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::IsWaiting
+// -----------------------------------------------------------------------------
+//
+TBool CTransportUdp::IsWaiting( TUint aProtocol, TUint aPort )
+	{
+	return ( aPort == SourcePort() && aProtocol == KProtocolInetUdp );
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::SocketContainer
+// -----------------------------------------------------------------------------
+//
+CSocketContainer& CTransportUdp::SocketContainer()
+	{
+    if ( iIPv6SocketContainer  )
+	    {
+	    return *iIPv6SocketContainer;
+	    } 
+	return *iIPv4SocketContainer;
+	}
+// -----------------------------------------------------------------------------
+// CTransportUdp::SocketContainer
+// -----------------------------------------------------------------------------
+//
+CSocketContainer* CTransportUdp::SocketContainer( TUint aIPAddrFamily )
+	{
+	if ( aIPAddrFamily == KAfInet )
+	    {
+	    if ( iIPv4SocketContainer  )
+	        {
+	        return iIPv4SocketContainer;
+	        }
+	    return iIPv6SocketContainer;
+	    }
+	else
+	    {
+	    if ( iIPv6SocketContainer  )
+	        {
+	        return iIPv6SocketContainer;
+	        } 	    
+	    }
+	return NULL; // Only IPv6 socket can be used for sending to a IPv6 address
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::ICMPErrorL
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::ICMPErrorL( CSipConnectionMgr::TICMPError aICMPError,
+							    const TInetAddr& aSourceAddr )
+	{
+	CResponseHandler* listItem = 0;
+	iListIter.SetToFirst();
+	while ( ( listItem = iListIter++ ) != 0 )
+		{
+		listItem->ICMPErrorL( aICMPError, aSourceAddr );
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::RemoveResHandler
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::RemoveResHandler( CResponseHandler* aHandler )
+	{
+	if ( !iList.IsEmpty() )
+		{
+		iList.Remove( *aHandler );
+		delete aHandler;
+		__SIP_LOG( "CResHandler removed" )
+		}
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::ConnectionOpenL
+// -----------------------------------------------------------------------------
+//
+TBool CTransportUdp::ConnectionOpenL()
+	{
+	User::Leave( KErrNotSupported );
+	return EFalse;
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::DisconnectedL
+// -----------------------------------------------------------------------------
+//
+TBool CTransportUdp::DisconnectedL()
+	{
+	return EFalse;
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::GetSocketContainerL
+// -----------------------------------------------------------------------------
+//	
+CSocketContainer& CTransportUdp::GetSocketContainerL( 
+    const TInetAddr& aRemoteAddr )
+    {
+    CSocketContainer* socketContainer = 
+        SocketContainer( CSender::IpAddrType( aRemoteAddr ) );
+    __ASSERT_ALWAYS( socketContainer, User::Leave( KErrNotFound ) );
+    return *socketContainer;
+    }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::InformSendingStatus
+// -----------------------------------------------------------------------------
+//    
+void CTransportUdp::InformSendingStatus( const TInetAddr& /*aRemoteAddr*/ )
+    {
+    __SIP_INT_LOG2( "CTransportUdp::InformSendingStatus (socket IPv4,sending)", 
+                    iIPv4Socket.SubSessionHandle(), iIsSending )
+
+    __SIP_INT_LOG2( "CTransportUdp::InformSendingStatus (socket IPv6,sending)", 
+                    iIPv6Socket.SubSessionHandle(), iIsSending )
+    
+    iNATTraversal.SocketIdle( !iIsSending, iIPv4Socket );
+    iNATTraversal.SocketIdle( !iIsSending, iIPv6Socket );
+    }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::Sender
+// -----------------------------------------------------------------------------
+//
+CSender* CTransportUdp::Sender( const TSIPTransportParams& aParams,
+                                TUint aProtocol,
+							    const TInetAddr& /*aRemoteAddr*/)
+	{
+	if ( aProtocol == Protocol() && Match( aParams ) )
+		{
+		return iSender;
+		}
+    return 0;
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::Remove
+// -----------------------------------------------------------------------------
+//
+TBool CTransportUdp::Remove( TUint32 aTransportId )
+    {
+    TInt index = iTransportUsers.Find( aTransportId );	
+    if ( index != KErrNotFound )
+        {
+        iTransportUsers.Remove( index );
+        iTransportUsers.Compress();
+        }
+    
+	// If no more transport users left and this is "protected" transport,
+	// the whole transport can be removed
+	return ( iTransportUsers.Count() == 0 && IsReservedTransport() );
+    }
+	
+// -----------------------------------------------------------------------------
+// CTransportUdp::AddUserL
+// -----------------------------------------------------------------------------
+//
+TBool CTransportUdp::AddUserL( 
+    const TSIPTransportParams& aParams, 
+    TUint aReceivePort )
+    {
+    __ASSERT_ALWAYS( aReceivePort == iSourcePort, User::Leave( KErrArgument ) );
+    
+    // Don't allow duplicate entries
+    User::LeaveIfError( iTransportUsers.InsertInOrder( aParams.TransportId() ) );
+    
+    return ETrue;
+    }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::AcquireUdpSocket
+// -----------------------------------------------------------------------------
+//    
+RSocket* CTransportUdp::AcquireUdpSocket( 
+    MSocketUsagePermissionObserver* aObserver,
+    const TInetAddr& aRemoteAddr,
+    TBool& aPermissionToUse )
+    {    
+    aPermissionToUse = EFalse;
+    
+    // If observer is not provided, caller cannot use the socket
+    if ( aObserver )
+        {
+        // If sender is active, we cannot give permission until the
+        // send is complete.
+        aPermissionToUse = !iSender->IsActive();
+    
+        // When we give permission for the caller to use the socket, 
+        // sender cannot send until UdpSocketReleased is called.
+        iSender->SetSendPermission( !aPermissionToUse );
+    
+        iSocketUsagePermissionObserver = aObserver;
+        }
+
+    RSocket* socket = NULL;
+    if ( aRemoteAddr.Address() && iIPv4SocketContainer )
+        {
+        socket = &iIPv4Socket;
+        }
+    else
+        {
+        socket = &iIPv6Socket;
+        }
+        
+    return socket;
+    }
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::UdpSocketReleased
+// -----------------------------------------------------------------------------
+//                                        
+void CTransportUdp::UdpSocketReleased( 
+    MSocketUsagePermissionObserver* aObserver,
+    RSocket& aSocket )
+    {
+    if ( aObserver && 
+         ( iIPv4Socket.SubSessionHandle() == aSocket.SubSessionHandle() ||
+           iIPv6Socket.SubSessionHandle() == aSocket.SubSessionHandle() ) )
+        {
+        iSocketUsagePermissionObserver = 0;
+        iSender->SetSendPermission( ETrue );
+        TRAP_IGNORE( iSender->SendNextL() )
+        }
+    }
+        
+// -----------------------------------------------------------------------------
+// CTransportUdp::Remove
+// -----------------------------------------------------------------------------
+//
+TInt CTransportUdp::Remove()
+	{
+	return iTransportOwner->RemoveTransport( this );
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::IapId
+// -----------------------------------------------------------------------------
+//
+TUint32 CTransportUdp::IapId()
+	{
+	return iTransportOwner->IapId();
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::Sending
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::Sending( TBool aIsSending )
+    {
+    __SIP_INT_LOG2( "CTransportUdp::Sending (socket IPv4,sending)", 
+                    iIPv4Socket.SubSessionHandle(), iIsSending )
+
+    __SIP_INT_LOG2( "CTransportUdp::Sending (socket IPv6,sending)", 
+                    iIPv6Socket.SubSessionHandle(), iIsSending )
+    
+    iIsSending = aIsSending; 
+    
+    if ( iSocketUsagePermissionObserver )
+        {
+        iSocketUsagePermissionObserver->UsagePermissionChanged( iIPv4Socket, 
+                                                                !iIsSending );
+        iSocketUsagePermissionObserver->UsagePermissionChanged( iIPv6Socket, 
+                                                                !iIsSending );
+        }
+       
+    iNATTraversal.SocketIdle( !iIsSending, iIPv4Socket );
+    iNATTraversal.SocketIdle( !iIsSending, iIPv6Socket );
+    }
+    
+// -----------------------------------------------------------------------------
+// CTransportUdp::ReRouteL
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::ReRouteL( TUint aProtocol, 
+                              COutgoingData* aData )
+	{
+	iTransportOwner->ReRouteL( aProtocol, aData );
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::ReceivedDataL
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::ReceivedDataL( HBufC8* aData,
+								   const TInetAddr& aRemoteAddr,
+								   TBool aCompressed )
+	{
+	RecvL( aData, aRemoteAddr, aCompressed );
+	}
+
+// -----------------------------------------------------------------------------
+// CTransportUdp::SigCompHandler
+// -----------------------------------------------------------------------------
+//
+MSigCompController* CTransportUdp::SigCompHandler()
+	{
+	return SigCompressionHandler();
+	}
+// -----------------------------------------------------------------------------
+// CTransportUdp::RefreshSocketContainerL
+// -----------------------------------------------------------------------------
+//
+void CTransportUdp::RefreshSocketContainerL( TUint aFamily )
+    {
+    if ( aFamily == KAfInet && !iIPv4SocketContainer )
+        {
+    	iIPv4SocketContainer = CreateSocketContainerL( KAfInet, iIPv4Socket );
+    	if ( iIPv4SocketContainer )
+    	    {
+    	    iIPv4Receiver = CReceiver::NewL( *this, KAfInet );
+    	    iIPv4Receiver->Listen();
+    	    }
+        }
+    if ( aFamily == KAfInet6 && !iIPv6SocketContainer )
+        {
+    	iIPv6SocketContainer = CreateSocketContainerL( KAfInet6, iIPv6Socket );
+    	if ( iIPv6SocketContainer )
+    	    {
+    	    iIPv6Receiver = CReceiver::NewL( *this, KAfInet6 );
+    	    iIPv6Receiver->Listen();
+    	    }
+        }        
+    }
+// -----------------------------------------------------------------------------
+// CTransportUdp::CreateSocketContainerL
+// -----------------------------------------------------------------------------
+//
+CSocketContainer* CTransportUdp::CreateSocketContainerL( 
+    TUint aFamily, 
+    RSocket& aSocket )
+    {
+    CSocketContainer* socketContainer( NULL );
+ 	TInetAddr addr;
+	if ( iTransportOwner->GetLocalIPAddr( aFamily, addr ) )
+	    {
+    	User::LeaveIfError( 
+    	    aSocket.Open( *iSocketServ, KAfInet, KSockDatagram,
+    	                  KProtocolInetUdp, *iConnection ) );
+    	socketContainer = CSocketContainer::NewLC( aSocket );
+    	aSocket.SetOpt( KSoReuseAddr, KSolInetIp, 1 );
+    	addr.SetPort( iSourcePort );
+    	addr.SetFamily( aFamily );
+    	TInt err = aSocket.Bind( addr );
+    	if ( err == KErrInUse )
+    		{
+    		User::Leave( KErrSIPTransportFailure );
+    		}
+    	else
+    		{
+    		User::LeaveIfError( err );
+    		}
+    	CleanupStack::Pop( socketContainer );	
+	    }
+	return socketContainer;
+    }