realtimenetprots/sipfw/SIP/ConnectionMgr/src/CTransport.cpp
changeset 0 307788aac0a8
child 20 a7d1e54a7332
equal deleted inserted replaced
-1:000000000000 0:307788aac0a8
       
     1 // Copyright (c) 2007-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          : CTransport.cpp
       
    15 // Part of       : ConnectionMgr
       
    16 // Version       : SIP/6.0 
       
    17 //
       
    18 
       
    19 
       
    20 
       
    21 #include "MHandler.h"
       
    22 #include "CTransport.h"
       
    23 #include "MTransportOwner.h"
       
    24 #include "CErrorHandler.h"
       
    25 #include "MTransactionFinder.h"
       
    26 #include "MServerTaFactory.h"
       
    27 #include "sipmessageparser.h"
       
    28 #include "MReceiverObserver.h"
       
    29 #include "SipLogs.h"
       
    30 #include "sipcontactheader.h"
       
    31 #include "sipaddress.h"
       
    32 #include "sipuri.h"
       
    33 #include "siptoheader.h"
       
    34 #include "sipfromheader.h"
       
    35 #include "sipcallidheader.h"
       
    36 #include "sipcseqheader.h"
       
    37 #include "sipviaheader.h"
       
    38 #include "sipheaderbase.h"
       
    39 #include "sipmessageparser.h"
       
    40 #include "siphostport.h"
       
    41 #include "sipcontenttypeheader.h"
       
    42 #include "sipmaxforwardsheader.h"
       
    43 #include "CSIPServerResolver.h"
       
    44 #include "utf.h"
       
    45 #include "CommonConsts.h"
       
    46 #include "sipstrings.h"
       
    47 #include "sipstrconsts.h"
       
    48 #include "uricontainer.h"
       
    49 #include "NetworkInfo.h"
       
    50 #include "COwnerSettingsList.h"
       
    51 #include "TSIPTransportParams.h"
       
    52 #include "MSigCompController.h"
       
    53 #include "CSocketContainer.h"
       
    54 #include "siperr.h"
       
    55 #include <sipnatbindingobserver.h>
       
    56 #include <sipnattraversalcontroller.h>
       
    57 
       
    58 
       
    59 const TUint KBadRequest = 400;
       
    60 const TUint KVersionError = 505;
       
    61 
       
    62 // -----------------------------------------------------------------------------
       
    63 // CTransport::CTransport
       
    64 // -----------------------------------------------------------------------------
       
    65 //
       
    66 CTransport::CTransport( MTransactionFinder& aFinder, 
       
    67 					    MServerTaFactory& aTaFactory,
       
    68 					    MTransportOwner& aTransportOwner,
       
    69 					    CSIPServerResolver& aServerResolver,
       
    70 					    MSigCompController& aSigCompHandler,
       
    71 					    const TSIPTransportParams& aTransportParams,
       
    72 					    CNetworkInfo& aNetworkInfo,
       
    73 					    COwnerSettingsList& aSettingsList,
       
    74 					    CSIPNATTraversalController& aNATTraversal ) :
       
    75 	iTransportParams( aTransportParams ),
       
    76 	iSettingsList( aSettingsList ),
       
    77 	iNATTraversal( aNATTraversal ),
       
    78 	iTaFinder( &aFinder ),
       
    79 	iTaFactory( &aTaFactory ),
       
    80 	iSigCompHandler( &aSigCompHandler ),
       
    81 	iNetworkInfo( aNetworkInfo )
       
    82 	{
       
    83 	iServerResolver = &aServerResolver;
       
    84 	iTransportOwner = &aTransportOwner;
       
    85 	}
       
    86 
       
    87 // -----------------------------------------------------------------------------
       
    88 // CTransport::~CTransport
       
    89 // -----------------------------------------------------------------------------
       
    90 //
       
    91 CTransport::~CTransport()
       
    92 	{
       
    93 	iIDArray.Reset();
       
    94 	iIDArray.Close();
       
    95 	iBindingObservers.Reset();
       
    96 	iBindingObservers.Close();
       
    97 	}
       
    98 
       
    99 // -----------------------------------------------------------------------------
       
   100 // CTransport::RecvL
       
   101 // -----------------------------------------------------------------------------
       
   102 //
       
   103 void CTransport::RecvL( HBufC8* aData,
       
   104 					    const TInetAddr& aRemoteAddr,
       
   105 					    TBool aCompressed )
       
   106 
       
   107 	{
       
   108 	__ASSERT_DEBUG( aData, User::Panic( _L("Nullpointer"), KErrGeneral ) );
       
   109 
       
   110 	CleanupStack::PushL( aData );
       
   111 	CSIPMessageParser* sipparser = CSIPMessageParser::NewLC();	
       
   112 	HBufC8* dataCopy = aData->Des().AllocL();
       
   113 	CSIPMessage* message( NULL );
       
   114 	TInt parserError = sipparser->FromText( aData, &message );
       
   115 	CleanupStack::PopAndDestroy( sipparser );
       
   116     CleanupStack::Pop(aData);
       
   117     CleanupStack::PushL(dataCopy);
       
   118 	
       
   119 	if ( !message && parserError )
       
   120 	    {
       
   121 	    // Show data to NATTraversalController if message couldn't be parsed
       
   122 	    // and it was received via UDP (might be e.g. a STUN binding response).
       
   123 	    TBool permissionToUse( EFalse );
       
   124 	    RSocket* socket = AcquireUdpSocket( 0, aRemoteAddr, permissionToUse );
       
   125 	    if ( socket )
       
   126 	        {
       
   127 	       	__SIP_LOG( "Received unrecognized data, passing to NATTraversal" )
       
   128 	        
       
   129 	        // NOTE: NATTraversal does not use the socket for sending
       
   130 	        // in DataReceived phase.
       
   131 	        TBool handled( EFalse );
       
   132 	        iNATTraversal.DataReceivedL( *dataCopy, *socket, handled );
       
   133 	        
       
   134 	        // Release immediately
       
   135 	        UdpSocketReleased( 0, *socket );
       
   136 	        }
       
   137 	    CleanupStack::PopAndDestroy( dataCopy );
       
   138 	    }
       
   139 	else
       
   140 	    {
       
   141 	    CleanupStack::PopAndDestroy( dataCopy );
       
   142 	    CleanupStack::PushL( message );
       
   143 	    RecvL( message, aRemoteAddr, parserError, aCompressed );
       
   144 	    CleanupStack::Pop( message );
       
   145 	    }
       
   146 	}
       
   147 
       
   148 // -----------------------------------------------------------------------------
       
   149 // CTransport::RecvL
       
   150 // -----------------------------------------------------------------------------
       
   151 //
       
   152 void CTransport::RecvL( CSIPMessage* aMessage,
       
   153 					    const TInetAddr& aRemoteAddr, 
       
   154 					    TInt aParserError,
       
   155 					    TBool aCompressed )
       
   156 	{
       
   157 	HandleSigCompAllowDenyL( aRemoteAddr, aParserError, aCompressed ); 
       
   158 	
       
   159 	if ( aMessage )
       
   160 		{
       
   161 		if ( aParserError == KErrNone && AllMandatoryHeaders( *aMessage ) )
       
   162 			{
       
   163             __SIP_ADDR_LOG( "Incoming message from", aRemoteAddr )
       
   164 				
       
   165 			if ( aMessage->IsRequest() )
       
   166 				{
       
   167 				if ( HandleServerRequestL( aMessage, aRemoteAddr ) == KErrNone )
       
   168 					{
       
   169 					RouteL( aMessage, aRemoteAddr );
       
   170 					return;
       
   171 					}
       
   172 				}
       
   173 			else
       
   174 				{
       
   175 				if ( HandleServerResponseL( aMessage, aRemoteAddr ) )
       
   176 					{
       
   177 					RouteL( aMessage, aRemoteAddr );
       
   178 					return;
       
   179 					}
       
   180 				}
       
   181 			}
       
   182 		else
       
   183 			{			
       
   184 			if ( aMessage->IsRequest() && !IsAck( *aMessage ) )
       
   185 				{
       
   186 				SetReceivedIfNeededL( TopViaHeader( aMessage ), aRemoteAddr );
       
   187 				SendErrorResponseL( KBadRequest,
       
   188 			                        SipStrConsts::EPhraseBadRequest, 
       
   189 					                *aMessage,
       
   190 				                    aRemoteAddr );
       
   191 				__SIP_LOG( "Invalid SIP Request" )
       
   192 				}
       
   193 			else
       
   194 				{
       
   195 				__SIP_LOG( "Invalid SIP Response or ACK" )
       
   196 				}
       
   197 				
       
   198 			__SIP_DES8_LOG( "Invalid data: ", aMessage->Content() )
       
   199 			__SIP_INT_LOG1( "Parser error", aParserError )
       
   200 			}
       
   201 		}
       
   202 	else
       
   203 		{
       
   204 		__SIP_INT_LOG1( "Parser error", aParserError )
       
   205 		}
       
   206 	delete aMessage;
       
   207 	}
       
   208 
       
   209 // -----------------------------------------------------------------------------
       
   210 // CTransport::RouteL
       
   211 // -----------------------------------------------------------------------------
       
   212 //
       
   213 void CTransport::RouteL( CSIPMessage* aMessage, const TInetAddr& aRemoteAddr )
       
   214 	{
       
   215 	TInt leaveValue = KErrNone;
       
   216 	
       
   217 	MReceiverObserver* receiver = iTaFinder->Search( *aMessage );
       
   218 	if ( receiver )
       
   219 		{
       
   220 		const TSIPTransportParams& tpParams = receiver->TransportParams();
       
   221 		
       
   222 		// Discard the message if receiving is not allowed
       
   223 		if ( !iSettingsList.IsReceivingAllowed( tpParams, 
       
   224 		                                        aRemoteAddr, 
       
   225 		                                        Protocol(), 
       
   226 		                                        SourcePort() ) )
       
   227 		    {
       
   228 		    delete aMessage;
       
   229 		    return;
       
   230 		    }
       
   231 		
       
   232 		if ( aMessage->IsRequest() )
       
   233 			{
       
   234 			TRAP( leaveValue,
       
   235 				  receiver->ReceiveL( static_cast<CSIPRequest*>( aMessage ) ) );
       
   236 			}
       
   237 		else
       
   238 			{
       
   239 			HandleResponseNATTraversalL( 
       
   240 			        static_cast< CSIPResponse& >( *aMessage ), 
       
   241 			        aRemoteAddr,
       
   242 			        const_cast<TSIPTransportParams&>(
       
   243 			            tpParams ).NATBindingObserver() );
       
   244 			   
       
   245 			TRAP( leaveValue,
       
   246 				  receiver->ReceiveL( static_cast<CSIPResponse*>( aMessage ) ) );
       
   247 			}
       
   248 		if ( leaveValue != KErrNone )
       
   249 			{
       
   250 			delete aMessage;
       
   251 			receiver->LeaveOccurred( leaveValue );
       
   252 			}
       
   253 		}
       
   254 	else
       
   255 		{
       
   256 		if ( aMessage->IsRequest() )
       
   257 			{
       
   258 			TTransactionId id;
       
   259 			// OwnerId cannot be known at this stage, default id will be used
       
   260 			TSIPTransportParams tpParams( KDefaultOwnerId,
       
   261 										  iTransportOwner->IapId() );
       
   262 			// Find out whether some existing SAs should be used also for
       
   263 			// this new transaction
       
   264 			TUint32 tpId = iSettingsList.FindTransportId( aRemoteAddr );
       
   265 			
       
   266 			tpParams.SetTransportId( tpId );
       
   267 			
       
   268 			receiver = iTaFactory->NewTransactionL(
       
   269 				static_cast<CSIPRequest&>( *aMessage ),
       
   270 				tpParams,
       
   271 				id );
       
   272 			if ( receiver )
       
   273 				{
       
   274 				if ( IsConnectedTransport() )
       
   275 					{
       
   276 					TResponseRoute route( id, aRemoteAddr );
       
   277 					iIDArray.Append( route );
       
   278 					}
       
   279 				TRAP( leaveValue,
       
   280 					  receiver->ReceiveL( static_cast<CSIPRequest*>( aMessage ) ) );
       
   281 				if ( leaveValue != KErrNone )
       
   282 					{
       
   283 					delete aMessage;
       
   284 					receiver->LeaveOccurred( leaveValue );
       
   285 					}
       
   286 				}
       
   287 			else
       
   288 				{
       
   289 				delete aMessage;
       
   290 				}
       
   291 			}
       
   292 		else
       
   293 			{
       
   294 			delete aMessage;
       
   295 			}
       
   296 		}
       
   297 	}
       
   298 
       
   299 // -----------------------------------------------------------------------------
       
   300 // CTransport::Send
       
   301 // -----------------------------------------------------------------------------
       
   302 //
       
   303 void CTransport::Send( const TSIPTransportParams& aParams,
       
   304                        CSIPResponse& aResponse,
       
   305 					   const TInetAddr& aAddr,
       
   306 					   TRequestStatus &aStatus )
       
   307 	{
       
   308 	TRAPD( leaveValue,
       
   309 		   SendToNetL( aParams, aAddr, aResponse, EFalse, Protocol(), aStatus ) );
       
   310 	if ( leaveValue != KErrNone )
       
   311 		{
       
   312 		TRequestStatus* stat = &aStatus;
       
   313 		User::RequestComplete( stat, leaveValue );
       
   314 		}
       
   315 	}
       
   316 
       
   317 // -----------------------------------------------------------------------------
       
   318 // CTransport::Send
       
   319 // -----------------------------------------------------------------------------
       
   320 //
       
   321 void CTransport::Send( const TSIPTransportParams& aParams,
       
   322                        CSIPResponse& aResponse,
       
   323 					   TTransactionId aId,
       
   324 					   TRequestStatus &aStatus )
       
   325 	{
       
   326 	TInt leaveValue = KErrNone;
       
   327 	TInetAddr remoteAddr;
       
   328 	
       
   329 	if ( Protocol() == KProtocolInetUdp )
       
   330 		{
       
   331 		TRAP( leaveValue, 
       
   332 			  HandleClientResponseL( aParams, &aResponse, remoteAddr );
       
   333 			  SendToNetL( aParams, remoteAddr, aId, aResponse, aStatus ) );
       
   334 		if ( leaveValue != KErrNone )
       
   335 			{
       
   336 			TRequestStatus* stat = &aStatus;
       
   337 			User::RequestComplete( stat, leaveValue );
       
   338 			}
       
   339 		}
       
   340 	else
       
   341 		{
       
   342 		TInt pos;
       
   343 		pos = iIDArray.Count();
       
   344 		while ( pos > 0 )
       
   345 			{
       
   346 			if ( iIDArray[ pos - 1 ].TAId() == aId )
       
   347 				{
       
   348 				TRAP( leaveValue,
       
   349 					  UpdateContactHeadersL( aParams, &aResponse, ETrue );
       
   350 					  SendToNetL( aParams,
       
   351 	                              iIDArray[ pos - 1 ].Address(),
       
   352 								  aResponse,
       
   353 								  EFalse,
       
   354 								  0,
       
   355 								  aStatus ) );
       
   356 				if ( leaveValue != KErrNone )
       
   357 					{
       
   358 					TRequestStatus* stat = &aStatus;
       
   359 					User::RequestComplete( stat, leaveValue );
       
   360 					}
       
   361 				return;
       
   362 				}
       
   363 			pos--;
       
   364 			}
       
   365 		TRAP( leaveValue,
       
   366 			  HandleClientResponseL( aParams, &aResponse, remoteAddr );
       
   367 			  SendToNetL( aParams, remoteAddr, aResponse, EFalse, Protocol(), aStatus ) );
       
   368 		if ( leaveValue != KErrNone )
       
   369 			{
       
   370 			TRequestStatus* stat = &aStatus;
       
   371 			User::RequestComplete( stat, leaveValue );
       
   372 			}
       
   373 		}
       
   374 	}
       
   375 
       
   376 // -----------------------------------------------------------------------------
       
   377 // CTransport::Send
       
   378 // -----------------------------------------------------------------------------
       
   379 //
       
   380 void CTransport::Send( const TSIPTransportParams& aParams,
       
   381                        CSIPRequest& aRequest,
       
   382                        TBool aForceUDP,
       
   383 					   const TInetAddr& aAddr,
       
   384 					   TUint aOrigTransport,
       
   385 					   TRequestStatus &aStatus,
       
   386 					   TBool aPublicAddrResolved )
       
   387 	{
       
   388 	TInt leaveValue = KErrNone;
       
   389 	TRAP( leaveValue, 
       
   390 		  HandleClientRequestL( aParams, aRequest, aPublicAddrResolved );
       
   391 		  UpdateListenersL( aParams, &aRequest );
       
   392 		  SendToNetL( aParams, aAddr, aRequest, aForceUDP, aOrigTransport, aStatus ) );
       
   393 		 
       
   394 	if ( leaveValue != KErrNone )
       
   395 		{
       
   396 		TRequestStatus* stat = &aStatus;
       
   397 		User::RequestComplete( stat, leaveValue );
       
   398 		}
       
   399 	}
       
   400 
       
   401 // -----------------------------------------------------------------------------
       
   402 // CTransport::HandleL
       
   403 // -----------------------------------------------------------------------------
       
   404 //
       
   405 TBool CTransport::HandleL(
       
   406     const TSIPTransportParams& aParams,
       
   407     CSIPMessage* aMessage, 
       
   408     TTransactionId aId,
       
   409     TBool aIsStrict )
       
   410 	{
       
   411 	if ( !aMessage ) 
       
   412 		{
       
   413 		return EFalse;
       
   414 		}
       
   415 	TInt pos = iIDArray.Count();
       
   416 	while ( pos > 0 )
       
   417 		{
       
   418 		if ( iIDArray[ pos - 1 ].TAId() == aId )	
       
   419 			{
       
   420 			return ETrue;
       
   421 			}
       
   422 		pos--;
       
   423 		}
       
   424 
       
   425     if ( aIsStrict )
       
   426         {
       
   427         return EFalse;
       
   428         }
       
   429         
       
   430 	TInetAddr remoteAddr;
       
   431 	HandleClientResponseL( aParams, aMessage, remoteAddr );
       
   432 	return HandleL( aParams, aMessage, remoteAddr, 0, ETrue );
       
   433 	}
       
   434 
       
   435 // -----------------------------------------------------------------------------
       
   436 // CTransport::HandleL
       
   437 // -----------------------------------------------------------------------------
       
   438 //
       
   439 TBool CTransport::HandleL(
       
   440     const TSIPTransportParams& aParams,
       
   441     CSIPMessage* aMessage, 
       
   442     const TInetAddr& aAddr,
       
   443     TUint aLocalPort,
       
   444     TBool aIsStrict )
       
   445 	{
       
   446 	if ( !aMessage ) 
       
   447 		{
       
   448 		return EFalse;
       
   449 		}
       
   450 	CSIPViaHeader* viaHeader = TopViaHeader( aMessage );
       
   451 	if ( viaHeader )
       
   452 		{
       
   453 		if ( HandleMessage( aParams, 
       
   454 		                    viaHeader->Transport(), 
       
   455 		                    aAddr,
       
   456 		                    aLocalPort,
       
   457 		                    aIsStrict ) )
       
   458 			{
       
   459 			return ETrue;
       
   460 			}
       
   461 		}
       
   462 	return EFalse;
       
   463 	}
       
   464 
       
   465 // -----------------------------------------------------------------------------
       
   466 // CTransport::Handle
       
   467 // -----------------------------------------------------------------------------
       
   468 //
       
   469 TBool CTransport::Handle( TUint32 aTransportId )
       
   470     {
       
   471     return ( IsReservedTransport() && 
       
   472              iTransportParams.TransportId() == aTransportId );
       
   473     }
       
   474     
       
   475 // -----------------------------------------------------------------------------
       
   476 // CTransport::Match
       
   477 // -----------------------------------------------------------------------------
       
   478 //	
       
   479 TBool CTransport::Match( const TSIPTransportParams& aParams )
       
   480     {
       
   481 	return ( aParams.TransportId() == 0 || Handle( aParams.TransportId() ) );
       
   482     }
       
   483 
       
   484 // -----------------------------------------------------------------------------
       
   485 // CTransport::HasRemoteHost
       
   486 // -----------------------------------------------------------------------------
       
   487 //
       
   488 TBool CTransport::HasRemoteHost(
       
   489     const TSIPTransportParams& aParams,
       
   490     const TInetAddr& aRemoteHost,
       
   491     RStringF aProtocol )
       
   492 	{
       
   493 	return HandleMessage( aParams, aProtocol, aRemoteHost, 0, ETrue );
       
   494 	}
       
   495 
       
   496 // -----------------------------------------------------------------------------
       
   497 // CTransport::Remove
       
   498 // -----------------------------------------------------------------------------
       
   499 //
       
   500 TBool CTransport::Remove( const TSIPTransportParams& aParams )
       
   501     {
       
   502     // Default transports are not removed when owner closes its connection.
       
   503     // Also removal of persistent and reserved transport are handled separately.
       
   504     return ( !IsDefault() &&
       
   505              iTransportParams.OwnerId() == aParams.OwnerId() &&
       
   506              !IsPersistent() &&
       
   507              !IsReservedTransport() );
       
   508     }
       
   509 
       
   510 // -----------------------------------------------------------------------------
       
   511 // CTransport::Remove
       
   512 // -----------------------------------------------------------------------------
       
   513 //
       
   514 TBool CTransport::Remove( MSIPNATBindingObserver& aSIPNATBindingObserver )
       
   515     {
       
   516     return ( !IsDefault() && RemoveBindingObserver( aSIPNATBindingObserver ) );
       
   517     }
       
   518 
       
   519 // -----------------------------------------------------------------------------
       
   520 // CTransport::Shutdown
       
   521 // -----------------------------------------------------------------------------
       
   522 //    
       
   523 TBool CTransport::Shutdown( 
       
   524     TUint32 /*aTransportId*/,
       
   525     MSIPTransportRemovalObserver* /*aRemovalObserver*/ )
       
   526     {
       
   527     return EFalse;
       
   528     }
       
   529     
       
   530 // -----------------------------------------------------------------------------
       
   531 // CTransport::IsReservedTransport
       
   532 // -----------------------------------------------------------------------------
       
   533 //	
       
   534 TBool CTransport::IsReservedTransport() const
       
   535     {
       
   536     return ( iTransportParams.TransportId() > 0 );
       
   537     }
       
   538 
       
   539 // -----------------------------------------------------------------------------
       
   540 // CTransport::AcquireUdpSocketL
       
   541 // -----------------------------------------------------------------------------
       
   542 //    
       
   543 RSocket* CTransport::AcquireUdpSocket( 
       
   544     MSocketUsagePermissionObserver* /*aObserver*/,
       
   545     const TInetAddr& /*aRemoteAddr*/,
       
   546     TBool& /*aPermissionToUse*/ )
       
   547     {
       
   548     return 0;
       
   549     }
       
   550 
       
   551 // -----------------------------------------------------------------------------
       
   552 // CTransport::UdpSocketReleased
       
   553 // -----------------------------------------------------------------------------
       
   554 //                                        
       
   555 void CTransport::UdpSocketReleased( 
       
   556     MSocketUsagePermissionObserver* /*aObserver*/,
       
   557     RSocket& /*aSocket*/ )
       
   558     {
       
   559     }
       
   560 
       
   561 // -----------------------------------------------------------------------------
       
   562 // CTransport::PersistentRemoteAddr
       
   563 // -----------------------------------------------------------------------------
       
   564 // 
       
   565 TInetAddr* CTransport::PersistentRemoteAddr( 
       
   566     MSIPNATBindingObserver* /*aBindingObserver*/ )
       
   567     {
       
   568     return 0;
       
   569     }
       
   570     
       
   571 // -----------------------------------------------------------------------------
       
   572 // CTransport::HandleClientRequestL
       
   573 // -----------------------------------------------------------------------------
       
   574 //
       
   575 void CTransport::HandleClientRequestL(
       
   576     const TSIPTransportParams& aParams,
       
   577     CSIPRequest& aRequest,
       
   578     TBool aPublicAddrResolved )
       
   579 	{
       
   580 	__ASSERT_DEBUG( aRequest.HasHeader(
       
   581 		SIPStrings::StringF( SipStrConsts::EMaxForwardsHeader ) ),
       
   582 		User::Panic( _L( "no MaxForwards header" ), KErrArgument ) );
       
   583 	
       
   584 	__ASSERT_DEBUG( AllMandatoryHeaders( aRequest ),
       
   585 		User::Panic( _L( "Mandatory header is missing" ), KErrArgument ) );
       
   586 		
       
   587     TUint32 transportId = aParams.TransportId();
       
   588 
       
   589    	CSIPViaHeader* viaHeader = TopViaHeader( &aRequest );
       
   590     if ( viaHeader )
       
   591     	{
       
   592     	// Currently both (aPublicAddrResolved==ETrue) and (receivePort>0)
       
   593     	// never happen at the same time.
       
   594     	if ( !aPublicAddrResolved )
       
   595     		{
       
   596     		TUint receivePort =
       
   597     			iSettingsList.SavedLocalReceivePort( transportId );
       
   598     		// If host is already filled (e.g. ConnectionMgr put public address
       
   599     		// to Via, sends request, gets 401, TU sends an updated request, Via
       
   600     		// has the public addr) don't put the private address to Via.
       
   601     		// Even if host is already set, set port if receivePort exists.
       
   602     		if ( viaHeader->SentByHostPort().Host().CompareF(
       
   603 			     SIPStrings::StringF( SipStrConsts::ELocalHost ).DesC() ) == 0 )
       
   604         		{
       
   605 		    	HBufC8* localaddress = LocalAddressL();
       
   606 		    	CleanupStack::PushL( localaddress );
       
   607 		    	viaHeader->SentByHostPort().SetHostL( *localaddress );
       
   608 				CleanupStack::PopAndDestroy( localaddress );
       
   609 
       
   610 				// Sent-by is now set for the first time, must set the port too
       
   611 				if ( receivePort == 0 )
       
   612 		            {
       
   613 		            receivePort = KDefaultSipPort;
       
   614 		            }
       
   615 	        	}
       
   616 	        if ( receivePort )
       
   617 	            {
       
   618 	            viaHeader->SentByHostPort().SetPort( receivePort );
       
   619 	            }
       
   620     		}
       
   621 
       
   622         // Add empty rport param
       
   623        	RStringF rport = SIPStrings::Pool().OpenFStringL( KParamrport );
       
   624         CleanupClosePushL( rport );
       
   625         viaHeader->SetParamL( rport );
       
   626         CleanupStack::PopAndDestroy(); // rport
       
   627         }
       
   628 
       
   629     UpdateContactHeadersL( aParams, &aRequest, !aPublicAddrResolved );
       
   630 	
       
   631 	// Check if request is sent integrity protected 
       
   632 	// (i.e. IPSec SA exists, ignore TLS)
       
   633 	iNetworkInfo.HandleRequestL( aRequest,
       
   634 	        iSettingsList.HasSavedTransportInfo( transportId ) &&
       
   635 	        !iSettingsList.HasSavedTLSTransportInfo( transportId ) );		
       
   636 	}
       
   637 
       
   638 // -----------------------------------------------------------------------------
       
   639 // CTransport::GetAddrFromResponseL
       
   640 // -----------------------------------------------------------------------------
       
   641 //
       
   642 void CTransport::GetAddrFromResponseL(
       
   643     const TSIPTransportParams& aParams,
       
   644     CSIPMessage& aMessage, 
       
   645     TInetAddr& aAddr )
       
   646 	{
       
   647 	HandleClientResponseL( aParams, &aMessage, aAddr );
       
   648 	}
       
   649 
       
   650 // -----------------------------------------------------------------------------
       
   651 // CTransport::HandleClientResponseL
       
   652 // -----------------------------------------------------------------------------
       
   653 //
       
   654 void CTransport::HandleClientResponseL(
       
   655     const TSIPTransportParams& aParams,
       
   656     CSIPMessage* aMessage, 
       
   657     TInetAddr& aAddr )
       
   658 	{	
       
   659 	CSIPViaHeader* viaHeader = TopViaHeader( aMessage );
       
   660 	if ( viaHeader )
       
   661 		{
       
   662 		TBool portSet( EFalse );
       
   663 		
       
   664 		if ( viaHeader->HasParam( SIPStrings::StringF( SipStrConsts::EMaddr ) ) )
       
   665 			{
       
   666 			ConvertToInetAddrL( 
       
   667 			    viaHeader->ParamValue(
       
   668 			        SIPStrings::StringF( SipStrConsts::EMaddr ) ).DesC(), aAddr );
       
   669 			
       
   670 			if ( !viaHeader->HasParam( 
       
   671 			        SIPStrings::StringF( SipStrConsts::ETtl ) ) )
       
   672 				{
       
   673 				viaHeader->SetTtlParamL(1);
       
   674 				}
       
   675 			}
       
   676 		else if ( viaHeader->HasParam(
       
   677 		    SIPStrings::StringF( SipStrConsts::EReceived ) ) )
       
   678 			{
       
   679 			ConvertToInetAddrL( 
       
   680 			    viaHeader->ParamValue(
       
   681 			        SIPStrings::StringF( SipStrConsts::EReceived ) ).DesC(),
       
   682 			        aAddr );
       
   683 			
       
   684 			portSet = HandleClientResponseRPortL( *viaHeader, aAddr );
       
   685 			}
       
   686 		else
       
   687 			{
       
   688 			ConvertToInetAddrL( viaHeader->SentByHostPort().Host(),
       
   689 			                    aAddr );
       
   690 			}
       
   691 	    
       
   692 	    // Port could be already set if received and rport values existed.
       
   693 	    if ( !portSet )
       
   694 	        {
       
   695     		if ( viaHeader->SentByHostPort().HasPort() )
       
   696     			{
       
   697     			aAddr.SetPort( viaHeader->SentByHostPort().Port() );
       
   698     			}
       
   699     		else
       
   700     			{
       
   701     			aAddr.SetPort( KDefaultSipPort );
       
   702     			}
       
   703 	        }
       
   704 		}
       
   705 		
       
   706 	UpdateContactHeadersL( aParams, aMessage, ETrue );
       
   707 	}
       
   708 
       
   709 // -----------------------------------------------------------------------------
       
   710 // CTransport::HandleServerResponseL
       
   711 // -----------------------------------------------------------------------------
       
   712 //
       
   713 TBool CTransport::HandleServerResponseL( CSIPMessage* aMessage,
       
   714 										 const TInetAddr& aAddr )
       
   715 	{
       
   716 	__ASSERT_DEBUG( aMessage, User::Panic( _L("Nullpointer"), KErrGeneral ) );
       
   717 	
       
   718 	if ( !CorrectProtocolInVia( *aMessage ) )
       
   719 		{
       
   720 		return EFalse;
       
   721 		}
       
   722 
       
   723 	if ( !OnlyOneViaHeader( *aMessage ) )
       
   724 		{
       
   725 		return EFalse;
       
   726 		}
       
   727 	if ( Protocol() == KProtocolInetUdp )
       
   728 		{
       
   729 		if (CheckAndUpdateContentLengthL( aMessage, aAddr ) != KErrNone )
       
   730 			{
       
   731 			return EFalse;
       
   732 			}
       
   733 		}
       
   734 	
       
   735 	if ( IsConnectedTransport() &&
       
   736 		 !aMessage->HasAnnouncedContentLength() )
       
   737 		{
       
   738 		return EFalse;
       
   739 		}
       
   740 
       
   741 	if ( !SupportedSIPVersion( *aMessage ) )
       
   742 		{
       
   743 		return EFalse;
       
   744 		}
       
   745 
       
   746 	return ETrue;
       
   747 	}
       
   748 
       
   749 // -----------------------------------------------------------------------------
       
   750 // CTransport::HandleServerRequestL
       
   751 // -----------------------------------------------------------------------------
       
   752 //
       
   753 TInt CTransport::HandleServerRequestL( CSIPMessage* aMessage,
       
   754 									   const TInetAddr& aAddr )
       
   755 	{
       
   756 	__ASSERT_ALWAYS( aMessage, User::Leave( KErrArgument ) );
       
   757 	
       
   758 	SetReceivedIfNeededL( TopViaHeader( aMessage ), aAddr );
       
   759 
       
   760 	if ( !SupportedSIPVersion( *aMessage ) || 
       
   761 	     !CorrectProtocolInVia( *aMessage ) )
       
   762 		{
       
   763 		SendErrorResponseL( KVersionError,
       
   764 			                SipStrConsts::EPhraseVersionNotSupported,
       
   765 					        *aMessage,
       
   766 					        aAddr );
       
   767 		return KErrArgument;
       
   768 		}
       
   769 
       
   770 	if ( ( IsConnectedTransport() && 
       
   771 	     !aMessage->HasAnnouncedContentLength() ) ||
       
   772 	     !ContentTypeOk( *aMessage ) ||
       
   773 	     !MethodIsSameInCSecAndReqLine( static_cast<CSIPRequest&>( *aMessage ) ) )
       
   774 		{
       
   775 		SendErrorResponseL( KBadRequest,
       
   776 					        SipStrConsts::EPhraseBadRequest,
       
   777 					        *aMessage,
       
   778 				          	aAddr );
       
   779 		return KErrArgument;
       
   780 		}
       
   781 		
       
   782 	if ( Protocol() == KProtocolInetUdp )
       
   783 		{
       
   784 		if ( CheckAndUpdateContentLengthL( aMessage, aAddr ) != KErrNone )
       
   785 			{
       
   786 			return KErrGeneral;
       
   787 			}
       
   788 		}
       
   789 
       
   790 	CSIPViaHeader* viaHeader = TopViaHeader( aMessage );
       
   791 	if ( viaHeader )
       
   792 	{
       
   793 		TBool isPortPresent = viaHeader->SentByHostPort().HasPort();
       
   794 		if (isPortPresent)
       
   795 		{
       
   796 			TUint sentByPort = viaHeader->SentByHostPort().Port();
       
   797 			if ((sentByPort > KMaxPortValue) || (sentByPort < KMinPortValue))
       
   798 			{
       
   799 		    	__SIP_LOG( "Topmost Via-header has invalid port value, dropping request" )
       
   800 		    	return KErrArgument;
       
   801 			}
       
   802 		}
       
   803 	}
       
   804 
       
   805 	return KErrNone;
       
   806 	}
       
   807 
       
   808 // -----------------------------------------------------------------------------
       
   809 // CTransport::AllMandatoryHeaders
       
   810 // -----------------------------------------------------------------------------
       
   811 //
       
   812 TBool CTransport::AllMandatoryHeaders( CSIPMessage& aMessage )
       
   813 	{
       
   814 	return aMessage.HasHeader( SIPStrings::StringF( SipStrConsts::EViaHeader ) )
       
   815 		&&
       
   816 		aMessage.HasHeader( SIPStrings::StringF( SipStrConsts::EToHeader ) )
       
   817 		&&
       
   818 		aMessage.HasHeader( SIPStrings::StringF( SipStrConsts::EFromHeader ) )
       
   819 		&&
       
   820 		aMessage.HasHeader( SIPStrings::StringF( SipStrConsts::ECallIDHeader ) )
       
   821 		&&
       
   822 		aMessage.HasHeader( SIPStrings::StringF( SipStrConsts::ECSeqHeader ) );
       
   823 	}
       
   824 
       
   825 // -----------------------------------------------------------------------------
       
   826 // CTransport::SupportedSIPVersion
       
   827 // -----------------------------------------------------------------------------
       
   828 //
       
   829 TBool CTransport::SupportedSIPVersion( CSIPMessage& aMessage )
       
   830 	{
       
   831 	TSglQueIter<CSIPHeaderBase> iter = 
       
   832 	    aMessage.Headers( SIPStrings::StringF( SipStrConsts::EViaHeader ) );
       
   833 	CSIPHeaderBase* header = 0;
       
   834 	iter.SetToFirst();
       
   835 	
       
   836 	while ( ( header = iter++ ) != 0 )
       
   837 		{
       
   838 		CSIPViaHeader* via = static_cast<CSIPViaHeader*>( header );
       
   839 		if ( !( via->SentProtocolVersion() ==
       
   840 		        SIPStrings::StringF( SipStrConsts::EDefaultVersionNumber ) ) )
       
   841 			{
       
   842 			return EFalse;
       
   843 			}
       
   844 		}
       
   845 
       
   846 	return ( aMessage.SIPVersion() == 
       
   847 	         SIPStrings::StringF( SipStrConsts::EDefaultProtocolVersion ) );
       
   848 	}
       
   849 
       
   850 // -----------------------------------------------------------------------------
       
   851 // CTransport::CorrectProtocolInVia
       
   852 // -----------------------------------------------------------------------------
       
   853 //
       
   854 TBool CTransport::CorrectProtocolInVia( CSIPMessage& aMessage )
       
   855 	{
       
   856 	TSglQueIter<CSIPHeaderBase> iter = 
       
   857 	    aMessage.Headers( SIPStrings::StringF( SipStrConsts::EViaHeader ) );
       
   858 	CSIPHeaderBase* header = 0;
       
   859 	iter.SetToFirst();
       
   860 	
       
   861 	while ( ( header = iter++ ) != 0 )
       
   862 		{
       
   863 		CSIPViaHeader* via = static_cast<CSIPViaHeader*>( header );
       
   864 		if ( via->SentProtocolName() !=
       
   865 			 SIPStrings::StringF( SipStrConsts::ESIP ) )
       
   866 			{
       
   867 			return EFalse;
       
   868 			}
       
   869 		}
       
   870 	
       
   871 	return ETrue;
       
   872 	}
       
   873 
       
   874 // -----------------------------------------------------------------------------
       
   875 // CTransport::ContentTypeOk
       
   876 // -----------------------------------------------------------------------------
       
   877 //
       
   878 TBool CTransport::ContentTypeOk( CSIPMessage& aMessage )
       
   879 	{
       
   880 	if ( aMessage.Content().Length() > 0 )
       
   881 		{
       
   882 		if ( !aMessage.HasHeader(
       
   883 		        SIPStrings::StringF( SipStrConsts::EContentTypeHeader ) ) )
       
   884 			{
       
   885 			return EFalse;
       
   886 			}
       
   887 		}
       
   888 	return ETrue;
       
   889 	}
       
   890 
       
   891 // -----------------------------------------------------------------------------
       
   892 // CTransport::SetReceivedIfNeededL
       
   893 // aAddr has to be passed by value
       
   894 // -----------------------------------------------------------------------------
       
   895 //
       
   896 void CTransport::SetReceivedIfNeededL( CSIPViaHeader* aViaHeader,
       
   897 									   TInetAddr aAddr )
       
   898 	{
       
   899 	if ( aViaHeader )
       
   900 		{
       
   901 		if ( aAddr.IsV4Mapped() )
       
   902 			{
       
   903 			aAddr.ConvertToV4();
       
   904 			}
       
   905 		aAddr.SetScope( 0 );
       
   906 		
       
   907 		const TInt KMaxAddrLen = 64;
       
   908 		TBuf<KMaxAddrLen> address;
       
   909 		aAddr.Output( address );
       
   910 		TBuf8<KMaxAddrLen> received;
       
   911 		CnvUtfConverter::ConvertFromUnicodeToUtf8( received, address );
       
   912 			            
       
   913 	    RStringF rport = SIPStrings::Pool().OpenFStringL( KParamrport );
       
   914 	    CleanupClosePushL( rport );
       
   915 	
       
   916 	    // If rport param exists but value has not been set, 
       
   917 	    // set it to be the source port
       
   918 	    TBool rportSet( EFalse );
       
   919 	    if ( aViaHeader->HasParam( rport ) && !HasValue( *aViaHeader, rport ) )
       
   920 	        {
       
   921 	        const TInt KMaxTUintAsDesLen = 10;
       
   922 	        TBuf8<KMaxTUintAsDesLen> sourcePortDes;
       
   923 	        sourcePortDes.AppendNum( static_cast<TInt64>( aAddr.Port() ) );
       
   924 	        
       
   925 	        RStringF rportVal = SIPStrings::Pool().OpenFStringL( sourcePortDes );
       
   926 	    	CleanupClosePushL( rportVal );
       
   927 	        aViaHeader->SetParamL( rport, rportVal );
       
   928 	        CleanupStack::PopAndDestroy(); // rportVal
       
   929 	        rportSet = ETrue;
       
   930 	        }
       
   931 	        
       
   932 	    CleanupStack::PopAndDestroy(); // rport
       
   933 	    
       
   934 	    // Set received param even if the address is same as in sent-by if
       
   935 	    // rport value was set   
       
   936 	    if ( aViaHeader->SentByHostPort().Host().CompareF( received ) != 0 ||
       
   937 	         rportSet )
       
   938 			{
       
   939 			RStringF recv = SIPStrings::Pool().OpenFStringL( received );
       
   940 			CleanupClosePushL( recv );
       
   941 			aViaHeader->SetParamL(
       
   942 			            SIPStrings::StringF(SipStrConsts::EReceived), recv );
       
   943 			CleanupStack::PopAndDestroy(); //recv
       
   944 			}
       
   945 		}
       
   946 	}
       
   947 
       
   948 // -----------------------------------------------------------------------------
       
   949 // CTransport::CheckAndUpdateContentLengthL
       
   950 // -----------------------------------------------------------------------------
       
   951 //
       
   952 TInt CTransport::CheckAndUpdateContentLengthL( CSIPMessage* aMessage,
       
   953 											   const TInetAddr& aAddr )
       
   954 	{
       
   955 	if ( aMessage->HasAnnouncedContentLength() )
       
   956 		{
       
   957 		if ( static_cast<TUint>( aMessage->Content().Length() ) == 
       
   958 			 aMessage->AnnouncedContentLength() )
       
   959 			{
       
   960 			return KErrNone;
       
   961 			}
       
   962 
       
   963 		if ( static_cast<TUint>( aMessage->Content().Length() ) > 
       
   964 			 aMessage->AnnouncedContentLength() )
       
   965 			{
       
   966 			HBufC8* content = aMessage->Content().AllocL();
       
   967 			content->Des().Delete( aMessage->AnnouncedContentLength(),
       
   968 								   aMessage->Content().Length() - 
       
   969 								   aMessage->AnnouncedContentLength() );
       
   970 
       
   971 			aMessage->SetContent( content );
       
   972 			return KErrNone;
       
   973 			}
       
   974 
       
   975 		if ( aMessage->IsRequest() )
       
   976 			{
       
   977 			SendErrorResponseL( KBadRequest, 
       
   978 			                    SipStrConsts::EPhraseBadRequest,
       
   979             			        *aMessage, 
       
   980             			        aAddr );
       
   981 			}
       
   982 		return KErrGeneral;
       
   983 		}
       
   984 	else
       
   985 		{
       
   986 		return KErrNone;
       
   987 		}
       
   988 	}
       
   989 
       
   990 // -----------------------------------------------------------------------------
       
   991 // CTransport::TopViaHeader
       
   992 // -----------------------------------------------------------------------------
       
   993 //
       
   994 CSIPViaHeader* CTransport::TopViaHeader( CSIPMessage* aMessage )
       
   995 	{
       
   996 	if ( aMessage->HasHeader( SIPStrings::StringF(SipStrConsts::EViaHeader) ) )
       
   997 		{
       
   998 		TSglQueIter<CSIPHeaderBase> iter =
       
   999 			aMessage->Headers( SIPStrings::StringF(SipStrConsts::EViaHeader) );
       
  1000 		CSIPHeaderBase* header = iter;
       
  1001 		return static_cast<CSIPViaHeader*>( header );
       
  1002 		}
       
  1003 
       
  1004 	return 0;
       
  1005 	}
       
  1006 
       
  1007 // -----------------------------------------------------------------------------
       
  1008 // CTransport::UpdateListenersL
       
  1009 // -----------------------------------------------------------------------------
       
  1010 //
       
  1011 void CTransport::UpdateListenersL(
       
  1012     const TSIPTransportParams& aParams, 
       
  1013     CSIPMessage* aMessage )
       
  1014 	{	
       
  1015 	if ( aMessage->IsRequest() )
       
  1016 		{
       
  1017 		if ( static_cast<CSIPRequest*>(aMessage)->Method() != 
       
  1018 		     SIPStrings::StringF(SipStrConsts::ERegister) )
       
  1019 			{
       
  1020 			return;
       
  1021 			}
       
  1022 		}
       
  1023 	if ( aMessage->HasHeader( 
       
  1024 	        SIPStrings::StringF(SipStrConsts::EContactHeader) ) )
       
  1025 		{
       
  1026 		TSglQueIter<CSIPHeaderBase> iter = 
       
  1027 		    aMessage->Headers( 
       
  1028 		        SIPStrings::StringF(SipStrConsts::EContactHeader) );
       
  1029 		CSIPHeaderBase* header = 0;
       
  1030 		CURIContainer* uriContainer = 0;
       
  1031 		while ( ( header = iter++ ) != 0 )
       
  1032 			{
       
  1033 			CSIPContactHeader* contact =
       
  1034 				static_cast<CSIPContactHeader*>( header );
       
  1035 				
       
  1036 		    CSIPAddress* sipAddr = contact->SIPAddress();
       
  1037 			if ( sipAddr )
       
  1038 			    {
       
  1039 			    uriContainer = &sipAddr->URI();
       
  1040 			
       
  1041     			if ( uriContainer->IsSIPURI() )
       
  1042     				{
       
  1043     				CSIPURI* sipUri = uriContainer->SIPURI();
       
  1044     				HBufC8* localaddress = LocalAddressL();
       
  1045     				CleanupStack::PushL( localaddress );
       
  1046     				TUint port = sipUri->HostPort().Port();
       
  1047     				
       
  1048     				if ( sipUri->HostPort().Host().CompareF( *localaddress ) == 0 &&
       
  1049     				     sipUri->HostPort().HasPort() )
       
  1050     					{
       
  1051     					if ( sipUri->HasParam(
       
  1052     					     SIPStrings::StringF(SipStrConsts::ETransport) ) )
       
  1053     					    {
       
  1054     					    RStringF transport = 
       
  1055     					        sipUri->ParamValue(
       
  1056     					            SIPStrings::StringF(SipStrConsts::ETransport) );
       
  1057     					         
       
  1058     					    if ( transport == SIPStrings::StringF(SipStrConsts::ETCP) )
       
  1059     					        {
       
  1060     				            iSettingsList.ReservePrivatePortL( aParams, port );
       
  1061     					        iTransportOwner->AddListenerL( aParams,
       
  1062     					                                       KProtocolInetTcp, 
       
  1063     					                                       port );
       
  1064     					        CleanupStack::PopAndDestroy( localaddress );
       
  1065     					        return;
       
  1066     					        }
       
  1067     					    
       
  1068     					    if ( transport == SIPStrings::StringF(SipStrConsts::ETLS) )
       
  1069     					        {
       
  1070     					        // No support for incoming TLS connections
       
  1071     					        CleanupStack::PopAndDestroy( localaddress );
       
  1072     					        return;
       
  1073     					        }
       
  1074     					    }
       
  1075     					    
       
  1076     				    iSettingsList.ReservePrivatePortL( aParams, port );     
       
  1077     				    iTransportOwner->AddListenerL( aParams,
       
  1078     				                                   KProtocolInetUdp, 
       
  1079     				                                   port );	
       
  1080     					}
       
  1081     				CleanupStack::PopAndDestroy( localaddress );
       
  1082     				}
       
  1083 			    }
       
  1084 			}
       
  1085 		}
       
  1086 	}
       
  1087 
       
  1088 // -----------------------------------------------------------------------------
       
  1089 // CTransport::OnlyOneViaHeader
       
  1090 // -----------------------------------------------------------------------------
       
  1091 //
       
  1092 TBool CTransport::OnlyOneViaHeader( CSIPMessage& aMessage )
       
  1093 	{
       
  1094 	return aMessage.HeaderCount(
       
  1095 	                    SIPStrings::StringF(SipStrConsts::EViaHeader) ) == 1;	
       
  1096 	}
       
  1097 
       
  1098 // -----------------------------------------------------------------------------
       
  1099 // CTransport::MethodIsSameInCSecAndReqLine
       
  1100 // -----------------------------------------------------------------------------
       
  1101 //
       
  1102 TBool CTransport::MethodIsSameInCSecAndReqLine( CSIPRequest& aMessage )
       
  1103 	{
       
  1104 	if ( aMessage.HasHeader( SIPStrings::StringF(SipStrConsts::ECSeqHeader) ) )
       
  1105 		{
       
  1106 		TSglQueIter<CSIPHeaderBase> iter =
       
  1107 			aMessage.Headers(SIPStrings::StringF(SipStrConsts::ECSeqHeader) );
       
  1108 		CSIPHeaderBase* header = iter;
       
  1109 		CSIPCSeqHeader* cseq = static_cast<CSIPCSeqHeader*>( header );
       
  1110 		if ( cseq->Method() == aMessage.Method() )
       
  1111 			{
       
  1112 			return ETrue;
       
  1113 			}
       
  1114 		}
       
  1115 	return EFalse;
       
  1116 	}
       
  1117 
       
  1118 // -----------------------------------------------------------------------------
       
  1119 // CTransport::SetPersistencyL
       
  1120 // -----------------------------------------------------------------------------
       
  1121 //	
       
  1122 void CTransport::SetPersistencyL( 
       
  1123     const TInetAddr& /*aRemoteAddr*/, 
       
  1124     TBool aIsPersistent,
       
  1125     MSIPNATBindingObserver* aBindingObserver )
       
  1126     {
       
  1127     if ( !aBindingObserver )
       
  1128         {
       
  1129         return;
       
  1130         }
       
  1131         
       
  1132     if ( aIsPersistent )
       
  1133         {
       
  1134         AddBindingObserverL( *aBindingObserver );
       
  1135         }
       
  1136     else
       
  1137         {
       
  1138         RemoveBindingObserver( *aBindingObserver );
       
  1139         }
       
  1140     }
       
  1141 
       
  1142 // -----------------------------------------------------------------------------
       
  1143 // CTransport::IsPersistent
       
  1144 // -----------------------------------------------------------------------------
       
  1145 //
       
  1146 TBool CTransport::IsPersistent() const
       
  1147     {
       
  1148     return ( iBindingObservers.Count() > 0 );
       
  1149     }
       
  1150 
       
  1151 // -----------------------------------------------------------------------------
       
  1152 // CTransport::IsDefault
       
  1153 // -----------------------------------------------------------------------------
       
  1154 //
       
  1155 TBool CTransport::IsDefault() const
       
  1156     {
       
  1157     return ( iTransportParams.OwnerId() == KDefaultOwnerId );
       
  1158     }
       
  1159 
       
  1160 // -----------------------------------------------------------------------------
       
  1161 // CTransport::RemoveResponseRoute
       
  1162 // -----------------------------------------------------------------------------
       
  1163 //
       
  1164 void CTransport::RemoveResponseRoute( const TInetAddr& aRemoteAddr )
       
  1165 	{
       
  1166 	TInt pos = iIDArray.Count();
       
  1167 	while ( pos > 0 )
       
  1168 		{
       
  1169 		if ( iIDArray[ pos - 1 ].Address().CmpAddr( aRemoteAddr ) )
       
  1170 			{
       
  1171 			iIDArray.Remove( pos - 1 );
       
  1172 			}
       
  1173 		pos--;
       
  1174 		}
       
  1175 	}
       
  1176 	
       
  1177 // -----------------------------------------------------------------------------
       
  1178 // CTransport::RemoveResponseRoute
       
  1179 // -----------------------------------------------------------------------------
       
  1180 //
       
  1181 void CTransport::RemoveResponseRoute( TTransactionId aId )
       
  1182 	{
       
  1183 	TInt pos = iIDArray.Count();
       
  1184 	while ( pos > 0 )
       
  1185 		{
       
  1186 		if ( iIDArray[ pos - 1 ].TAId() == aId )
       
  1187 			{
       
  1188 			iIDArray.Remove( pos - 1 );
       
  1189 			}
       
  1190 		pos--;
       
  1191 		}
       
  1192 	iIDArray.Compress();
       
  1193 	}
       
  1194 
       
  1195 // -----------------------------------------------------------------------------
       
  1196 // CTransport::SendToNetL
       
  1197 // -----------------------------------------------------------------------------
       
  1198 //
       
  1199 void CTransport::SendToNetL( const TSIPTransportParams& /*aParams*/,
       
  1200                              const TInetAddr& /*aAddress*/,
       
  1201 							 CSIPMessage& /*aMessage*/, 
       
  1202 							 TBool /*aForceUDP*/,
       
  1203 							 TUint /*aOrigTransport*/,
       
  1204 							 TRequestStatus& /*aStatus*/ )
       
  1205 	{	
       
  1206 	__ASSERT_DEBUG(EFalse,
       
  1207 		User::Panic(_L("CTransport::SendToNetL is called"),
       
  1208 		KErrGeneral));
       
  1209 	}
       
  1210 
       
  1211 // -----------------------------------------------------------------------------
       
  1212 // CTransport::SendToNetL
       
  1213 // -----------------------------------------------------------------------------
       
  1214 //
       
  1215 void CTransport::SendToNetL( const TSIPTransportParams& /*aParams*/,
       
  1216                              const TInetAddr& /*aAddress*/,
       
  1217 							 TTransactionId /*aId*/, 
       
  1218 							 CSIPMessage& /*aMessage*/,
       
  1219 						 	 TRequestStatus& /*aStatus*/ )
       
  1220 	{
       
  1221 	__ASSERT_DEBUG(EFalse,
       
  1222 		User::Panic(_L("CTransport::SendToNetL is called"),
       
  1223 		KErrGeneral));
       
  1224 	}
       
  1225 
       
  1226 // -----------------------------------------------------------------------------
       
  1227 // CTransport::SendToNetL
       
  1228 // -----------------------------------------------------------------------------
       
  1229 //
       
  1230 void CTransport::SendToNetL( const TSIPTransportParams& /*aParams*/,
       
  1231                              const TInetAddr& /*aAddress*/,
       
  1232 					   		 CSIPMessage& /*aMessage*/,
       
  1233 					   		 TRequestStatus& /*aStatus*/ )
       
  1234 	{
       
  1235 	}
       
  1236 
       
  1237 // -----------------------------------------------------------------------------
       
  1238 // CTransport::IsAck
       
  1239 // -----------------------------------------------------------------------------
       
  1240 //
       
  1241 TBool CTransport::IsAck( CSIPMessage& aMessage )
       
  1242 	{
       
  1243 	if ( aMessage.IsRequest() )
       
  1244 		{
       
  1245 		if ( static_cast<CSIPRequest*>( &aMessage )->Method() == 
       
  1246 		     SIPStrings::StringF(SipStrConsts::EAck) )
       
  1247 			{
       
  1248 			return ETrue;
       
  1249 			}
       
  1250 		}
       
  1251 	return EFalse;
       
  1252 	}
       
  1253 
       
  1254 // -----------------------------------------------------------------------------
       
  1255 // CTransport::HandleSigCompAllowDenyL
       
  1256 // -----------------------------------------------------------------------------
       
  1257 //	
       
  1258 void CTransport::HandleSigCompAllowDenyL(
       
  1259     const TInetAddr& aRemoteAddr, 
       
  1260     TInt aParserError,
       
  1261     TBool aCompressed )
       
  1262     {
       
  1263     if ( !iSigCompHandler->IsSupported() || !aCompressed )
       
  1264         {
       
  1265         return;
       
  1266         }
       
  1267         
       
  1268 	if ( aParserError == KErrNone )
       
  1269 	    {
       
  1270 	    iSigCompHandler->AllowL( aRemoteAddr, 
       
  1271 	                             iTransportOwner->IapId() );
       
  1272 	    }
       
  1273 	else
       
  1274 	    {
       
  1275 	    iSigCompHandler->Deny();
       
  1276 	    }
       
  1277     }
       
  1278 
       
  1279 // -----------------------------------------------------------------------------
       
  1280 // CTransport::CancelResponseSend
       
  1281 // -----------------------------------------------------------------------------
       
  1282 //
       
  1283 TBool CTransport::CancelResponseSend( 
       
  1284     TTransactionId aId, 
       
  1285     TBool aCancelAlso2xxResponses )
       
  1286 	{
       
  1287 	// Remove response route information only after all responses related
       
  1288 	// to the transaction are canceled.
       
  1289 	if ( aCancelAlso2xxResponses )
       
  1290 	    {
       
  1291 	    RemoveResponseRoute( aId );
       
  1292 	    }
       
  1293 	
       
  1294 	return EFalse;
       
  1295 	}
       
  1296 
       
  1297 // -----------------------------------------------------------------------------
       
  1298 // CTransport::ProtocolType
       
  1299 // -----------------------------------------------------------------------------
       
  1300 //
       
  1301 TUint CTransport::ProtocolType()
       
  1302 	{
       
  1303 	return Protocol();
       
  1304 	}
       
  1305 
       
  1306 // -----------------------------------------------------------------------------
       
  1307 // CTransport::LocalAddressL
       
  1308 // -----------------------------------------------------------------------------
       
  1309 //
       
  1310 HBufC8* CTransport::LocalAddressL()
       
  1311 	{
       
  1312 	TInetAddr address;
       
  1313 	iTransportOwner->GetLocalAddrL( address, NULL );
       
  1314     return ConvertInetAddrToTextL( address );
       
  1315 	}
       
  1316     
       
  1317 // -----------------------------------------------------------------------------
       
  1318 // CTransport::HandleMixedAddressFamilysL
       
  1319 // -----------------------------------------------------------------------------
       
  1320 // 
       
  1321 void CTransport::HandleMixedAddressFamilysL( 
       
  1322     CSIPMessage& aMessage, 
       
  1323 	const TInetAddr& aRemoteAddr )
       
  1324     {
       
  1325     // Possibly update contact header if message is request
       
  1326     if ( aMessage.IsRequest() )
       
  1327         {
       
  1328         if ( aMessage.HasHeader( 
       
  1329                         SIPStrings::StringF(SipStrConsts::EContactHeader) ) )
       
  1330     		{
       
  1331             TSglQueIter<CSIPHeaderBase> iter = 
       
  1332                 aMessage.Headers( 
       
  1333                             SIPStrings::StringF(SipStrConsts::EContactHeader) );
       
  1334     		CSIPHeaderBase* header = 0;
       
  1335     		while ( ( header = iter++ ) != 0 )
       
  1336     			{
       
  1337     			CSIPContactHeader* contact = 
       
  1338     			        static_cast<CSIPContactHeader*>( header );
       
  1339     			CSIPAddress* sipAddr = contact->SIPAddress();
       
  1340     			
       
  1341     			if ( sipAddr )
       
  1342     			    {
       
  1343     			    CURIContainer& uriContainer = sipAddr->URI();
       
  1344     			    if ( uriContainer.IsSIPURI() )
       
  1345     			        {
       
  1346     			        ChangeHostAddressFamilyIfNeededL( 
       
  1347     			                uriContainer.SIPURI()->HostPort(), 
       
  1348     			                aRemoteAddr );
       
  1349     			        }
       
  1350     			    }
       
  1351     			}
       
  1352     		}
       
  1353         }
       
  1354         
       
  1355     // Possibly update via header (also if message is response)
       
  1356     CSIPViaHeader* viaHeader = TopViaHeader( &aMessage );
       
  1357     if ( viaHeader )
       
  1358         {
       
  1359         ChangeHostAddressFamilyIfNeededL( viaHeader->SentByHostPort(), 
       
  1360                                           aRemoteAddr );
       
  1361         }
       
  1362     }
       
  1363 
       
  1364 // -----------------------------------------------------------------------------
       
  1365 // CTransport::IsConnectedTransport
       
  1366 // -----------------------------------------------------------------------------
       
  1367 //
       
  1368 TBool CTransport::IsConnectedTransport()
       
  1369     {
       
  1370     TUint protocol( Protocol() );
       
  1371     return ( protocol == KProtocolInetTcp || protocol == KProtocolTls );
       
  1372     }
       
  1373 
       
  1374 // -----------------------------------------------------------------------------
       
  1375 // CTransport::NotifyFlowFailure
       
  1376 // -----------------------------------------------------------------------------
       
  1377 //   
       
  1378 TBool CTransport::NotifyFlowFailure()
       
  1379     {
       
  1380     // NOTE: Notification leads to synchronous removal of the bindingobserver
       
  1381     // from the array and the whole transport is removed when all observers
       
  1382     // has been removed.
       
  1383     
       
  1384     TInt observerCount( iBindingObservers.Count() );
       
  1385     TInt lastIndex( observerCount - 1 );
       
  1386     for ( TInt i = lastIndex; i >= 0; i-- )
       
  1387         {
       
  1388         iBindingObservers[ i ]->FlowFailure( KErrSIPTransportFailure );
       
  1389         }
       
  1390         
       
  1391     return ( observerCount > 0 );
       
  1392     }
       
  1393     
       
  1394 // -----------------------------------------------------------------------------
       
  1395 // CTransport::SendErrorResponseL
       
  1396 // -----------------------------------------------------------------------------
       
  1397 //  
       
  1398 void CTransport::SendErrorResponseL( 
       
  1399 	TUint aResponseCode, 
       
  1400 	TInt aStrIndex, 
       
  1401 	CSIPMessage& aMessage, 
       
  1402 	const TInetAddr& aAddr )
       
  1403     {
       
  1404     if ( !IsAck( aMessage ) )
       
  1405 		{			
       
  1406 		ErrorHandler().SendErrorResponseL( 
       
  1407 		    iTransportParams,
       
  1408 		    aResponseCode,
       
  1409 	        SIPStrings::StringF( aStrIndex ),
       
  1410 			aMessage,
       
  1411 			aAddr );
       
  1412 		}
       
  1413     }
       
  1414   
       
  1415 // -----------------------------------------------------------------------------
       
  1416 // CTransport::UpdateContactHeadersL
       
  1417 // -----------------------------------------------------------------------------
       
  1418 //  
       
  1419 void CTransport::UpdateContactHeadersL( 
       
  1420     const TSIPTransportParams& aParams, 
       
  1421     CSIPMessage* aMessage,
       
  1422     TBool aUpdatePorts )
       
  1423     {
       
  1424     if ( !aMessage )
       
  1425         {
       
  1426         return;
       
  1427         }
       
  1428         
       
  1429     TSglQueIter<CSIPHeaderBase> iter = 
       
  1430         aMessage->Headers( SIPStrings::StringF(SipStrConsts::EContactHeader) );
       
  1431     CSIPHeaderBase* header = NULL;
       
  1432     while ( ( header = iter++ ) != NULL )
       
  1433     	{
       
  1434     	CSIPContactHeader* contact = static_cast<CSIPContactHeader*>( header );
       
  1435         CSIPAddress* sipAddr = contact->SIPAddress();
       
  1436 			
       
  1437         if ( sipAddr )
       
  1438             {
       
  1439             CURIContainer& uri = sipAddr->URI();
       
  1440             if ( uri.IsSIPURI() )
       
  1441                 {
       
  1442                 TUint receivePort = 
       
  1443                     iSettingsList.SavedLocalReceivePort( aParams.TransportId() );
       
  1444             
       
  1445                 if ( aUpdatePorts && receivePort > 0 )
       
  1446                     {
       
  1447                     uri.SIPURI()->HostPort().SetPort( receivePort );
       
  1448                     }
       
  1449                 
       
  1450                 RStringF transportParam =
       
  1451                     uri.SIPURI()->ParamValue(
       
  1452                         SIPStrings::StringF( SipStrConsts::ETransport ) );
       
  1453 
       
  1454                 if ( Protocol() == KProtocolTls )
       
  1455                     {
       
  1456                     RStringF tls = SIPStrings::StringF( SipStrConsts::ETLS );
       
  1457                     // SIP-URI with transport=TLS must not use sips scheme
       
  1458                     uri.SIPURI()->SetSIPS( transportParam != tls );
       
  1459                     if(transportParam == tls)
       
  1460                         {
       
  1461                         uri.SIPURI()->SetSIPS(EFalse);
       
  1462                         //Delete the param transport=tls from the URI as it is deprecated in RFC 3261
       
  1463                         uri.SIPURI()->DeleteParam(SIPStrings::StringF( SipStrConsts::ETransport ));
       
  1464                         }
       
  1465                     }
       
  1466                 else
       
  1467                     {
       
  1468                     uri.SIPURI()->SetSIPS( EFalse );
       
  1469                     }
       
  1470 			    }
       
  1471 			}
       
  1472 		}    
       
  1473         
       
  1474     }
       
  1475 
       
  1476 // -----------------------------------------------------------------------------
       
  1477 // CTransport::ChangeHostAddressFamilyIfNeededL
       
  1478 // -----------------------------------------------------------------------------
       
  1479 //     
       
  1480 void CTransport::ChangeHostAddressFamilyIfNeededL( 
       
  1481     CSIPHostPort& aHostPort, 
       
  1482     const TInetAddr& aRemoteAddr )
       
  1483     {
       
  1484     if ( aHostPort.HostType() == CSIPHostPort::ESIPHostName ||
       
  1485          aHostPort.HostType() == CSIPHostPort::ESIPNoHost )
       
  1486         {
       
  1487         return;
       
  1488         }
       
  1489         
       
  1490     TInetAddr hostInetAddr;
       
  1491     ConvertToInetAddrL( aHostPort.Host(), hostInetAddr );
       
  1492     
       
  1493     if ( iTransportOwner->IsLocalAddr( hostInetAddr ) )
       
  1494         {
       
  1495         // Fills hostInetAddr based on the address family of aRemoteAddr.
       
  1496         // If aRemoteAddr is IPv6, then hostInetAddr is set to IPv6.
       
  1497         // If aRemoteAddr is IPv4, then hostInetAddr is set to IPv4 if possible.
       
  1498         iTransportOwner->FillWithMatchingAddrFamily( 
       
  1499             hostInetAddr, &aRemoteAddr );
       
  1500         }
       
  1501     else
       
  1502         {
       
  1503         TBool isRemoteIPv6Addr( aRemoteAddr.Address() == 0 ||
       
  1504                                 aRemoteAddr.IsV4Compat() );
       
  1505         
       
  1506         if ( isRemoteIPv6Addr && aHostPort.HostType() == CSIPHostPort::ESIPIpv4 )
       
  1507             {
       
  1508              // Update host if remote address is IPv6 and host address is IPv4
       
  1509             hostInetAddr.ConvertToV4Compat();
       
  1510             }
       
  1511         else if ( !isRemoteIPv6Addr && 
       
  1512                 ( hostInetAddr.IsV4Compat() || hostInetAddr.IsV4Mapped() ) )
       
  1513             {
       
  1514             // Update host if remote address is IPv4 address and host is
       
  1515             // IPv6 address which can be converted to V4
       
  1516             hostInetAddr.ConvertToV4();
       
  1517             }
       
  1518         else
       
  1519             {
       
  1520             // Otherwise no actions taken
       
  1521             return;
       
  1522             }
       
  1523         }
       
  1524         
       
  1525     HBufC8* hostAddr = ConvertInetAddrToTextL( hostInetAddr );
       
  1526     CleanupStack::PushL( hostAddr );
       
  1527     aHostPort.SetHostL( *hostAddr );
       
  1528     CleanupStack::PopAndDestroy( hostAddr );
       
  1529     }
       
  1530  
       
  1531 // -----------------------------------------------------------------------------
       
  1532 // CTransport::HandleClientResponseRPortL
       
  1533 // -----------------------------------------------------------------------------
       
  1534 // 
       
  1535  TBool CTransport::HandleClientResponseRPortL( 
       
  1536     CSIPViaHeader& aViaHeader, 
       
  1537     TInetAddr& aAddr )
       
  1538     {
       
  1539     if ( aViaHeader.Transport() != SIPStrings::StringF( SipStrConsts::EUDP ) )
       
  1540         {
       
  1541         return EFalse;
       
  1542         }
       
  1543     
       
  1544     TBool portSet( EFalse ); 
       
  1545     RStringF rport = SIPStrings::Pool().OpenFStringL( KParamrport );
       
  1546 	CleanupClosePushL( rport );
       
  1547 	
       
  1548 	if ( HasValue( aViaHeader, rport ) )
       
  1549 	    {
       
  1550 	    TLex8 lexer( aViaHeader.ParamValue( rport ).DesC() );
       
  1551     	TInt rportVal( 0 );
       
  1552     	User::LeaveIfError( lexer.Val( rportVal ) );
       
  1553     	aAddr.SetPort( rportVal );
       
  1554     	portSet = ETrue;
       
  1555 	    }
       
  1556 	    
       
  1557     CleanupStack::PopAndDestroy(); // rport
       
  1558     
       
  1559     return portSet;
       
  1560     }
       
  1561 
       
  1562 // -----------------------------------------------------------------------------
       
  1563 // CTransport::HandleResponseNATTraversalL
       
  1564 // -----------------------------------------------------------------------------
       
  1565 //    
       
  1566 void CTransport::HandleResponseNATTraversalL( 
       
  1567     CSIPResponse& aResponse, 
       
  1568     const TInetAddr& aRemoteAddr,
       
  1569     MSIPNATBindingObserver* aBindingObserver )
       
  1570     {
       
  1571     TBool persistent( EFalse );
       
  1572     CSIPCSeqHeader* cseq = aResponse.CSeq();
       
  1573     if ( aResponse.Type() == CSIPResponse::E2XX && 
       
  1574          cseq && 
       
  1575          cseq->Method() == SIPStrings::StringF( SipStrConsts::ERegister ) )
       
  1576         {
       
  1577         CSocketContainer& container = GetSocketContainerL( aRemoteAddr );
       
  1578     
       
  1579         if ( container.HasSecureSocket() )
       
  1580             {
       
  1581             persistent = iNATTraversal.RefreshNATBindingL( 
       
  1582                 *container.SecureSocket(),
       
  1583                 aBindingObserver );
       
  1584             }
       
  1585         else
       
  1586             {
       
  1587             persistent = iNATTraversal.RefreshNATBindingL(  
       
  1588                 container.Socket(), 
       
  1589                 aBindingObserver );
       
  1590             }
       
  1591         SetPersistencyL( aRemoteAddr, persistent, aBindingObserver );
       
  1592         }
       
  1593     InformSendingStatus( aRemoteAddr );
       
  1594     }
       
  1595 
       
  1596 // -----------------------------------------------------------------------------
       
  1597 // CTransport::HasValue
       
  1598 // -----------------------------------------------------------------------------
       
  1599 //   
       
  1600 TBool CTransport::HasValue( CSIPViaHeader& aViaHeader, RStringF& aParam )
       
  1601     {
       
  1602     TBool hasVal( EFalse );
       
  1603 	if ( aViaHeader.HasParam( aParam ) )
       
  1604 	    {
       
  1605 		hasVal = aViaHeader.ParamValue( aParam ).DesC().Length() > 0;
       
  1606 	    }
       
  1607 	return hasVal;
       
  1608     }
       
  1609 
       
  1610 // -----------------------------------------------------------------------------
       
  1611 // CTransport::AddBindingObserverL
       
  1612 // -----------------------------------------------------------------------------
       
  1613 //     
       
  1614 void CTransport::AddBindingObserverL( MSIPNATBindingObserver& aBindingObserver )
       
  1615     {
       
  1616     // Don't mind if the observer already exists.
       
  1617     TInt err = iBindingObservers.InsertInAddressOrder( &aBindingObserver );
       
  1618     if ( err && err != KErrAlreadyExists )
       
  1619         {
       
  1620         User::Leave( err );
       
  1621         }
       
  1622     }
       
  1623 
       
  1624 // -----------------------------------------------------------------------------
       
  1625 // CTransport::RemoveBindingObserver
       
  1626 // -----------------------------------------------------------------------------
       
  1627 //     
       
  1628 TBool CTransport::RemoveBindingObserver( 
       
  1629     MSIPNATBindingObserver& aBindingObserver )
       
  1630     {
       
  1631     TInt index = iBindingObservers.FindInAddressOrder( &aBindingObserver );
       
  1632     TBool found( index >= 0 && index < iBindingObservers.Count() );
       
  1633     if ( found )
       
  1634         {
       
  1635         iBindingObservers.Remove( index );
       
  1636         iBindingObservers.Compress();
       
  1637         }
       
  1638     
       
  1639     // Allow removal of whole transport if no more observers exist.
       
  1640     // Reserved transports are removed with different mechanism.
       
  1641     return ( found && !IsPersistent() && !IsReservedTransport() );
       
  1642     }
       
  1643     
       
  1644 // -----------------------------------------------------------------------------
       
  1645 // CTransport::ConvertToInetAddrL
       
  1646 // -----------------------------------------------------------------------------
       
  1647 //     
       
  1648 void CTransport::ConvertToInetAddrL( 
       
  1649     const TDesC8& aAddrStr, 
       
  1650     TInetAddr& aAddr )
       
  1651     {	                        
       
  1652 	HBufC* tempInputAddr = HBufC::NewLC( aAddrStr.Length() );
       
  1653 	TPtr ptempInputAddr( tempInputAddr->Des() );
       
  1654 	ptempInputAddr.Copy( aAddrStr );
       
  1655 
       
  1656 	User::LeaveIfError( aAddr.Input( ptempInputAddr ) );
       
  1657 	
       
  1658 	CleanupStack::PopAndDestroy( tempInputAddr );
       
  1659     }
       
  1660     
       
  1661 // -----------------------------------------------------------------------------
       
  1662 // CTransport::ConvertInetAddrToTextL
       
  1663 // -----------------------------------------------------------------------------
       
  1664 //        
       
  1665 HBufC8* CTransport::ConvertInetAddrToTextL( const TInetAddr& aAddr )
       
  1666     {
       
  1667     const TInt KMaxIPAddrLen = 256;
       
  1668     HBufC* addressOut = HBufC::NewLC( KMaxIPAddrLen );
       
  1669 	TPtr outputPtr( addressOut->Des() );
       
  1670 	aAddr.Output( outputPtr );
       
  1671 	
       
  1672 	HBufC8* addressResult = HBufC8::NewL( addressOut->Length() );
       
  1673 	TPtr8 resultPtr( addressResult->Des() );
       
  1674 	CnvUtfConverter::ConvertFromUnicodeToUtf8( resultPtr, *addressOut );
       
  1675 	CleanupStack::PopAndDestroy( addressOut );
       
  1676 
       
  1677 	return addressResult;
       
  1678     }
       
  1679 
       
  1680 // End of File