realtimenetprots/sipfw/SIP/ConnectionMgr/src/CTransportUdp.cpp
changeset 0 307788aac0a8
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Name          : CTransportUdp.cpp
       
    15 // Part of       : ConnectionMgr
       
    16 // Version       : SIP/4.0 
       
    17 //
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 #include "CTransportUdp.h"
       
    23 #include "CSipConnection.h"
       
    24 #include "CErrorHandler.h"
       
    25 #include "CReceiver.h"
       
    26 #include "CSenderUdp.h"
       
    27 #include "CSIPServerResolver.h"
       
    28 #include "sipviaheader.h"
       
    29 #include "siphostport.h"
       
    30 #include "sipmessage.h"
       
    31 #include "sipresponse.h"
       
    32 #include "Lwtimer.h"
       
    33 #include "SipLogs.h"
       
    34 #include "CResHandler.h"
       
    35 #include "utf.h"
       
    36 #include "CommonConsts.h"
       
    37 #include "sipstrings.h"
       
    38 #include "sipstrconsts.h"
       
    39 #include "siperr.h"
       
    40 #include "NetworkInfo.h"
       
    41 #include "COwnerSettingsList.h"
       
    42 #include "CSocketContainer.h"
       
    43 #include "MSocketUsagePermissionObserver.h"
       
    44 #include <sipnattraversalcontroller.h>
       
    45 
       
    46 
       
    47 const TInt KTransportUsersGranularity = 2;
       
    48 
       
    49 
       
    50 // -----------------------------------------------------------------------------
       
    51 // CTransportUdp::NewL
       
    52 // -----------------------------------------------------------------------------
       
    53 //
       
    54 CTransportUdp* CTransportUdp::NewL( 
       
    55     RSocketServ& aServer, 
       
    56     TUint aPort,
       
    57     MTransactionFinder& aFinder, 
       
    58     MServerTaFactory& aTaFactory,
       
    59     MTransportOwner& aTransportOwner,
       
    60     MTimerManager& aTimerManager,
       
    61     CSIPServerResolver& aServerResolver,
       
    62     RConnection& aConnection,
       
    63     MSigCompController& aSigCompHandler,
       
    64     TUint aICMPErrorWaitTime,
       
    65     CNetworkInfo& aNetworkInfo,
       
    66     COwnerSettingsList& aSettingsList,
       
    67     const TSIPTransportParams& aTransportParams,
       
    68     CSIPNATTraversalController& aNATTraversal,
       
    69     TBool aOnlyForReceiving )
       
    70 	{
       
    71 	CTransportUdp* self = NewLC( aServer, aPort, aFinder, aTaFactory, 
       
    72 						     	 aTransportOwner, aTimerManager, 
       
    73 						     	 aServerResolver, aConnection, aSigCompHandler,
       
    74 						    	 aICMPErrorWaitTime, aNetworkInfo,
       
    75 						    	 aSettingsList, aTransportParams,
       
    76 						    	 aNATTraversal, aOnlyForReceiving );
       
    77 	CleanupStack::Pop( self );
       
    78 	return self;
       
    79 	}
       
    80 
       
    81 // -----------------------------------------------------------------------------
       
    82 // CTransportUdp::NewLC
       
    83 // -----------------------------------------------------------------------------
       
    84 //
       
    85 CTransportUdp* CTransportUdp::NewLC( 
       
    86     RSocketServ& aServer, 
       
    87     TUint aPort,
       
    88     MTransactionFinder& aFinder, 
       
    89     MServerTaFactory& aTaFactory,
       
    90     MTransportOwner& aTransportOwner,
       
    91     MTimerManager& aTimerManager,
       
    92     CSIPServerResolver& aServerResolver,
       
    93     RConnection& aConnection,
       
    94     MSigCompController& aSigCompHandler,
       
    95     TUint aICMPErrorWaitTime,
       
    96     CNetworkInfo& aNetworkInfo,
       
    97     COwnerSettingsList& aSettingsList,
       
    98     const TSIPTransportParams& aTransportParams,
       
    99     CSIPNATTraversalController& aNATTraversal,
       
   100     TBool aOnlyForReceiving )
       
   101 	{
       
   102 	CTransportUdp* self = new ( ELeave ) CTransportUdp( aServer, 
       
   103 	                                                    aPort,
       
   104 	                                                    aFinder, 
       
   105 	                                                    aTaFactory, 
       
   106 													    aTransportOwner,
       
   107 													    aTimerManager,
       
   108 													    aServerResolver,
       
   109 													    aConnection,
       
   110 													    aSigCompHandler,
       
   111 													    aICMPErrorWaitTime,
       
   112 													    aNetworkInfo,
       
   113 													    aSettingsList,
       
   114 													    aTransportParams,
       
   115 													    aNATTraversal,
       
   116 													    aOnlyForReceiving );
       
   117 	CleanupStack::PushL( self );
       
   118 	self->ConstructL();
       
   119 	return self;
       
   120 	}
       
   121 
       
   122 // -----------------------------------------------------------------------------
       
   123 // CTransportUdp::CTransportUdp
       
   124 // -----------------------------------------------------------------------------
       
   125 //
       
   126 CTransportUdp::CTransportUdp( 
       
   127     RSocketServ& aServer,
       
   128     TUint aPort, 
       
   129     MTransactionFinder& aFinder, 
       
   130     MServerTaFactory& aTaFactory,
       
   131     MTransportOwner& aTransportOwner,
       
   132     MTimerManager& aTimerManager,
       
   133     CSIPServerResolver& aServerResolver,
       
   134     RConnection& aConnection,
       
   135     MSigCompController& aSigCompHandler,
       
   136     TUint aICMPErrorWaitTime,
       
   137     CNetworkInfo& aNetworkInfo,
       
   138     COwnerSettingsList& aSettingsList,
       
   139     const TSIPTransportParams& aTransportParams,
       
   140     CSIPNATTraversalController& aNATTraversal,
       
   141     TBool aOnlyForReceiving ) 
       
   142         :
       
   143 	CTransport( aFinder, aTaFactory, aTransportOwner, aServerResolver,
       
   144 	            aSigCompHandler, aTransportParams, aNetworkInfo, 
       
   145 	            aSettingsList, aNATTraversal ),
       
   146 	iSocketServ( &aServer ),
       
   147 	iConnection( &aConnection ),
       
   148 	iSourcePort( aPort ),
       
   149 	iTimerManager( aTimerManager ),
       
   150 	iList( CResponseHandler::iOffset ),
       
   151 	iListIter( iList ),
       
   152 	iICMPErrorWaitTime( aICMPErrorWaitTime ),
       
   153 	iTransportUsers( KTransportUsersGranularity ),
       
   154 	iOnlyForReceiving( aOnlyForReceiving ),
       
   155 	iIsSending( EFalse )
       
   156 	{		
       
   157 	}
       
   158 
       
   159 // -----------------------------------------------------------------------------
       
   160 // CTransportUdp::ConstructL
       
   161 // -----------------------------------------------------------------------------
       
   162 //
       
   163 void CTransportUdp::ConstructL()
       
   164 	{
       
   165 	iErrorHandler =	CTransportErrorHandler::NewL( *this );
       
   166 	
       
   167     RefreshSocketContainerL( KAfInet );
       
   168     RefreshSocketContainerL( KAfInet6 );	                                   	
       
   169 	
       
   170 	iSender = CSenderUdp::NewL( *this, iSettingsList );
       
   171 	
       
   172 	iTransportUsers.AppendL( iTransportParams.TransportId() );
       
   173 	}
       
   174 
       
   175 // -----------------------------------------------------------------------------
       
   176 // CTransportUdp::~CTransportUdp
       
   177 // -----------------------------------------------------------------------------
       
   178 //
       
   179 CTransportUdp::~CTransportUdp()
       
   180 	{
       
   181     if ( iSocketUsagePermissionObserver )
       
   182 	    {
       
   183 	    iSocketUsagePermissionObserver->UsagePermissionChanged( iIPv4Socket, EFalse );
       
   184 	    iSocketUsagePermissionObserver->UsagePermissionChanged( iIPv6Socket, EFalse );
       
   185 	    }
       
   186 	
       
   187 	iNATTraversal.SocketIdle( EFalse, iIPv4Socket );
       
   188 	iNATTraversal.SocketIdle( EFalse, iIPv6Socket );
       
   189 	
       
   190 	CResponseHandler* listItem;
       
   191 	iListIter.SetToFirst();
       
   192 	while ( ( listItem = iListIter++ ) != 0 )
       
   193 		{
       
   194 		iList.Remove( *listItem );
       
   195 		delete listItem;
       
   196 		}
       
   197 	delete iErrorHandler;
       
   198 	delete iIPv4Receiver;
       
   199 	delete iIPv6Receiver;
       
   200 	delete iSender;
       
   201 	delete iIPv4SocketContainer;
       
   202 	delete iIPv6SocketContainer;
       
   203 	iNATTraversal.SocketIdle( EFalse, iIPv4Socket );
       
   204 	iIPv4Socket.Close();
       
   205 	iNATTraversal.SocketIdle( EFalse, iIPv6Socket );
       
   206 	iIPv6Socket.Close();
       
   207 	iTransportUsers.Close();
       
   208 	}
       
   209 	
       
   210 // -----------------------------------------------------------------------------
       
   211 // CTransportUdp::Handle
       
   212 // -----------------------------------------------------------------------------
       
   213 //
       
   214 TBool CTransportUdp::Handle( TUint32 aTransportId )
       
   215     {
       
   216     // Only interested about "protected" transports
       
   217     return ( ( aTransportId > 0 ) && 
       
   218              ( iTransportUsers.Find( aTransportId ) != KErrNotFound ) );
       
   219     }
       
   220 
       
   221 // -----------------------------------------------------------------------------
       
   222 // CTransportUdp::HandleMessage
       
   223 // -----------------------------------------------------------------------------
       
   224 //
       
   225 TBool CTransportUdp::HandleMessage( const TSIPTransportParams& aParams,
       
   226                                     RStringF aProtocol,
       
   227 								    const TInetAddr& /*aRemoteAddr*/,
       
   228 								    TUint aLocalPort,
       
   229 								    TBool aIsStrict )
       
   230     {
       
   231     // If not strict comparison, receiveonly mode has no significance
       
   232 	return ( aProtocol == SIPStrings::StringF( SipStrConsts::EUDP ) && 
       
   233 	         Match( aParams ) &&
       
   234 	         ( aLocalPort == 0 || iSourcePort == aLocalPort ) &&
       
   235 	         ( !aIsStrict || !iOnlyForReceiving ) );
       
   236 	}
       
   237 
       
   238 // -----------------------------------------------------------------------------
       
   239 // CTransportUdp::ResetSocketL
       
   240 // -----------------------------------------------------------------------------
       
   241 //
       
   242 void CTransportUdp::ResetSocketL()
       
   243 	{
       
   244 	iIPv4Socket.Close();
       
   245 	CSocketContainer* tmp = CreateSocketContainerL( KAfInet, iIPv4Socket );
       
   246 	delete iIPv4SocketContainer;
       
   247 	iIPv4SocketContainer = tmp;
       
   248 	
       
   249 	iIPv6Socket.Close();
       
   250 	tmp = CreateSocketContainerL( KAfInet6, iIPv6Socket );
       
   251 	delete iIPv6SocketContainer;
       
   252 	iIPv6SocketContainer = tmp;	
       
   253 	}
       
   254 		
       
   255 // -----------------------------------------------------------------------------
       
   256 // CTransportUdp::StopL
       
   257 // -----------------------------------------------------------------------------
       
   258 //
       
   259 TBool CTransportUdp::StopL()
       
   260 	{
       
   261 	if ( iIPv4Receiver )
       
   262 	    {
       
   263 	    iIPv4Receiver->Cancel();
       
   264 	    }	
       
   265 	if ( iIPv6Receiver )
       
   266 	    {
       
   267 	    iIPv6Receiver->Cancel();
       
   268 	    }
       
   269 	iSender->Cancel();
       
   270 		
       
   271 	// If there's binding observers, notify that old socket
       
   272 	// cannot be used anymore
       
   273 	return NotifyFlowFailure();
       
   274 	}
       
   275 
       
   276 // -----------------------------------------------------------------------------
       
   277 // CTransportUdp::ContinueL
       
   278 // -----------------------------------------------------------------------------
       
   279 //
       
   280 void CTransportUdp::ContinueL()
       
   281 	{
       
   282 	WaitL();
       
   283 	iSender->SendNextL();
       
   284 	}
       
   285 
       
   286 // -----------------------------------------------------------------------------
       
   287 // CTransportUdp::SourcePort
       
   288 // -----------------------------------------------------------------------------
       
   289 //
       
   290 TUint CTransportUdp::SourcePort()
       
   291 	{
       
   292 	return iSourcePort;
       
   293 	}
       
   294 
       
   295 // -----------------------------------------------------------------------------
       
   296 // CTransportUdp::WaitL
       
   297 // -----------------------------------------------------------------------------
       
   298 //
       
   299 void CTransportUdp::WaitL()
       
   300 	{
       
   301 	if ( iIPv4Receiver )
       
   302 	    {
       
   303 	    iIPv4Receiver->Listen();
       
   304 	    }
       
   305 	if ( iIPv6Receiver )
       
   306 	    {
       
   307 	    iIPv6Receiver->Listen();
       
   308 	    }
       
   309 	}
       
   310 
       
   311 // -----------------------------------------------------------------------------
       
   312 // CTransportUdp::SendToNetL
       
   313 // -----------------------------------------------------------------------------
       
   314 //
       
   315 void CTransportUdp::SendToNetL( const TSIPTransportParams& aParams,
       
   316                                 const TInetAddr& aAddress, 
       
   317 							    CSIPMessage& aMessage,
       
   318 							    TBool aForceUDP,
       
   319 							    TUint aOrigTransport,
       
   320 							    TRequestStatus &aStatus )
       
   321 	{
       
   322 	RefreshSocketContainerL( CSender::IpAddrType( aAddress ) );
       
   323 	HandleMixedAddressFamilysL( aMessage, aAddress );
       
   324 	
       
   325 	iSender->SendL(
       
   326 	    aParams, 
       
   327 	    aMessage, 
       
   328 	    aAddress, 
       
   329 	    aOrigTransport, 
       
   330 	    aStatus, 
       
   331 	    EFalse, 
       
   332 	    aForceUDP );
       
   333 	}
       
   334 
       
   335 // -----------------------------------------------------------------------------
       
   336 // CTransportUdp::SendToNetL
       
   337 // -----------------------------------------------------------------------------
       
   338 //
       
   339 void CTransportUdp::SendToNetL( const TSIPTransportParams& aParams,
       
   340                                 const TInetAddr& aAddress,
       
   341 							    CSIPMessage& aMessage,
       
   342 							    TRequestStatus &aStatus )
       
   343 	{
       
   344 	RefreshSocketContainerL( CSender::IpAddrType( aAddress ) );
       
   345 	HandleMixedAddressFamilysL( aMessage, aAddress );
       
   346 	
       
   347 	iSender->SendL( 
       
   348 	    aParams, 
       
   349 	    aMessage, 
       
   350 	    aAddress, 
       
   351 	    0, 
       
   352 	    aStatus, 
       
   353 	    EFalse, 
       
   354 	    EFalse );
       
   355 	}
       
   356 
       
   357 // -----------------------------------------------------------------------------
       
   358 // CTransportUdp::SendToNetL
       
   359 // -----------------------------------------------------------------------------
       
   360 //
       
   361 void CTransportUdp::SendToNetL( const TSIPTransportParams& aParams,
       
   362                                 const TInetAddr& aAddress, 
       
   363                                 TTransactionId aId, 
       
   364 							    CSIPMessage& aMessage, 
       
   365 							    TRequestStatus &aStatus )
       
   366 	{
       
   367 	RefreshSocketContainerL( CSender::IpAddrType( aAddress ) );
       
   368 	HandleMixedAddressFamilysL( aMessage, aAddress );
       
   369 	
       
   370 	CResponseHandler* listItem = 0;
       
   371 	iListIter.SetToFirst();
       
   372 	while ( ( listItem = iListIter++ ) != 0 )
       
   373 		{
       
   374 		if(listItem->Handle( aId ) ) 
       
   375 			{
       
   376 			listItem->SendL( aParams, 
       
   377 			                 static_cast<CSIPResponse&>( aMessage ), 
       
   378 			                 aAddress, 
       
   379 			                 aStatus );
       
   380 			return;
       
   381 			}
       
   382 		}
       
   383 	CResponseHandler* responsehandler =
       
   384 		CResponseHandler::NewL( *this, iTimerManager, *iServerResolver, aId,
       
   385 							    iICMPErrorWaitTime );
       
   386 	iList.AddLast( *responsehandler );
       
   387 	responsehandler->SendL( aParams, 
       
   388 	                        static_cast<CSIPResponse&>( aMessage ), 
       
   389 	                        aAddress, 
       
   390 	                        aStatus);
       
   391 	}
       
   392 
       
   393 // -----------------------------------------------------------------------------
       
   394 // CTransportUdp::CancelSend
       
   395 // -----------------------------------------------------------------------------
       
   396 //
       
   397 TBool CTransportUdp::CancelSend( TRequestStatus& aStatus )
       
   398 	{
       
   399 	return iSender->FindAndCancel( aStatus );
       
   400 	}
       
   401 
       
   402 // -----------------------------------------------------------------------------
       
   403 // CTransportUdp::CancelAllRequests
       
   404 // -----------------------------------------------------------------------------
       
   405 //
       
   406 void CTransportUdp::CancelAllRequests( CSIPConnection::TState aReason )
       
   407 	{
       
   408 	iSender->CancelAllRequests( aReason );
       
   409 	}
       
   410     
       
   411 // -----------------------------------------------------------------------------
       
   412 // CTransportUdp::CancelResponseSend
       
   413 // -----------------------------------------------------------------------------
       
   414 //
       
   415 TBool CTransportUdp::CancelResponseSend( 
       
   416     TTransactionId aId, 
       
   417     TBool aCancelAlso2xxResponses )
       
   418 	{
       
   419 	CResponseHandler* listItem = 0;
       
   420 	iListIter.SetToFirst();
       
   421 	while ( ( listItem = iListIter++ ) != 0 )
       
   422 		{
       
   423 		if ( listItem->Handle( aId ) )
       
   424 			{
       
   425 			return listItem->CancelAll( aId, aCancelAlso2xxResponses );
       
   426 			}
       
   427 		}
       
   428 	return EFalse;
       
   429 	}
       
   430 
       
   431 // -----------------------------------------------------------------------------
       
   432 // CTransportUdp::IsWaiting
       
   433 // -----------------------------------------------------------------------------
       
   434 //
       
   435 TBool CTransportUdp::IsWaiting( TUint aProtocol, TUint aPort )
       
   436 	{
       
   437 	return ( aPort == SourcePort() && aProtocol == KProtocolInetUdp );
       
   438 	}
       
   439 
       
   440 // -----------------------------------------------------------------------------
       
   441 // CTransportUdp::SocketContainer
       
   442 // -----------------------------------------------------------------------------
       
   443 //
       
   444 CSocketContainer& CTransportUdp::SocketContainer()
       
   445 	{
       
   446     if ( iIPv6SocketContainer  )
       
   447 	    {
       
   448 	    return *iIPv6SocketContainer;
       
   449 	    } 
       
   450 	return *iIPv4SocketContainer;
       
   451 	}
       
   452 // -----------------------------------------------------------------------------
       
   453 // CTransportUdp::SocketContainer
       
   454 // -----------------------------------------------------------------------------
       
   455 //
       
   456 CSocketContainer* CTransportUdp::SocketContainer( TUint aIPAddrFamily )
       
   457 	{
       
   458 	if ( aIPAddrFamily == KAfInet )
       
   459 	    {
       
   460 	    if ( iIPv4SocketContainer  )
       
   461 	        {
       
   462 	        return iIPv4SocketContainer;
       
   463 	        }
       
   464 	    return iIPv6SocketContainer;
       
   465 	    }
       
   466 	else
       
   467 	    {
       
   468 	    if ( iIPv6SocketContainer  )
       
   469 	        {
       
   470 	        return iIPv6SocketContainer;
       
   471 	        } 	    
       
   472 	    }
       
   473 	return NULL; // Only IPv6 socket can be used for sending to a IPv6 address
       
   474 	}
       
   475 
       
   476 // -----------------------------------------------------------------------------
       
   477 // CTransportUdp::ICMPErrorL
       
   478 // -----------------------------------------------------------------------------
       
   479 //
       
   480 void CTransportUdp::ICMPErrorL( CSipConnectionMgr::TICMPError aICMPError,
       
   481 							    const TInetAddr& aSourceAddr )
       
   482 	{
       
   483 	CResponseHandler* listItem = 0;
       
   484 	iListIter.SetToFirst();
       
   485 	while ( ( listItem = iListIter++ ) != 0 )
       
   486 		{
       
   487 		listItem->ICMPErrorL( aICMPError, aSourceAddr );
       
   488 		}
       
   489 	}
       
   490 
       
   491 // -----------------------------------------------------------------------------
       
   492 // CTransportUdp::RemoveResHandler
       
   493 // -----------------------------------------------------------------------------
       
   494 //
       
   495 void CTransportUdp::RemoveResHandler( CResponseHandler* aHandler )
       
   496 	{
       
   497 	if ( !iList.IsEmpty() )
       
   498 		{
       
   499 		iList.Remove( *aHandler );
       
   500 		delete aHandler;
       
   501 		__SIP_LOG( "CResHandler removed" )
       
   502 		}
       
   503 	}
       
   504 
       
   505 // -----------------------------------------------------------------------------
       
   506 // CTransportUdp::ConnectionOpenL
       
   507 // -----------------------------------------------------------------------------
       
   508 //
       
   509 TBool CTransportUdp::ConnectionOpenL()
       
   510 	{
       
   511 	User::Leave( KErrNotSupported );
       
   512 	return EFalse;
       
   513 	}
       
   514 
       
   515 // -----------------------------------------------------------------------------
       
   516 // CTransportUdp::DisconnectedL
       
   517 // -----------------------------------------------------------------------------
       
   518 //
       
   519 TBool CTransportUdp::DisconnectedL()
       
   520 	{
       
   521 	return EFalse;
       
   522 	}
       
   523 
       
   524 // -----------------------------------------------------------------------------
       
   525 // CTransportUdp::GetSocketContainerL
       
   526 // -----------------------------------------------------------------------------
       
   527 //	
       
   528 CSocketContainer& CTransportUdp::GetSocketContainerL( 
       
   529     const TInetAddr& aRemoteAddr )
       
   530     {
       
   531     CSocketContainer* socketContainer = 
       
   532         SocketContainer( CSender::IpAddrType( aRemoteAddr ) );
       
   533     __ASSERT_ALWAYS( socketContainer, User::Leave( KErrNotFound ) );
       
   534     return *socketContainer;
       
   535     }
       
   536 
       
   537 // -----------------------------------------------------------------------------
       
   538 // CTransportUdp::InformSendingStatus
       
   539 // -----------------------------------------------------------------------------
       
   540 //    
       
   541 void CTransportUdp::InformSendingStatus( const TInetAddr& /*aRemoteAddr*/ )
       
   542     {
       
   543     __SIP_INT_LOG2( "CTransportUdp::InformSendingStatus (socket IPv4,sending)", 
       
   544                     iIPv4Socket.SubSessionHandle(), iIsSending )
       
   545 
       
   546     __SIP_INT_LOG2( "CTransportUdp::InformSendingStatus (socket IPv6,sending)", 
       
   547                     iIPv6Socket.SubSessionHandle(), iIsSending )
       
   548     
       
   549     iNATTraversal.SocketIdle( !iIsSending, iIPv4Socket );
       
   550     iNATTraversal.SocketIdle( !iIsSending, iIPv6Socket );
       
   551     }
       
   552 
       
   553 // -----------------------------------------------------------------------------
       
   554 // CTransportUdp::Sender
       
   555 // -----------------------------------------------------------------------------
       
   556 //
       
   557 CSender* CTransportUdp::Sender( const TSIPTransportParams& aParams,
       
   558                                 TUint aProtocol,
       
   559 							    const TInetAddr& /*aRemoteAddr*/)
       
   560 	{
       
   561 	if ( aProtocol == Protocol() && Match( aParams ) )
       
   562 		{
       
   563 		return iSender;
       
   564 		}
       
   565     return 0;
       
   566 	}
       
   567 
       
   568 // -----------------------------------------------------------------------------
       
   569 // CTransportUdp::Remove
       
   570 // -----------------------------------------------------------------------------
       
   571 //
       
   572 TBool CTransportUdp::Remove( TUint32 aTransportId )
       
   573     {
       
   574     TInt index = iTransportUsers.Find( aTransportId );	
       
   575     if ( index != KErrNotFound )
       
   576         {
       
   577         iTransportUsers.Remove( index );
       
   578         iTransportUsers.Compress();
       
   579         }
       
   580     
       
   581 	// If no more transport users left and this is "protected" transport,
       
   582 	// the whole transport can be removed
       
   583 	return ( iTransportUsers.Count() == 0 && IsReservedTransport() );
       
   584     }
       
   585 	
       
   586 // -----------------------------------------------------------------------------
       
   587 // CTransportUdp::AddUserL
       
   588 // -----------------------------------------------------------------------------
       
   589 //
       
   590 TBool CTransportUdp::AddUserL( 
       
   591     const TSIPTransportParams& aParams, 
       
   592     TUint aReceivePort )
       
   593     {
       
   594     __ASSERT_ALWAYS( aReceivePort == iSourcePort, User::Leave( KErrArgument ) );
       
   595     
       
   596     // Don't allow duplicate entries
       
   597     User::LeaveIfError( iTransportUsers.InsertInOrder( aParams.TransportId() ) );
       
   598     
       
   599     return ETrue;
       
   600     }
       
   601 
       
   602 // -----------------------------------------------------------------------------
       
   603 // CTransportUdp::AcquireUdpSocket
       
   604 // -----------------------------------------------------------------------------
       
   605 //    
       
   606 RSocket* CTransportUdp::AcquireUdpSocket( 
       
   607     MSocketUsagePermissionObserver* aObserver,
       
   608     const TInetAddr& aRemoteAddr,
       
   609     TBool& aPermissionToUse )
       
   610     {    
       
   611     aPermissionToUse = EFalse;
       
   612     
       
   613     // If observer is not provided, caller cannot use the socket
       
   614     if ( aObserver )
       
   615         {
       
   616         // If sender is active, we cannot give permission until the
       
   617         // send is complete.
       
   618         aPermissionToUse = !iSender->IsActive();
       
   619     
       
   620         // When we give permission for the caller to use the socket, 
       
   621         // sender cannot send until UdpSocketReleased is called.
       
   622         iSender->SetSendPermission( !aPermissionToUse );
       
   623     
       
   624         iSocketUsagePermissionObserver = aObserver;
       
   625         }
       
   626 
       
   627     RSocket* socket = NULL;
       
   628     if ( aRemoteAddr.Address() && iIPv4SocketContainer )
       
   629         {
       
   630         socket = &iIPv4Socket;
       
   631         }
       
   632     else
       
   633         {
       
   634         socket = &iIPv6Socket;
       
   635         }
       
   636         
       
   637     return socket;
       
   638     }
       
   639 
       
   640 // -----------------------------------------------------------------------------
       
   641 // CTransportUdp::UdpSocketReleased
       
   642 // -----------------------------------------------------------------------------
       
   643 //                                        
       
   644 void CTransportUdp::UdpSocketReleased( 
       
   645     MSocketUsagePermissionObserver* aObserver,
       
   646     RSocket& aSocket )
       
   647     {
       
   648     if ( aObserver && 
       
   649          ( iIPv4Socket.SubSessionHandle() == aSocket.SubSessionHandle() ||
       
   650            iIPv6Socket.SubSessionHandle() == aSocket.SubSessionHandle() ) )
       
   651         {
       
   652         iSocketUsagePermissionObserver = 0;
       
   653         iSender->SetSendPermission( ETrue );
       
   654         TRAP_IGNORE( iSender->SendNextL() )
       
   655         }
       
   656     }
       
   657         
       
   658 // -----------------------------------------------------------------------------
       
   659 // CTransportUdp::Remove
       
   660 // -----------------------------------------------------------------------------
       
   661 //
       
   662 TInt CTransportUdp::Remove()
       
   663 	{
       
   664 	return iTransportOwner->RemoveTransport( this );
       
   665 	}
       
   666 
       
   667 // -----------------------------------------------------------------------------
       
   668 // CTransportUdp::IapId
       
   669 // -----------------------------------------------------------------------------
       
   670 //
       
   671 TUint32 CTransportUdp::IapId()
       
   672 	{
       
   673 	return iTransportOwner->IapId();
       
   674 	}
       
   675 
       
   676 // -----------------------------------------------------------------------------
       
   677 // CTransportUdp::Sending
       
   678 // -----------------------------------------------------------------------------
       
   679 //
       
   680 void CTransportUdp::Sending( TBool aIsSending )
       
   681     {
       
   682     __SIP_INT_LOG2( "CTransportUdp::Sending (socket IPv4,sending)", 
       
   683                     iIPv4Socket.SubSessionHandle(), iIsSending )
       
   684 
       
   685     __SIP_INT_LOG2( "CTransportUdp::Sending (socket IPv6,sending)", 
       
   686                     iIPv6Socket.SubSessionHandle(), iIsSending )
       
   687     
       
   688     iIsSending = aIsSending; 
       
   689     
       
   690     if ( iSocketUsagePermissionObserver )
       
   691         {
       
   692         iSocketUsagePermissionObserver->UsagePermissionChanged( iIPv4Socket, 
       
   693                                                                 !iIsSending );
       
   694         iSocketUsagePermissionObserver->UsagePermissionChanged( iIPv6Socket, 
       
   695                                                                 !iIsSending );
       
   696         }
       
   697        
       
   698     iNATTraversal.SocketIdle( !iIsSending, iIPv4Socket );
       
   699     iNATTraversal.SocketIdle( !iIsSending, iIPv6Socket );
       
   700     }
       
   701     
       
   702 // -----------------------------------------------------------------------------
       
   703 // CTransportUdp::ReRouteL
       
   704 // -----------------------------------------------------------------------------
       
   705 //
       
   706 void CTransportUdp::ReRouteL( TUint aProtocol, 
       
   707                               COutgoingData* aData )
       
   708 	{
       
   709 	iTransportOwner->ReRouteL( aProtocol, aData );
       
   710 	}
       
   711 
       
   712 // -----------------------------------------------------------------------------
       
   713 // CTransportUdp::ReceivedDataL
       
   714 // -----------------------------------------------------------------------------
       
   715 //
       
   716 void CTransportUdp::ReceivedDataL( HBufC8* aData,
       
   717 								   const TInetAddr& aRemoteAddr,
       
   718 								   TBool aCompressed )
       
   719 	{
       
   720 	RecvL( aData, aRemoteAddr, aCompressed );
       
   721 	}
       
   722 
       
   723 // -----------------------------------------------------------------------------
       
   724 // CTransportUdp::SigCompHandler
       
   725 // -----------------------------------------------------------------------------
       
   726 //
       
   727 MSigCompController* CTransportUdp::SigCompHandler()
       
   728 	{
       
   729 	return SigCompressionHandler();
       
   730 	}
       
   731 // -----------------------------------------------------------------------------
       
   732 // CTransportUdp::RefreshSocketContainerL
       
   733 // -----------------------------------------------------------------------------
       
   734 //
       
   735 void CTransportUdp::RefreshSocketContainerL( TUint aFamily )
       
   736     {
       
   737     if ( aFamily == KAfInet && !iIPv4SocketContainer )
       
   738         {
       
   739     	iIPv4SocketContainer = CreateSocketContainerL( KAfInet, iIPv4Socket );
       
   740     	if ( iIPv4SocketContainer )
       
   741     	    {
       
   742     	    iIPv4Receiver = CReceiver::NewL( *this, KAfInet );
       
   743     	    iIPv4Receiver->Listen();
       
   744     	    }
       
   745         }
       
   746     if ( aFamily == KAfInet6 && !iIPv6SocketContainer )
       
   747         {
       
   748     	iIPv6SocketContainer = CreateSocketContainerL( KAfInet6, iIPv6Socket );
       
   749     	if ( iIPv6SocketContainer )
       
   750     	    {
       
   751     	    iIPv6Receiver = CReceiver::NewL( *this, KAfInet6 );
       
   752     	    iIPv6Receiver->Listen();
       
   753     	    }
       
   754         }        
       
   755     }
       
   756 // -----------------------------------------------------------------------------
       
   757 // CTransportUdp::CreateSocketContainerL
       
   758 // -----------------------------------------------------------------------------
       
   759 //
       
   760 CSocketContainer* CTransportUdp::CreateSocketContainerL( 
       
   761     TUint aFamily, 
       
   762     RSocket& aSocket )
       
   763     {
       
   764     CSocketContainer* socketContainer( NULL );
       
   765  	TInetAddr addr;
       
   766 	if ( iTransportOwner->GetLocalIPAddr( aFamily, addr ) )
       
   767 	    {
       
   768     	User::LeaveIfError( 
       
   769     	    aSocket.Open( *iSocketServ, KAfInet, KSockDatagram,
       
   770     	                  KProtocolInetUdp, *iConnection ) );
       
   771     	socketContainer = CSocketContainer::NewLC( aSocket );
       
   772     	aSocket.SetOpt( KSoReuseAddr, KSolInetIp, 1 );
       
   773     	addr.SetPort( iSourcePort );
       
   774     	addr.SetFamily( aFamily );
       
   775     	TInt err = aSocket.Bind( addr );
       
   776     	if ( err == KErrInUse )
       
   777     		{
       
   778     		User::Leave( KErrSIPTransportFailure );
       
   779     		}
       
   780     	else
       
   781     		{
       
   782     		User::LeaveIfError( err );
       
   783     		}
       
   784     	CleanupStack::Pop( socketContainer );	
       
   785 	    }
       
   786 	return socketContainer;
       
   787     }