diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SIP/ServerResolver/src/CSIPServerResolver.cpp --- /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 +#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; + }