realtimenetprots/sipfw/SIP/ServerResolver/src/CSIPServerResolver.cpp
changeset 0 307788aac0a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/realtimenetprots/sipfw/SIP/ServerResolver/src/CSIPServerResolver.cpp	Tue Feb 02 01:03:15 2010 +0200
@@ -0,0 +1,356 @@
+// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Name          : CSIPServerResolver.cpp
+// Part of       : ServerResolver
+// Version       : SIP/4.0 
+//
+
+
+
+#include <uriutils.h>
+#include "CSIPServerResolver.h"
+#include "CSIPHostResolver.h"
+#include "CServerQuery.h"
+#include "sipuri.h"
+#include "uricontainer.h"
+#include "siphostport.h"
+#include "sipviaheader.h"
+
+#include "MSIPResolvingResult.h"
+#include "CSIPNaptrOrigDomain.h"
+#include "CSIPSRVOrigDomain.h"
+#include "CSIPQuerySrv.h"
+#include "MSIPHostResolver.h"
+
+#include "CSIPQueryA_AAAA.h"
+#include "CSIPA_AAAAOrigDomain.h"
+#include "CSIPQueryData.h"
+#include "sipstrings.h"
+#include "sipstrconsts.h"
+#include "siperr.h"
+
+// ----------------------------------------------------------------------------
+// CSIPServerResolver::NewL
+// ----------------------------------------------------------------------------
+//
+CSIPServerResolver* CSIPServerResolver::NewL( RSocketServ& aServer, 
+                                              RConnection& aConnection )
+	{
+	CSIPServerResolver* self = NewLC( aServer, aConnection );
+	CleanupStack::Pop( self );
+	return self;	
+	}
+
+// ----------------------------------------------------------------------------
+// CSIPServerResolver::NewLC
+// ----------------------------------------------------------------------------
+//
+CSIPServerResolver* CSIPServerResolver::NewLC( RSocketServ& aServer, 
+                                               RConnection& aConnection )
+	{
+	CSIPServerResolver* self = new ( ELeave ) CSIPServerResolver();
+	CleanupStack::PushL( self );
+	self->ConstructL( aServer, aConnection );
+	return self;	
+	}
+
+// ----------------------------------------------------------------------------
+// CSIPServerResolver::CSIPServerResolver
+// ----------------------------------------------------------------------------
+//
+CSIPServerResolver::CSIPServerResolver()
+	{
+	}
+
+// ----------------------------------------------------------------------------
+// CSIPServerResolver::ConstructL
+// ----------------------------------------------------------------------------
+//
+void CSIPServerResolver::ConstructL( RSocketServ& aServer, 
+                                     RConnection& aConnection )
+	{
+	iResolver = CSIPHostResolver::NewL( aServer, aConnection );
+	}
+
+// ----------------------------------------------------------------------------
+// CSIPServerResolver::~CSIPServerResolver
+// ----------------------------------------------------------------------------
+//
+CSIPServerResolver::~CSIPServerResolver()
+	{
+	delete iResolver;
+	}
+
+// ----------------------------------------------------------------------------
+// CSIPServerResolver::GetByURIL
+// ----------------------------------------------------------------------------
+//
+void CSIPServerResolver::GetByURIL( 
+    const CURIContainer& aURI,
+    TBool aSkipNaptrAndSrvQueries,
+    RPointerArray< MSIPResolvingResult >& aResult, 
+    MSIPServerResolverObserver* aObserver )
+	{
+	__ASSERT_ALWAYS( aURI.IsSIPURI(), User::Leave( KErrSIPInvalidURIType ) );
+	
+	const CSIPURI& uri = *(aURI.SIPURI());
+	
+	TBool forceUDP( EFalse );
+	RStringF protocol = TransportProtocolL( uri, forceUDP );  
+
+	TUint port( uri.HostPort().Port() );
+		
+	HBufC8* host = NULL;
+	if ( uri.HasParam( SIPStrings::StringF( SipStrConsts::EMaddr ) ) )
+		{
+		host = uri.ParamValue( 
+		    SIPStrings::StringF( SipStrConsts::EMaddr ) ).DesC().AllocL();
+		}
+	else
+		{
+		host = uri.HostPort().Host().AllocL();
+		}
+    CleanupStack::PushL( host );
+			
+	if ( !( UriUtils::HostType( *host ) == UriUtils::ETextHost ) && port == 0 )		
+		{
+		// The host is an IP address and there is no explicit port is in the URI
+		TBool useTls = 
+		    ( protocol == SIPStrings::StringF( SipStrConsts::ETLS ) );
+		port = DefaultPort( useTls );
+		}
+	
+	if ( ( UriUtils::HostType( *host ) == UriUtils::ETextHost ) &&
+	     aSkipNaptrAndSrvQueries )			
+		{
+        if ( protocol == SIPStrings::StringF( SipStrConsts::EEmpty ) )
+            {
+            protocol.Close();
+            protocol = DefaultTransport( uri.IsSIPSURI() );
+            }
+        if ( port == 0 )
+            {
+            port = DefaultPort( uri.IsSIPSURI() );
+			}
+		}
+		
+	ChooseQueryL( aObserver, *host, aResult, uri.IsSIPSURI(), 
+	              port, protocol, forceUDP, aSkipNaptrAndSrvQueries );
+	              
+	CleanupStack::PopAndDestroy( host );
+	}
+
+// ----------------------------------------------------------------------------
+// CSIPServerResolver::GetByViaL
+// ----------------------------------------------------------------------------
+//
+void CSIPServerResolver::GetByViaL( 
+    CSIPViaHeader& aVia,
+	RPointerArray< MSIPResolvingResult >& aResult, 
+    MSIPServerResolverObserver* aObserver )
+    {
+    TUint port( aVia.SentByHostPort().Port() );
+		
+	HBufC8* host = NULL;
+	
+	if ( aVia.HasParam(SIPStrings::StringF(SipStrConsts::EMaddr)) )
+		{
+		host = aVia.ParamValue( SIPStrings::StringF( 
+									SipStrConsts::EMaddr ) ).DesC().AllocLC();
+		}
+	else
+		{
+		host = aVia.SentByHostPort().Host().AllocLC();
+		}
+	
+	if ( !( UriUtils::HostType( *host ) == UriUtils::ETextHost ) )		
+		{
+		if ( port == 0 )
+			{
+			port = KSIPDefaultPort;
+			}
+		}
+		
+	ChooseQueryL( aObserver, *host, aResult, EFalse, port, aVia.Transport() );
+	
+	CleanupStack::PopAndDestroy( host );
+	}
+
+// ----------------------------------------------------------------------------
+// CSIPServerResolver::Cancel
+// ----------------------------------------------------------------------------
+//
+void CSIPServerResolver::Cancel( MSIPServerResolverObserver* aObserver )
+	{
+	iResolver->CancelGetByURI( aObserver );
+	}
+
+// ----------------------------------------------------------------------------
+// CSIPServerResolver::ChooseQueryL
+// ----------------------------------------------------------------------------
+//
+void CSIPServerResolver::ChooseQueryL( 
+    MSIPServerResolverObserver* aObserver,
+    const TDesC8& aTarget,
+    RPointerArray< MSIPResolvingResult >& aResult,
+    TBool aSipsUri,
+    TUint aPort,
+    RStringF aProtocol,
+    TBool aForceUDP,
+    TBool aSkipNaptrAndSrvQueries )
+	{	
+	CSIPQueryData* querydata = CSIPQueryData::NewL( aObserver,
+												    aPort, 
+												    aProtocol,
+												    aTarget,
+												    *iResolver,
+												    aResult,
+												    aSipsUri,
+												    aForceUDP );
+	CleanupStack::PushL( querydata );	
+	CServerQuery* query = CServerQuery::NewL( aObserver, querydata );
+	CleanupStack::Pop( querydata );
+	CleanupStack::PushL( query );
+		
+	if ( aPort || aSkipNaptrAndSrvQueries )
+		{
+		SetA_AAAAQueryL( query );
+		}
+	else
+		{
+		if ( aProtocol != SIPStrings::StringF( SipStrConsts::EEmpty ) )
+			{
+			SetSRVQueryL( query );
+			}
+		else
+			{
+			// NAPTR query is done only when resolving by URI, and neither the
+			// transport protocol nor port was specified in the URI.
+			SetNaptrQueryL( query );
+			}
+		}
+		
+	CleanupStack::Pop( query );
+	}
+
+// ----------------------------------------------------------------------------
+// CSIPServerResolver::SetA_AAAAQueryL
+// ----------------------------------------------------------------------------
+//
+void CSIPServerResolver::SetA_AAAAQueryL( CServerQuery* aQuery )
+	{
+	CSIPA_AAAAOrigDomain* querycondition =
+										 CSIPA_AAAAOrigDomain::NewL( *aQuery );																
+	CleanupStack::PushL( querycondition );
+	aQuery->SetQueryConditionL( querycondition );
+	CleanupStack::Pop( querycondition );		 								 
+	iResolver->GetByQueryL( aQuery );
+	}
+
+// ----------------------------------------------------------------------------
+// CSIPServerResolver::SetSRVQueryL
+// ----------------------------------------------------------------------------
+//
+void CSIPServerResolver::SetSRVQueryL( CServerQuery* aQuery )
+	{
+	CSIPSRVOrigDomain* querycondition = CSIPSRVOrigDomain::NewL( *aQuery );													
+	CleanupStack::PushL( querycondition );
+	aQuery->SetQueryConditionL( querycondition );
+	CleanupStack::Pop( querycondition );							 
+	iResolver->GetByQueryL( aQuery );
+	}
+	
+// ----------------------------------------------------------------------------
+// CSIPServerResolver::SetNaptrQueryL
+// ----------------------------------------------------------------------------
+//
+void CSIPServerResolver::SetNaptrQueryL( CServerQuery* aQuery )
+	{
+	CSIPNaptrOrigDomain* querycondition = CSIPNaptrOrigDomain::NewL( *aQuery );												
+	CleanupStack::PushL( querycondition );
+	aQuery->SetQueryConditionL( querycondition );
+	CleanupStack::Pop( querycondition );		 								 
+	iResolver->GetByQueryL( aQuery );
+	}
+
+// ----------------------------------------------------------------------------
+// CSIPServerResolver::TransportProtocolL
+// ----------------------------------------------------------------------------
+//
+RStringF CSIPServerResolver::TransportProtocolL( 
+    const CSIPURI& aURI,
+    TBool& aForceUdp ) const
+    {
+    aForceUdp = EFalse;
+    
+    RStringF protocol =
+        aURI.ParamValue( SIPStrings::StringF( SipStrConsts::ETransport ) );    
+    
+    if ( protocol == SIPStrings::StringF( SipStrConsts::EEmpty ) )
+        {
+        // Add explicit transport protocol 
+        // if there is a port in the URI or the host is an IP address
+        const CSIPHostPort& hostPort( aURI.HostPort() );
+        if ( hostPort.HasPort() || 
+             !( UriUtils::HostType( hostPort.Host() ) == UriUtils::ETextHost ) )
+            {
+            protocol = DefaultTransport( aURI.IsSIPSURI() );
+            }
+        }
+    else
+        {
+        if ( aURI.IsSIPSURI() && 
+             protocol == SIPStrings::StringF( SipStrConsts::EUDP ) )
+            {
+            User::Leave( KErrNotSupported );
+            }
+        
+        __ASSERT_ALWAYS( 
+            ( protocol == SIPStrings::StringF( SipStrConsts::ETCP ) ||
+		      protocol == SIPStrings::StringF( SipStrConsts::EUDP ) ||		
+		      protocol == SIPStrings::StringF( SipStrConsts::ETLS ) ),
+		    User::Leave( KErrNotSupported ) );
+		    
+		aForceUdp = ( protocol == SIPStrings::StringF( SipStrConsts::EUDP ) ); 
+        }
+    return protocol;
+    }
+
+// ----------------------------------------------------------------------------
+// CSIPServerResolver::DefaultTransport
+// ----------------------------------------------------------------------------
+//
+RStringF CSIPServerResolver::DefaultTransport( TBool aSipsUri ) const
+    {
+    RStringF protocol( SIPStrings::StringF( SipStrConsts::EUDP ) );
+    if ( aSipsUri )
+        {
+        protocol = SIPStrings::StringF( SipStrConsts::ETLS );
+        }
+    return protocol; 
+    }
+
+// ----------------------------------------------------------------------------
+// CSIPServerResolver::DefaultPort
+// ----------------------------------------------------------------------------
+//        
+TUint CSIPServerResolver::DefaultPort( TBool aUseTls ) const
+    {
+    TUint port( KSIPDefaultPort );
+    if ( aUseTls )
+        {
+        port = KSIPsDefaultPort;
+        }
+    return port;
+    }