diff -r f742655b05bf -r d38647835c2e voipplugins/sipconnectionprovider/src/scpprofilehandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/voipplugins/sipconnectionprovider/src/scpprofilehandler.cpp Wed Sep 01 12:29:57 2010 +0100 @@ -0,0 +1,1010 @@ +/* +* Copyright (c) 2007-2010 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: +* +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ipvmbxinterface.h" +#include "scpprofilehandler.h" +#include "scplogger.h" +#include "scpsipconnection.h" +#include "cipappphoneutils.h" +#include "cipapputilsaddressresolver.h" + +#include "scputility.h" + +const TInt KTempStringlength = 200; +const TUint KSCPUserAgentStringLength = 12; +const TUint KSCPWlanMacAddressLength = 50; +const TUint KSCPMaxTerminalTypeLength = 64; +_LIT( KScpUserAgentString, "User-Agent: " ); +_LIT8 ( KSCPWlanMacAddressFrmt, "-" ); + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::CScpProfileHandler +// ----------------------------------------------------------------------------- +// +CScpProfileHandler::CScpProfileHandler() + { + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::ConstructL +// ----------------------------------------------------------------------------- +// +void CScpProfileHandler::ConstructL() + { + SCPLOGSTRING( "CScpProfileHandler::ConstructL" ); + + iSip = CSIP::NewL( TUid::Null(), *this ); + iProfileRegistry = CSIPProfileRegistry::NewL( *iSip, *this ); + iManagedProfileRegistry = CSIPManagedProfileRegistry::NewL( *this ); + iAlrController = CSipProfileAlrController::NewL( *iProfileRegistry, + *this ); + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::NewL +// ----------------------------------------------------------------------------- +// +CScpProfileHandler* CScpProfileHandler::NewL() + { + CScpProfileHandler* self = new ( ELeave ) CScpProfileHandler(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::~CScpProfileHandler +// ----------------------------------------------------------------------------- +// +CScpProfileHandler::~CScpProfileHandler() + { + SCPLOGSTRING( "CScpProfileHandler::~CScpProfileHandler" ); + + iObservers.Close(); + iSipConnections.ResetAndDestroy(); + iSipConnections.Close(); + + delete iVmbxInterface; + delete iAlrController; + delete iManagedProfileRegistry; + delete iProfileRegistry; + delete iSip; + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::AddObserverL +// ----------------------------------------------------------------------------- +// +void CScpProfileHandler::AddObserverL( MScpSipConnectionObserver& aObserver ) + { + SCPLOGSTRING2( "CScpProfileHandler::AddObserverL: 0x%x", &aObserver ); + + TInt result = iObservers.Find( &aObserver ); + + if ( result == KErrNotFound ) + { + iObservers.AppendL( &aObserver ); + } + else + { + User::Leave( KErrAlreadyExists ); + } + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::RemoveObserver +// ----------------------------------------------------------------------------- +// +TInt CScpProfileHandler::RemoveObserver( MScpSipConnectionObserver& aObserver ) + { + SCPLOGSTRING2( "CScpProfileHandler::RemoveObserver: 0x%x", &aObserver ); + + TInt result = iObservers.Find( &aObserver ); + + if ( result != KErrNotFound ) + { + iObservers.Remove( result ); + return KErrNone; + } + + return KErrNotFound; + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::GetCurrentState +// ----------------------------------------------------------------------------- +// +TInt CScpProfileHandler::GetCurrentState( TUint32 aProfileId, + CScpSipConnection::TConnectionState& aState, + TInt& aError ) const + { + SCPLOGSTRING( "CScpProfileHandler::GetCurrentState" ); + + TInt result( KErrNone ); + + // Go through own sip profiles and check state + // If not found, create SipConnection and check state + CScpSipConnection* sipConnection = GetSipConnection( aProfileId ); + + TBool sipConnectionCreated = EFalse; + + if( !sipConnection ) + { + sipConnectionCreated = ETrue; + TRAP( result, sipConnection = CreateSipConnectionL( aProfileId ) ); + } + + if( result == KErrNone && sipConnection ) + { + sipConnection->GetState( aState, aError ); + } + + if( sipConnectionCreated ) + { + delete sipConnection; + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::RegisterProfileL +// ----------------------------------------------------------------------------- +// +void CScpProfileHandler::RegisterProfileL( TUint32 aProfileId ) + { + SCPLOGSTRING2("CScpProfileHandler::RegisterProfileL profile id: %d", aProfileId ); + + // Check if sip connection already exists + TBool found( EFalse ); + CScpSipConnection* sipConnection( NULL ); + + for( TInt i=0; iProfileId() == aProfileId ) + { + found = ETrue; + sipConnection->EnableL(); + break; + } + } + + // Otherwise create it + if( !found ) + { + sipConnection = CreateSipConnectionL( aProfileId ); + CleanupStack::PushL( sipConnection ); + // try enabling + sipConnection->AddObserver( *this ); + sipConnection->EnableL(); + // add to array + iSipConnections.AppendL( sipConnection ); + CleanupStack::Pop( sipConnection ); + } + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::SipConnectionExists +// ----------------------------------------------------------------------------- +// +TBool CScpProfileHandler::SipConnectionExists( TUint32 aProfileId ) const + { + SCPLOGSTRING2("CScpProfileHandler::SipConnectionExists profile id: %d", aProfileId ); + + return ( GetSipConnection( aProfileId ) != NULL ); + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::GetSipConnection +// ----------------------------------------------------------------------------- +// +CScpSipConnection* CScpProfileHandler::GetSipConnection( TUint32 aProfileId ) const + { + SCPLOGSTRING2("CScpProfileHandler::GetSipConnection profile id: %d", aProfileId ); + + CScpSipConnection* sipConnection( NULL ); + + for( TInt i=0; iProfileId() == aProfileId ) + { + return sipConnection; + } + } + + return NULL; + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::CreateSipConnectionL +// ----------------------------------------------------------------------------- +// +CScpSipConnection* CScpProfileHandler::CreateSipConnectionL( TUint32 aProfileId ) const + { + SCPLOGSTRING2("CScpProfileHandler::CreateSipConnectionL profile: %d", aProfileId); + + return CScpSipConnection::NewL( aProfileId, + *iProfileRegistry, + *iManagedProfileRegistry, + *iSip ); + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::UnRegisterProfile +// ----------------------------------------------------------------------------- +// +TInt CScpProfileHandler::UnregisterProfile( TUint32 aProfileId ) + { + SCPLOGSTRING2("CScpProfileHandler::UnregisterProfile id: %d", aProfileId ); + + CScpSipConnection* sipConnection( NULL ); + + for( TInt i=0; iProfileId() == aProfileId ) + { + return sipConnection->Disable(); + } + } + + return KErrNotFound; + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::CancelRegistration +// ----------------------------------------------------------------------------- +// +TInt CScpProfileHandler::CancelRegistration( TUint32 aProfileId ) + { + SCPLOGSTRING2("CScpProfileHandler::UnregisterProfile id: %d", aProfileId ); + + TInt result = UnregisterProfile( aProfileId ); + + if( result == KErrNone || + result == KErrNotFound || + result == KErrArgument ) + { + result = RemoveSipConnection( aProfileId ); + } + + return result; + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::IncomingRequest +// ----------------------------------------------------------------------------- +// +void CScpProfileHandler::IncomingRequest( TUint32 /*aIapId*/, + CSIPServerTransaction* /*aTransaction*/ ) + { + SCPLOGSTRING( "CScpProfileHandler::IncomingRequest" ); + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::TimedOut +// ----------------------------------------------------------------------------- +// +void CScpProfileHandler::TimedOut( + CSIPServerTransaction& /*aTransaction*/ ) + { + SCPLOGSTRING( "CScpProfileHandler::TimedOut" ); + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::RemoveSipConnection +// ----------------------------------------------------------------------------- +// +TInt CScpProfileHandler::RemoveSipConnection( TUint32 aProfileId ) + { + SCPLOGSTRING2( "CScpProfileHandler::RemoveSipConnection id: %i", + aProfileId ); + + TInt ret = ( KErrNotFound ); + CScpSipConnection* sipConnection( NULL ); + + sipConnection = GetSipConnection( aProfileId ); + + if ( sipConnection ) + { + TInt index = iSipConnections.Find( sipConnection ); + iSipConnections.Remove( index ); + delete sipConnection; + ret = KErrNone; + } + return ret; + } + + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::ProfileRegistryEventOccurred +// ----------------------------------------------------------------------------- +// +void CScpProfileHandler::ProfileRegistryEventOccurred( + TUint32 aProfileId, + MSIPProfileRegistryObserver::TEvent aEvent ) + { + SCPLOGSTRING3( "CScpProfileHandler::ProfileRegistryEventOccurred id: %i event: %d", + aProfileId, aEvent ); + + CScpSipConnection* sipConnection = GetSipConnection( aProfileId ); + + if( sipConnection ) + { + sipConnection->ProfileRegistryEventOccurred( aEvent ); + + // Deal with sip profile removals + switch ( aEvent ) + { + case EProfileDeregistered: + { + // Remove sip connection only if user has requested deregistration + CScpSipConnection::TRegistrationRequestState state = + sipConnection->RegistrationRequestState(); + + if( state == CScpSipConnection::EDeregistrationRequested ) + { + RemoveSipConnection( aProfileId ); + } + } + break; + + case EProfileDestroyed: + { + RemoveSipConnection( aProfileId ); + } + break; + + default: + break; + } + } + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::ProfileRegistryErrorOccurred +// ----------------------------------------------------------------------------- +// +void CScpProfileHandler::ProfileRegistryErrorOccurred( TUint32 aProfileId, + TInt aError ) + { + SCPLOGSTRING3( "CScpProfileHandler::ProfileRegistryErrorOccurred profile:%i error: %d", + aProfileId, aError ); + + CScpSipConnection* sipConnection = GetSipConnection( aProfileId ); + + if( sipConnection ) + { + sipConnection->ProfileRegistryErrorOccurred( aError ); + } + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::ProfileExist +// ----------------------------------------------------------------------------- +// +TBool CScpProfileHandler::ProfileExists( TUint32 aProfileId ) const + { + SCPLOGSTRING2( "CScpProfileHandler::ProfileExists id: %d", aProfileId ); + + CSIPProfile* profile( NULL ); + TRAPD( result, profile = iProfileRegistry->ProfileL( aProfileId ) ); + + if( result == KErrNone && profile ) + { + delete profile; + return ETrue; + } + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::SetSipProfileReserved +// ----------------------------------------------------------------------------- +// +void CScpProfileHandler::SetSipProfileReserved( TUint32 aProfileId, TBool aReserved ) + { + SCPLOGSTRING3( "CScpProfileHandler::SetSipProfileReserved id: %d reserved: %d", + aProfileId, aReserved ); + + CScpSipConnection* sipConnection = GetSipConnection( aProfileId ); + + if( sipConnection ) + { + sipConnection->SetReserved( aReserved ); + + // If profile was freed and iap availability alr event had come + // before, let ALR controller to know that the profile is up + // for ALR + if( aReserved == EFalse && + sipConnection->IapAvailableOffered() ) + { + TRAP_IGNORE( iAlrController->RefreshIapAvailabilityL( aProfileId ) ); + + // Reset the iap availability offered flag + sipConnection->SetIapAvailableOffered( EFalse ); + } + } + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::StartAlrMigration +// ----------------------------------------------------------------------------- +// +void CScpProfileHandler::StartAlrMigration( TUint32 aProfileId ) + { + SCPLOGSTRING2( "CScpProfileHandler::StartMigrtion profile: %i", aProfileId ); + SCPLOGSTRING2( "CScpProfileHandler::StartMigrtion iNewAlrIapId: %i", iNewAlrIapId ); + + TRAP_IGNORE( + iAlrController->AllowMigrationL( aProfileId, iNewAlrIapId ) ); + + CScpSipConnection* sipConnection( NULL ); + sipConnection = GetSipConnection( aProfileId ); + + if ( sipConnection ) + { + sipConnection->SetProfileCurrentlyRoaming(); + } + + SCPLOGSTRING( "CScpProfileHandler::StartMigrtion -exit" ); + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::AlrEvent +// ----------------------------------------------------------------------------- +// +void CScpProfileHandler::AlrEvent( MSipProfileAlrObserver::TEvent aEvent, + TUint32 aProfileId, +#ifdef _DEBUG + TUint32 aSnapId, +#else + TUint32 /*aSnapId*/, +#endif + TUint32 aIapId ) + { + SCPLOGSTRING2("CScpProfileHandler::AlrEvent profile:%i", aProfileId); + SCPLOGSTRING2("CScpProfileHandler::AlrEvent aEvent:%i", (TInt)aEvent); + SCPLOGSTRING2("CScpProfileHandler::AlrEvent aSnapId:%i", aSnapId); + SCPLOGSTRING2("CScpProfileHandler::AlrEvent aIapId:%i", aIapId); + + CScpSipConnection* sipConnection( NULL ); + + switch( aEvent ) + { + case MSipProfileAlrObserver::EIapAvailable: + { + TBool reserved( EFalse ); + sipConnection = GetSipConnection( aProfileId ); + + if( sipConnection ) + { + reserved = sipConnection->Reserved(); + + if( reserved ) + { + TRAPD( result, + iAlrController->DisallowMigrationL( aProfileId, aIapId ) ); + + if( result == KErrNone ) + { + // Raise the iap availability offered flag + sipConnection->SetIapAvailableOffered( ETrue ); + } + } + else + { + iAlrAllowedToStartImmediately = ETrue; + + for ( TInt i = 0; i < iObservers.Count(); i++ ) + { + if ( !iObservers[ i ]->IsSipProfileAllowedToStartAlr() ) + { + iAlrAllowedToStartImmediately = EFalse; + break; + } + } + if ( iAlrAllowedToStartImmediately ) + { + TRAP_IGNORE( + iAlrController->AllowMigrationL( aProfileId, aIapId ) ); + sipConnection->SetProfileCurrentlyRoaming(); + } + else + { + iNewAlrIapId = aIapId; + sipConnection->HandleMigrationStarted(); + } + } + } + break; + } + + // For possible beyond use (E.g. Maybe we should change CHH state + // during iap migration -> VoIP call not possible if iap migration + // ongoing.) + case MSipProfileAlrObserver::EMigrationStarted: + { + sipConnection = GetSipConnection( aProfileId ); + + if( sipConnection && iAlrAllowedToStartImmediately ) + { + sipConnection->HandleMigrationStarted(); + } + break; + } + + case MSipProfileAlrObserver::EMigrationCompleted: + default: + { + break; + } + } + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::AlrError +// ----------------------------------------------------------------------------- +// +void CScpProfileHandler::AlrError( + TInt aError, + TUint32 aProfileId, + TUint32 aSnapId, + TUint32 aIapId ) + { + SCPLOGSTRING("CScpProfileHandler::AlrError"); + SCPLOGSTRING2(" profile id: %d", aProfileId); + SCPLOGSTRING2(" error: %d", aError); + + CScpSipConnection* sipConnection = GetSipConnection( aProfileId ); + if( sipConnection ) + { + sipConnection->HandleMigrationError( + aError, aProfileId, aSnapId, aIapId ); + } + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::HandleSipConnectionEvent +// ----------------------------------------------------------------------------- +// +void CScpProfileHandler::HandleSipConnectionEvent( TUint32 aProfileId, + TScpConnectionEvent aSipEvent ) + { + SCPLOGSTRING3( + "CScpProfileHandler::HandleSipConnectionEvent profile id: %d sip event: %d", + aProfileId, aSipEvent ); + + // Make a copy of the observers array, since observers + // may be removed during the event handling + RPointerArray< MScpSipConnectionObserver > observers; + + for ( TInt i=0; i < iObservers.Count(); i++ ) + { + observers.Append( iObservers[ i ] ); + } + + // Send notify to observers + for( TInt i=0; i < observers.Count(); i++ ) + { + //check that the observer is still valid before triggering notify + if ( KErrNotFound != iObservers.Find( observers[ i ] ) ) + { + observers[ i ]->HandleSipConnectionEvent( aProfileId, aSipEvent ); + } + } + + observers.Close(); + + // if registration failed, time to delete connection + if ( aSipEvent == EScpRegistrationFailed ) + { + RemoveSipConnection( aProfileId ); + } + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::IsSipProfileAllowedToStartAlr +// ----------------------------------------------------------------------------- +// +TBool CScpProfileHandler::IsSipProfileAllowedToStartAlr() + { + return ETrue; + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::VmbxInterfaceL +// ----------------------------------------------------------------------------- +// +CIpVmbxInterface& CScpProfileHandler::VmbxInterfaceL( MIpVmbxObserver& aObserver ) + { + SCPLOGSTRING( "CScpProfileHandler::VmbxInterfaceL" ); + + // Todo: save observer and set MIpVmbxObserver to this class + // problem when several vmbx services, current observer logic isn't work + + if( !iVmbxInterface ) + { + iVmbxInterface = CIpVmbxInterface::NewL( aObserver ); + } + + return *iVmbxInterface; + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::DeleteVmbxInterface +// ----------------------------------------------------------------------------- +// +void CScpProfileHandler::DeleteVmbxInterface() + { + SCPLOGSTRING( "CScpProfileHandler::DeleteVmbxInterface" ); + + if( iVmbxInterface ) + { + delete iVmbxInterface; + iVmbxInterface = NULL; + } + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::UpdateSipProfile +// ----------------------------------------------------------------------------- +// +void CScpProfileHandler::UpdateSipProfileL( + TUint32 aProfileId, + TBool aTerminalType, + TBool aWlanMac, + TInt aStringLength ) + { + SCPLOGSTRING( "CScpProfileHandler::UpdateSipProfileL IN" ); + SCPLOGSTRING2( " profile id: %d", aProfileId ); + SCPLOGSTRING2( " terminal type: %d", aTerminalType ); + SCPLOGSTRING2( " wlan mac: %d", aWlanMac ); + SCPLOGSTRING2( " string length: %d", aStringLength ); + + // Do not update, if terminal type is not defined in user agent header + if ( !aTerminalType ) + { + return; + } + + const MDesC8Array* array; + CSIPProfile* sipProfile = iProfileRegistry->ProfileL( aProfileId ); + CleanupStack::PushL( sipProfile ); + User::LeaveIfError( sipProfile->GetParameter( KSIPHeaders, array ) ); + + TBuf terminalType( KNullDesC ); + TBuf tempHeader( KNullDesC ); + + // 1. Get the terminal type and seek is user agent header's + // terminal type same, if so no need to continue + CIpAppPhoneUtils* libIpAppPhoneUtils = CIpAppPhoneUtils::NewLC(); + libIpAppPhoneUtils->GetTerminalTypeL( terminalType ); + CleanupStack::PopAndDestroy( libIpAppPhoneUtils ); + + for( TInt t( 0 ); t < array->MdcaCount(); t++ ) + { + tempHeader.Copy( array->MdcaPoint( t ) ); + if( tempHeader.Find( terminalType ) != KErrNotFound ) + { + SCPLOGSTRING(" terminal type found"); + CleanupStack::PopAndDestroy( sipProfile ); + return; + } + } + + // 2. If appropriate terminal type not found, we need to update it + if ( array->MdcaCount() ) + { + TBuf8 userAgentHeader; + CDesC8ArrayFlat* uahArray = new ( ELeave ) CDesC8ArrayFlat( 1 ); + CleanupStack::PushL( uahArray ); + //Find the User-Agent string + for( TInt t( 0 ); t < array->MdcaCount(); t++ ) + { + tempHeader.Copy( array->MdcaPoint( t ) ); + // user-Agent found, now change it + if( tempHeader.Find( KScpUserAgentString ) != KErrNotFound ) + { + // 3. now we have the right user agent header which is not correct + // replace the old terminal type + TInt len( KErrNone ); + // Get mac if defined + if ( aWlanMac ) + { + TBuf8 wlanMacAddress( KNullDesC8 ); + TBuf tempAddr( KNullDesC ); + CIPAppUtilsAddressResolver* addressResolver = + CIPAppUtilsAddressResolver::NewLC(); + User::LeaveIfError( addressResolver->GetWlanMACAddress( + wlanMacAddress, KSCPWlanMacAddressFrmt ) ); + CleanupStack::PopAndDestroy( addressResolver ); + tempAddr.Copy( wlanMacAddress ); + + // leave the space before MAC ADDR (-1) + len = tempHeader.Find( tempAddr ) - KSCPUserAgentStringLength - 1; + } + else + { + // leave the space before free string (-1) + len = tempHeader.Length() - KSCPUserAgentStringLength - aStringLength - 1; + } + // make sure that the len is correct value(not below zero) + if ( 0 >= len ) + { + User::Leave( KErrGeneral ); + } + tempHeader.Replace( KSCPUserAgentStringLength, len, terminalType ); + SCPLOGSTRING2(" header: %S", &tempHeader); + userAgentHeader.Append( tempHeader ); + uahArray->AppendL( userAgentHeader ); + } + else + { + //if this entry is not user agent, leave it untouched + uahArray->AppendL( array->MdcaPoint( t ) ); + } + } + + CSIPManagedProfile* managedProfile = static_cast( + iProfileRegistry->ProfileL( aProfileId ) ); + CleanupStack::PushL( managedProfile ); + //Update the new user-agent to sipprofile + User::LeaveIfError( + managedProfile->SetParameter( KSIPHeaders, *uahArray ) ); + iManagedProfileRegistry->SaveL( *managedProfile ); + CleanupStack::PopAndDestroy( managedProfile ); + CleanupStack::PopAndDestroy( uahArray ); + } + CleanupStack::PopAndDestroy( sipProfile ); + SCPLOGSTRING( "CScpProfileHandler::UpdateSipProfileL OUT" ); + } + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::SetUsernameAndPasswordL +// ----------------------------------------------------------------------------- +// +void CScpProfileHandler::SetUsernameAndPasswordL( TUint32 aProfileId, + const TDesC8& aUsername, + TBool aSetUsername, + const TDesC8& aPassword, + TBool aSetPassword ) + { + SCPLOGSTRING( "CScpProfileHandler::SetUsernameAndPasswordL" ); + + CSIPManagedProfile* profile = static_cast + (iProfileRegistry->ProfileL( aProfileId )); + CleanupStack::PushL( profile ); + + SCPLOGSTRING( "CScpProfileHandler::SetUsernameAndPasswordL sip profile availble" ); + + if( aSetUsername ) + { + RBuf8 formattedUsername; + CleanupClosePushL( formattedUsername ); + + if( !TScpUtility::CheckSipUsername( aUsername ) ) + { + // Since username is returned with prefix and domain, it needs + // to be possible to also set it with prefix and domain. + // Strip prefix and domain from user aor if found. + // Prefix might be sip or sips so search by colon. + // If username is empty, leave with KErrArgument + if ( aUsername == KNullDesC8 ) + { + User::Leave( KErrArgument ); + } + else + { + User::LeaveIfError( TScpUtility::RemovePrefixAndDomain( + aUsername, formattedUsername ) ); + } + } + else + { + formattedUsername.CreateL( aUsername.Length() ); + formattedUsername.Copy( aUsername ); + } + + TBool validAorExists( EFalse ); + const TDesC8* aorPtr( NULL ); + + TInt err = profile->GetParameter( KSIPUserAor, aorPtr ); + + TInt loc( KErrNotFound ); + if ( !err && aorPtr->Length() ) + { + loc = aorPtr->Find( KAt() ); + + if ( KErrNotFound != loc ) + { + TPtrC8 ptr = aorPtr->Right( 1 ); + + if ( ptr.Compare( KAt ) != 0 ) + { + // @ is found and there is something in domain part + validAorExists = ETrue; + } + } + } + + HBufC8* newAor = NULL; + TBuf8 prefix; + TScpUtility::GetValidPrefix( aUsername, prefix ); + + if ( validAorExists ) + { + SCPLOGSTRING( "CScpProfileHandler::SetUsernameAndPasswordL valid aor" ); + TPtrC8 domainPart = aorPtr->Mid( loc ); + + newAor = HBufC8::NewLC( prefix.Length() + + domainPart.Length() + + formattedUsername.Length() ); + newAor->Des().Append( prefix ); + newAor->Des().Append( formattedUsername ); + newAor->Des().Append( domainPart ); + } + else + { + SCPLOGSTRING( "CScpProfileHandler::SetUsernameAndPasswordL no valid aor" ); + // Check if given username contains valid aor + TInt loc = aUsername.Find( KAt() ); + + if ( KErrNotFound != loc ) + { + TPtrC8 ptrRight = aorPtr->Right( 1 ); + TPtrC8 ptrLeft = aorPtr->Left( 1 ); + + if ( ( ptrRight.Compare( KAt ) != 0 ) && + ( ptrLeft.Compare( KAt ) != 0 ) ) + { + // both sides of @ have data --> aor is valid + newAor = HBufC8::NewLC( aUsername.Length() ); + newAor->Des().Copy( aUsername ); + } + else + { + User::Leave( KErrArgument ); + } + } + else + { + User::Leave( KErrArgument ); + } + } + + SCPLOGSTRING( "CScpProfileHandler::SetUsernameAndPasswordL set new aor value" ); + + User::LeaveIfError( profile->SetParameter( KSIPUserAor, newAor->Des() ) ); + CleanupStack::PopAndDestroy( newAor ); + + // Add digest username & password + SCPLOGSTRING( "CScpProfileHandler:SetUsernameAndPasswordL outbound & digest username" ); + User::LeaveIfError( profile->SetParameter( KSIPOutboundProxy, + KSIPDigestUserName, + formattedUsername ) ); + + + SCPLOGSTRING( "CScpProfileHandler:SetUsernameAndPasswordL registrar & digest username" ); + User::LeaveIfError( profile->SetParameter( KSIPRegistrar, + KSIPDigestUserName, + formattedUsername ) ); + CleanupStack::PopAndDestroy( &formattedUsername ); + } + + if( aSetPassword ) + { + if( !TScpUtility::CheckSipPassword( aPassword ) ) + { + User::Leave( KErrArgument ); + } + SCPLOGSTRING( "CScpProfileHandler:SetUsernameAndPasswordL outbound & digest pwd" ); + User::LeaveIfError( profile->SetParameter( KSIPOutboundProxy, + KSIPDigestPassword, + aPassword ) ); + SCPLOGSTRING( "CScpProfileHandler:SetUsernameAndPasswordL registrar & digest pwd" ); + User::LeaveIfError( profile->SetParameter( KSIPRegistrar, + KSIPDigestPassword, + aPassword ) ); + } + + SCPLOGSTRING( "CScpProfileHandler:SetUsernameAndPasswordL save sip changes" ); + + // Save changes + TRAPD( err, iManagedProfileRegistry->SaveL( *profile ) ); + + CleanupStack::PopAndDestroy( profile ); + + SCPLOGSTRING2( "CScpProfileHandler:SetUsernameAndPasswordL save sip err: %d", err ); + User::LeaveIfError( err ); + } + + + +// ----------------------------------------------------------------------------- +// CScpProfileHandler::GetDebugInfo +// ----------------------------------------------------------------------------- +// +#ifdef _DEBUG +void CScpProfileHandler::GetDebugInfo( TDes& aInfo ) const + { + TInt connections = iSipConnections.Count(); + TInt registeredConnections( 0 ); + TInt registeringConnections( 0 ); + TInt unregisteringConnections( 0 ); + TInt unregisteredConnections( 0 ); + + for( TInt i=0; iGetState( state, error ); + + switch( state ) + { + case CScpSipConnection::ERegistered: + registeredConnections++; + break; + + case CScpSipConnection::ERegistering: + registeringConnections++; + break; + + case CScpSipConnection::EDeregistering: + unregisteringConnections++; + break; + + case CScpSipConnection::EDeregistered: + unregisteredConnections++; + break; + + default: + break; + } + } + + TBuf< 255 > buffer; + buffer.Format( _L( "Connections: %d\n Registered: %d\n Registering: %d\n Unregistering: %d\n Unregistered: %d\n" ), + connections, registeredConnections, registeringConnections, + unregisteringConnections, unregisteredConnections ); + + aInfo.Append( buffer ); + } +#endif + +// ========================== OTHER EXPORTED FUNCTIONS ========================= + +// End of File