diff -r 000000000000 -r 1bce908db942 multimediacommsengine/mmcesrv/mmceserver/src/mcesipmanager.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/multimediacommsengine/mmcesrv/mmceserver/src/mcesipmanager.cpp Tue Feb 02 01:04:58 2010 +0200 @@ -0,0 +1,1088 @@ +/* +* Copyright (c) 2005 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 +#include +#include +#include +#include +#include + +#include "mcesipstatemachine.h" +#include "mcesipmanager.h" +#include "mceservercore.h" +#include "mcecssession.h" +#include "mcecssessionimplementation.h" +#include "mcesipsession.h" +#include "mcesipconnection.h" +#include "mcemediamanager.h" +#include "mcenatpluginmanager.h" +#include "mcenatsipsession.h" +#include "mceclientserver.h" +#include "mcesrvlogs.h" +#include "mceclient.pan" +#include "mcesipevent.h" +#include "mceclientresolver.h" +#include "mcetimermanager.h" +#include "cleanupresetanddestroy.h" + + +#define REJECT( transaction )\ + MCESRV_DEBUG("REJECTED");\ + MceSip::DiscardRequest( transaction );\ + return + +#define REJECT_IF_ERROR( error, transaction )\ + if ( error != KErrNone )\ + {\ + REJECT( transaction );\ + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::NewL +// ----------------------------------------------------------------------------- +// +CMceSipManager* CMceSipManager::NewL (CMceServerCore& aServerCore ) + { + CMceSipManager* self = CMceSipManager::NewLC( aServerCore ); + CleanupStack::Pop(self); + return self; + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::NewLC +// ----------------------------------------------------------------------------- +// +CMceSipManager* CMceSipManager::NewLC ( CMceServerCore& aServerCore ) + { + CMceSipManager* self = new (ELeave) CMceSipManager(aServerCore); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::CMceSipManager +// ----------------------------------------------------------------------------- +// +CMceSipManager::CMceSipManager (CMceServerCore& aServerCore) +: iServerCore (aServerCore), + iNextDialogId( 0 ) + { + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::ConstructL +// ----------------------------------------------------------------------------- +// +void CMceSipManager::ConstructL () + { + MCESRV_DEBUG("CMceSipManager::ConstructL, Entry") + + User::LeaveIfError( iSocketServ.Connect() ); + + iSIP = CSIP::NewL( KServerUid3, *this ); + iProfileRegistry = CSIPProfileRegistry::NewL( *iSIP, *this ); + + iMediaManager = CMceMediaManager::NewL( *this ); + iStateMachine = CMceSipStateMachine::NewL(); + + iClientResolver = CMceClientResolver::NewL( *this ); + + iOrphanSubSessions = CMceCsSessionImplementation::NewL( *this, NULL ); + + iTimerManager = CMceTimerManager::NewL(); + + MCESRV_DEBUG("CMceSipManager::ConstructL, Exit") + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::~CMceSipManager +// ----------------------------------------------------------------------------- +// +CMceSipManager::~CMceSipManager() + { + MCESRV_DEBUG("CMceSipManager::~CMceSipManager, Entry") + + iSIPClientConnections.ResetAndDestroy(); + iSIPClientConnections.Close(); + iClients.Reset(); + iClients.Close(); + + if ( iOrphanSubSessions ) + { + iOrphanSubSessions->RemoveAllSubSessions( EFalse ); + } + delete iOrphanSubSessions; + + iProfiles.ResetAndDestroy(); + iProfiles.Close(); + + delete iMediaManager; + delete iStateMachine; + delete iProfileRegistry; + delete iClientResolver; + delete iTimerManager; + delete iSIP; + + iSocketServ.Close(); + + MCESRV_DEBUG("CMceSipManager::~CMceSipManager, Exit") + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::NextDialogId +// ----------------------------------------------------------------------------- +// +TUint32 CMceSipManager::NextDialogId() + { + iNextDialogId++; + return iNextDialogId; + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::RegisterClientL +// ----------------------------------------------------------------------------- +// +void CMceSipManager::RegisterClientL( CMceCsSession& aClientSession ) + { + MCESRV_DEBUG("CMceSipManager::RegisterClientL, Entry") + MCESRV_DEBUG_DVALUE("UID", aClientSession.Uid().iUid ) + + iClientResolver->RegisterClientL( aClientSession.Uid() ); + iClients.AppendL( &aClientSession ); + + MCESRV_DEBUG("CMceSipManager::RegisterClientL, Exit") + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::UnRegisterClient +// ----------------------------------------------------------------------------- +// +void CMceSipManager::UnRegisterClient( CMceCsSession& aClientSession ) + { + MCESRV_DEBUG("CMceSipManager::UnRegisterClient, Entry") + + iClientResolver->DeregisterClient( aClientSession.Uid() ); + + TInt index = iClients.Find( &aClientSession ); + + if ( index >= KErrNone ) + { + iClients.Remove( index ); + } + else + { + MCESRV_DEBUG("UnRegisterClient: CLIENT NOT FOUND") + } + + MCESRV_DEBUG("CMceSipManager::UnRegisterClient, Exit") + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::MediaManager +// ----------------------------------------------------------------------------- +// +CMceMediaManager& CMceSipManager::MediaManager() + { + return *iMediaManager; + } + + +// ----------------------------------------------------------------------------- +// CMceSipManager::TimerManager +// ----------------------------------------------------------------------------- +// +CMceTimerManager& CMceSipManager::TimerManager() + { + return *iTimerManager; + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::MediaManager +// ----------------------------------------------------------------------------- +// +CSIP& CMceSipManager::SIPClient() + { + return *iSIP; + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::ProfileL +// ----------------------------------------------------------------------------- +// +CSIPProfile& CMceSipManager::ProfileL( TUint32 aProfileId ) + { + CSIPProfile* profile = NULL; + TInt status = KErrNotFound; + + TInt index = FindProfileById( iProfiles, aProfileId ); + if ( index != KErrNotFound ) + { + profile = iProfiles[ index ]; + } + else + { + RPointerArray profiles; + iProfileRegistry->ProfilesL( profiles ); + + index = FindProfileById( profiles, aProfileId ); + if ( index != KErrNotFound ) + { + profile = profiles[ index ]; + status = iProfiles.Append( profile ); + if ( status != KErrNone ) + { + profile = NULL; + } + else + { + profiles.Remove( index ); + } + } + profiles.ResetAndDestroy(); + profiles.Close(); + } + if (!profile ) + { + User::Leave( status ); + } + + return *profile; + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::ProfileL +// ----------------------------------------------------------------------------- +// +CSIPProfile& CMceSipManager::ProfileL( TUint32 /*aIapId*/, + const CUri8& aRequestUri ) + { + CSIPProfile* profile = NULL; + TInt status = KErrNotFound; + + // Try to find in existing profiles + // Try matching with request URI + TInt index = FindProfileByRequestUriL( iProfiles, aRequestUri ); + + if ( index != KErrNotFound ) + { + // found in existing profiles + profile = iProfiles[ index ]; + } + else + { + // Get all profiles + RPointerArray profiles; + MceCleanupResetAndDestroyPushL( profiles ); + iProfileRegistry->ProfilesL( profiles ); + // Try matching with request URI + index = FindProfileByRequestUriL( profiles, aRequestUri ); + + if ( index != KErrNotFound ) + { + profile = profiles[ index ]; + status = iProfiles.Append( profile ); + if ( status != KErrNone ) + { + profile = NULL; + } + else + { + profiles.Remove( index ); + } + } + CleanupStack::PopAndDestroy( &profiles ); + } + + if (!profile ) + { + User::Leave( status ); + } + + return *profile; + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::Cleanup +// ----------------------------------------------------------------------------- +// +void CMceSipManager::Cleanup() + { + MCESRV_DEBUG("CMceSipManager::Cleanup, Entry") + + for ( int i = 0; i < iOrphanSubSessions->SubSessions().Count(); i++ ) + { + CMceCsSubSession* session = iOrphanSubSessions->SubSessions()[i]; + if ( session->CanDispose() || + session->Terminate() ) + { + MCESRV_DEBUG_DVALUE("Cleanup: orphan removed. ID", + MCE_SESSION_ID( session ) ) + iOrphanSubSessions->SubSessions().Remove( i ); + delete session; + i--; + } + } + + // If number of orphan subsessions and number of CMceCsSession + // object's count are 0, stop MCE server after time out. + iServerCore.InactiveServerCleanup(); + + MCESRV_DEBUG("CMceSipManager::Cleanup, Exit") + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::ConnectionL +// ----------------------------------------------------------------------------- +// +CMceSipConnection& CMceSipManager::ConnectionL( CSIPProfile& aProfile ) + { + MCESRV_DEBUG("CMceSipManager::ConnectionL, Entry") + TUint32 iapId = 0; + aProfile.GetParameter( KSIPAccessPointId, iapId ); + + CMceSipConnection* connection = NULL; + + TInt index = 0; + while ( !connection && index < iSIPClientConnections.Count() ) + { + if ( iSIPClientConnections[ index ]->AccessPointId() == iapId ) + { + connection = iSIPClientConnections[ index ]; + } + index++; + } + + if (!connection ) + { + MCESRV_DEBUG("CMceSipManager::ConnectionL, no connection created") + + MCESRV_DEBUG("CMceSipManager::ConnectionL, Create MceSipConnection") + connection = + CMceSipConnection::NewLC( *this, aProfile, *iProfileRegistry ); + iSIPClientConnections.AppendL( connection ); + CleanupStack::Pop( connection ); + } + + if ( !iProfileRegistry->IsEnabled( aProfile ) ) + { + iProfileRegistry->EnableL( aProfile, *connection ); + } + + __ASSERT_ALWAYS( aProfile.IsContextActive(), + User::Leave( KErrCouldNotConnect ) ); + + MCESRV_DEBUG("CMceSipManager::ConnectionL, Exit") + return *connection; + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::ConnectionL +// ----------------------------------------------------------------------------- +// +CMceSipConnection& CMceSipManager::ConnectionL( TUint32 aIAPId ) + { + CMceSipConnection* connection = NULL; + + TInt index = 0; + while ( !connection && index < iSIPClientConnections.Count() ) + { + if ( iSIPClientConnections[ index ]->AccessPointId() == aIAPId ) + { + connection = iSIPClientConnections[ index ]; + } + index++; + } + + if ( !connection ) + { + connection = CMceSipConnection::NewLC( *this, aIAPId ); + iSIPClientConnections.AppendL( connection ); + CleanupStack::Pop( connection ); + } + + return *connection; + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::CreateSubSessionL +// ----------------------------------------------------------------------------- +// +CMceCsSubSession* CMceSipManager::CreateSubSessionL( CMceCsSession& aSession, + TMceIds& aIds, + CDesC8Array& aParams ) + { + MCESRV_DEBUG("CMceSipManager::CreateSubSessionL( by client ), Entry") + + Cleanup(); + + TUint32 profileId = aIds.iProfileID; + TMceCsSessionType sessionType = (TMceCsSessionType)aIds.iManagerType; + TMceDialogType dialogType = (TMceDialogType)aIds.iDialogType; + TUint32 dialogId = aIds.iDialogID; + + CMceSipConnection* connection = NULL; + if ( profileId ) + { + CSIPProfile& profile = ProfileL( profileId ); + + connection = &ConnectionL( profile ); + } + else + { + TInt32 iapId = 0; + TLex8 accessPoint( aParams.MdcaPoint( KMceArrayIndexIAPId ) ); + accessPoint.Val( iapId ); + connection = &ConnectionL( iapId ); + } + + __ASSERT_ALWAYS( connection, User::Leave( KErrCouldNotConnect ) ); + + CMceCsSubSession* subSession = NULL; + + aIds.iSpare1 = ( connection->State() == CSIPConnection::EActive ); + + switch ( sessionType ) + { + case KMceCSSIPSession: + { + if ( iMediaManager->NatPluginManager().NatEnabledL() ) + { + if( profileId ) + { + MCESRV_DEBUG("CMceSipManager::CreateSubSessionL, NAT SIP session with profile") + subSession = CMceNatSipSession::NewLC( aSession, + *connection, + *iStateMachine, + ProfileL( profileId ), + &aParams ); + } + else + { + MCESRV_DEBUG("CMceSipManager::CreateSubSessionL, NAT SIP session without profile") + subSession = CMceNatSipSession::NewLC( aSession, + *connection, + *iStateMachine, + &aParams ); + } + + } + else + { + if( profileId ) + { + MCESRV_DEBUG("CMceSipManager::CreateSubSessionL, SIP session with profile") + subSession = CMceSipSession::NewLC( aSession, + *connection, + *iStateMachine, + ProfileL( profileId ) ); + } + else + { + MCESRV_DEBUG("CMceSipManager::CreateSubSessionL, SIP session without profile") + subSession = CMceSipSession::NewLC( aSession, + *connection, + *iStateMachine ); + } + } + break; + } + case KMceCSSIPEvent: + { + MCESRV_DEBUG("CreateSubSessionL: creating SIP event") + subSession = CMceSipEvent::NewLC( aSession, + *connection, + ProfileL( profileId ) ); + break; + } + default: + { + MCESRV_DEBUG("CreateSubSessionL: NOT SUPPORTED") + User::Leave( KErrNotSupported ); + } + } + + const CMceCsSubSession* sharedSession = NULL; + CSIPDialogAssocBase* dialog = NULL; + + if ( dialogId != KMceNotAssigned ) + { + MCESRV_DEBUG_DVALUE( + "CreateSubSessionL: find subsession with dialogId", dialogId ) + sharedSession = aSession.Implementation().FindSubSession( dialogId ); + } + + if ( sharedSession ) + { + MCESRV_DEBUG_DVALUE( + "CreateSubSessionL: creating dialog assoc to existing dialog. ID", + dialogId ) + + dialog = subSession->CreateOutgoingDialogL( + dialogType, + aParams, + sharedSession->Dialog()->Dialog() ); + subSession->SetDialog( CMceCsSubSession::EOutSession, + dialog, + sharedSession->DialogId() ); + } + else + { + MCESRV_DEBUG( "CreateSubSessionL: creating new dialog assoc" ) + dialog = subSession->CreateOutgoingDialogL( dialogType, aParams ); + subSession->SetDialog( CMceCsSubSession::EOutSession, + dialog, + NextDialogId() ); + } + + connection->AttachL( *subSession ); + CleanupStack::Pop( subSession ); + + MCESRV_DEBUG( + "CMceSipManager: CMceSipManager::CreateSubSessionL( by client ), Exit") + + return subSession; + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::CreateSubSessionL +// ----------------------------------------------------------------------------- +// +void CMceSipManager::CreateSubSessionL( CSIPServerTransaction* aTransaction, + CMceSipConnection& aConnection ) + { + MCESRV_DEBUG("CMceSipManager::CreateSubSessionL, Entry") + + User::LeaveIfError( Consumes( *aTransaction ) ? + KErrNone : + KErrNotSupported ); + + + iClientResolver->RegisterIncomingRequestL( aTransaction, aConnection ); + + MCESRV_DEBUG("CMceSipManager::CreateSubSessionL, Exit") + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::IncomingResolvedRequest +// ----------------------------------------------------------------------------- +// +void CMceSipManager::IncomingResolvedRequest( TUid aClientUid, + CMceSipConnection& aConnection, + CSIPServerTransaction* aRequest ) + { + MCESRV_DEBUG("CMceSipManager::IncomingResolvedRequest, Entry") + MCESRV_DEBUG_SVALUE("request", MceSip::Method( *aRequest ).DesC() ) + + CMceCsSession* client = NULL; + TInt i = 0; + while ( !client && i < iClients.Count() ) + { + client = iClients[ i++ ]; + if ( client->Uid() != aClientUid ) + { + client = NULL; + } + } + + TInt error = KErrNone; + if ( client ) + { + TRAP( error, CreateSubSessionL( aRequest, *client, aConnection ) ); + } + else + { + MCESRV_DEBUG("CLIENT NOT FOUND") + } + + if ( !client || error != KErrNone ) + { + MCESRV_DEBUG("IncomingResolvedRequest: discarding request") + MCESRV_DEBUG_DVALUE( "ERROR:", error ) + MceSip::DiscardRequest( aRequest, error ); + } + + MCESRV_DEBUG("CMceSipManager::IncomingResolvedRequest, Exit") + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::CreateSubSessionL +// ----------------------------------------------------------------------------- +// +void CMceSipManager::CreateSubSessionL( CSIPServerTransaction* aTransaction, + CMceCsSession& aClient, + CMceSipConnection& aConnection, + CMceCsSubSession* aAssocSession ) + { + MCESRV_DEBUG("CMceSipManager::CreateSubSessionL( from network ), Entry") + MCESRV_DEBUG_SVALUE("request", MceSip::Method( *aTransaction ).DesC() ) + + __ASSERT_ALWAYS( Consumes( *aTransaction ), User::Leave( KErrArgument ) ); + + CMceCsSubSession* session = NULL; + CSIPProfile *profile = NULL; + TUint32 profileId = 0; + + if ( aAssocSession != NULL ) + { + User::LeaveIfError( + aAssocSession->Profile().GetParameter( KSIPProfileId, profileId ) ); + } + else + { + const TDesC8* remoteContact = + &aTransaction->RequestElements()->RemoteUri().Uri().UriDes(); + + TInt len = remoteContact->Length(); + HBufC8* editRemoteContact = HBufC8::NewLC( len ); + TPtr8 desERC = editRemoteContact->Des(); + desERC.Copy( *remoteContact ); + TInt cut = desERC.Find( _L8( ":" ) ); + + if ( cut != KErrNotFound ) + { + desERC.Delete( 0, ++cut ); + len -= cut; + cut = desERC.Find( _L8( "@" ) ); + desERC.Delete( cut, len ); + + RPointerArray profiles; + iProfileRegistry->ProfilesL( profiles ); + + TInt error( KErrNone ); + const TDesC8* localContact = NULL; + TBool found( EFalse ); + for ( TInt i = 0; !found && i < profiles.Count(); i++ ) + { + profile = profiles[ i ]; + error = profile->GetParameter( KSIPContactHeaderUser, localContact ); + if ( error == KErrNone ) + { + if ( desERC.Compare( *localContact ) == 0 ) + { + User::LeaveIfError( + profile->GetParameter( KSIPProfileId, profileId ) ); + found = ETrue; + } + } + } + profiles.ResetAndDestroy(); + profiles.Close(); + } + CleanupStack::PopAndDestroy( editRemoteContact ); + } + profile = &ProfileL( profileId ); + + + RStringF method = MceSip::Method( *aTransaction ); + + if ( method == SIPStrings::StringF( SipStrConsts::EInvite ) ) + { + if ( iMediaManager->NatPluginManager().NatEnabledL() ) + { + MCESRV_DEBUG("CMceSipManager::CreateSubSessionL, NAT SIP session") + session = CMceNatSipSession::NewLC( aClient, + aConnection, + *iStateMachine, + ProfileL( profileId ) ); + } + else + { + MCESRV_DEBUG("CMceSipManager::CreateSubSessionL, SIP session") + // we can give to MceSipSession... + session = CMceSipSession::NewLC( aClient, + aConnection, + *iStateMachine, + *profile ); + } + } + else + { + MCESRV_DEBUG("IncomingResolvedRequest: creating SIP event") + session = CMceSipEvent::NewLC( aClient, aConnection, *profile ); + } + + CSIPDialogAssocBase* dialog = + session->CreateIncomingDialogL( *aTransaction ); + + TUint32 dialogId = aAssocSession ? + aAssocSession->DialogId() : NextDialogId(); + + session->SetDialog( CMceCsSubSession::EInSession, dialog, dialogId ); + + aConnection.AttachL( *session ); + + session->InitializeIncomingDialogL( aTransaction ); + + //check if session failed and is in terminated state already + if ( !session->CanDispose() ) + { + TInt error = aClient.Implementation().SubSessions().Append( session ); + if ( error != KErrNone ) + { + MCESRV_DEBUG("CMceSipManager::CreateSubSessionL: Appending failed") + session->PopRequest(); + User::Leave( error ); + } + CleanupStack::Pop( session ); + } + else + { + MCESRV_DEBUG("IncomingResolvedRequest: Initialization FAILED") + CleanupStack::PopAndDestroy( session ); + } + + MCESRV_DEBUG("CMceSipManager::CreateSubSessionL( from network ), Exit") + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::SocketServ +// ----------------------------------------------------------------------------- +// +RSocketServ& CMceSipManager::SocketServ() + { + return iSocketServ; + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::Consumes +// ----------------------------------------------------------------------------- +// +TBool CMceSipManager::Consumes( CSIPServerTransaction& aTransaction ) + { + RStringF method = MceSip::Method( aTransaction ); + + return method == SIPStrings::StringF( SipStrConsts::EInvite ) || + method == SIPStrings::StringF( SipStrConsts::ESubscribe ) || + method == SIPStrings::StringF( SipStrConsts::ERefer ); + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::AddOrphanSubSessionL +// ----------------------------------------------------------------------------- +// +void CMceSipManager::AddOrphanSubSessionL( CMceCsSubSession* aSubSession ) + { + MCESRV_DEBUG("CMceSipManager::AddOrphanSubSessionL, Entry") + MCESRV_DEBUG_DVALUE("dialogid", aSubSession->DialogId() ) + + aSubSession->SetClient( *iOrphanSubSessions ); + aSubSession->SetSessionReceiver( NULL ); + iOrphanSubSessions->SubSessions().AppendL( aSubSession ); + + MCESRV_DEBUG("CMceSipManager::AddOrphanSubSessionL, Exit") + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::OrphanSubSessionCount +// ----------------------------------------------------------------------------- +// +TInt CMceSipManager::OrphanSubSessionCount() + { + return iOrphanSubSessions->SubSessions().Count(); + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::UnRegisterSubSession +// ----------------------------------------------------------------------------- +// +void CMceSipManager::UnRegisterSubSession( CMceCsSubSession& aSubSession ) + { + MCESRV_DEBUG("CMceSipManager::UnRegisterSubSession, Entry") + + CSIPProfile* profile = NULL; + TBool profileUsed( EFalse ); + TInt err = KErrNone; + TInt index = iSIPClientConnections.Find( &aSubSession.SIPConnection() ); + + if ( index != KErrNotFound ) + { + if ( aSubSession.SIPConnection().Detach( aSubSession ) == 0 ) + { + // If no SubSessions related to the CMceSipConnection any more, + // delete the CMceSipConnection instance. + MCESRV_DEBUG("CMceSipManager::UnRegisterSubSession, remove connection") + CMceSipConnection* connection = iSIPClientConnections[ index ]; + iSIPClientConnections.Remove( index ); + delete connection; + connection = NULL; + } + if ( aSubSession.ProfileConfigured() ) + { + MCESRV_DEBUG("CMceSipManager::UnRegisterSubSession, profile configured") + TUint32 profileId = 0; + aSubSession.Profile().GetParameter( KSIPProfileId, profileId ); + + TRAP( err, profile = &ProfileL( profileId ) ); + + if ( err == KErrNone ) + { + for ( TInt i = 0; i < iSIPClientConnections.Count() && !profileUsed; i++ ) + { + profileUsed = iSIPClientConnections[ i ]->IsProfileUsedInSession( + *profile ); + } + } + } + + // Delete the unused profile after un-register a SubSession. + if ( !profileUsed ) + { + MCESRV_DEBUG("CMceSipManager::UnRegisterSubSession, profile not used anymore") + + // No need to loop downwards, as just one profile is removed + for ( TInt j = 0; j < iProfiles.Count() && profile; j++ ) + { + if ( iProfiles[ j ] == profile ) + { + MCESRV_DEBUG("CMceSipManager::UnRegisterSubSession, deleting profile") + iProfiles.Remove( j ); + delete profile; + profile = NULL; + } + } + } + } + MCESRV_DEBUG("CMceSipManager::UnRegisterSubSession, Exit") + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::FindProfileByRequestUriL +// ----------------------------------------------------------------------------- +// +TInt CMceSipManager::FindProfileByRequestUriL( + RPointerArray& aProfiles, + const CUri8& aRequestUri ) + { + TInt ret = KErrNotFound; + + // User name of request URI + const TDesC8& uriUser = aRequestUri.Uri().Extract( EUriUserinfo ); + + CSIPProfile* profile = NULL; + TInt profileInd = 0; + + while( ret == KErrNotFound && profileInd < aProfiles.Count() ) + { + // Try to find a profile with matching contact header user part + profile = aProfiles[ profileInd ]; + + const TDesC8* contactUser = NULL; + // get Contact-header's user-part + User::LeaveIfError( profile->GetParameter( KSIPContactHeaderUser, contactUser ) ); + + if ( uriUser.CompareF( *contactUser ) == 0 ) + { + ret = profileInd; + } + + profileInd++; + } + + return ret; + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::FindProfileById +// ----------------------------------------------------------------------------- +// +TInt CMceSipManager::FindProfileById( + RPointerArray& aProfiles, + TUint32 profileId ) + { + TInt index = 0; + while ( index < aProfiles.Count() ) + { + TUint32 macthId; + TInt error = aProfiles[ index ]->GetParameter( KSIPProfileId, macthId ); + if ( error == KErrNone && macthId == profileId ) + { + return index; + } + index++; + } + + return KErrNotFound; + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::IncomingRequest +// ----------------------------------------------------------------------------- +// +void CMceSipManager::IncomingRequest( + TUint32 aIapId, + CSIPServerTransaction* aTransaction ) + { + MCESRV_DEBUG("CMceSipManager::IncomingRequest, Entry") + MCESRV_DEBUG_SVALUE("request", MceSip::Method( *aTransaction ).DesC() ) + MCESRV_DEBUG_DVALUE("iapid", aIapId ) + + CMceSipConnection* connection = NULL; + CSIPProfile* profile = NULL; + + if ( !Consumes( *aTransaction ) ) + { + REJECT( aTransaction ); + } + + const CSIPRequestElements* request = aTransaction->RequestElements(); + const CSIPToHeader* to = request->ToHeader(); + if ( !to ) + { + MCESRV_DEBUG("IncomingRequest: no recipient: REJECT") + REJECT( aTransaction ); + } + + const CUri8& reqUri = request->RemoteUri(); + + TRAPD( error1, profile = &ProfileL( aIapId, reqUri ) ); + REJECT_IF_ERROR( error1, aTransaction ) + + TRAPD( error2, connection = &ConnectionL( *profile ) ); + REJECT_IF_ERROR( error2, aTransaction ) + + __ASSERT_ALWAYS( profile->IsContextActive(), + User::Leave( KErrCouldNotConnect ) ); + + TRAPD( error3, CreateSubSessionL( aTransaction, *connection ) ); + REJECT_IF_ERROR( error3, aTransaction ) + + MCESRV_DEBUG("CMceSipManager::IncomingRequest, Exit") + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::TimedOut +// ----------------------------------------------------------------------------- +// +void CMceSipManager::TimedOut( CSIPServerTransaction& /*aTransaction*/ ) + { + MCESRV_DEBUG("CMceSipManager::TimedOut, Entry") + MCESRV_DEBUG("-- NOT IMPLEMENTED --") + MCESRV_DEBUG("CMceSipManager::TimedOut, Exit") + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::ProfileRegistryEventOccurred +// If profile is updated, read its data from profile server and replace the +// local copy of profile's data. As CSIPProfile's memory address changes, also +// CMceCsSubSession::iProfile pointers must be updated. +// ----------------------------------------------------------------------------- +// +void CMceSipManager::ProfileRegistryEventOccurred( + TUint32 aProfileId, + MSIPProfileRegistryObserver::TEvent aEvent ) + { + MCESRV_DEBUG("CMceSipManager::ProfileRegistryEventOccurred(pid,event), Entry") + MCESRV_DEBUG_DVALUES( "profileId", aProfileId, "event", aEvent ) + + if ( aEvent == MSIPProfileRegistryObserver::EProfileUpdated ) + { + CSIPProfile* profile( NULL ); + TRAPD( err, profile = iProfileRegistry->ProfileL( aProfileId ) ); + + if ( profile && err == KErrNone ) + { + TInt index = FindProfileById( iProfiles, aProfileId ); + if ( index != KErrNotFound ) + { + CSIPProfile* oldProfile = iProfiles[ index ]; + UpdateProfileToSubSessions( *profile, *oldProfile ); + delete oldProfile; + // Replace pointer in iProfiles array + iProfiles[ index ] = profile; + } + else + { + err = iProfiles.Append( profile ); + if ( err != KErrNone ) + { + delete profile; + } + } + } + MCESRV_DEBUG_DVALUE( "err", err ) + } + MCESRV_DEBUG("CMceSipManager::ProfileRegistryEventOccurred(pid,event), Exit") + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::ProfileRegistryErrorOccurred +// ----------------------------------------------------------------------------- +// +void CMceSipManager::ProfileRegistryErrorOccurred( + TUint32 /*aProfileId*/, + TInt /*aError*/) + { + MCESRV_DEBUG("CMceSipManager::ProfileRegistryErrorOccurred(pid,error), Entry") + MCESRV_DEBUG("-- NOT IMPLEMENTED --") + MCESRV_DEBUG("CMceSipManager::ProfileRegistryErrorOccurred(pid,error), Exit") + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::MediaError +// ----------------------------------------------------------------------------- +// +void CMceSipManager::MediaError( TInt /*aError*/ ) + { + MCESRV_DEBUG("CMceSipManager::MediaError, Entry") + MCESRV_DEBUG("-- NOT IMPLEMENTED --") + MCESRV_DEBUG("CMceSipManager::MediaError, Exit") + } + +// ----------------------------------------------------------------------------- +// CMceSipManager::UpdateProfileToSubSessions +// ----------------------------------------------------------------------------- +// +void CMceSipManager::UpdateProfileToSubSessions( CSIPProfile& aNewProfile, + CSIPProfile& aOldProfile ) + { + MCESRV_DEBUG("CMceSipManager::UpdateProfileToSubSessions, Entry") + + TInt count = iClients.Count(); + for ( TInt i = 0; i < count; ++i ) + { + CMceCsSessionImplementation& session = iClients[ i ]->Implementation(); + RPointerArray& subSessions = session.SubSessions(); + + TInt subSessionCount = subSessions.Count(); + for ( TInt j = 0; j < subSessionCount; ++j ) + { + CSIPProfile& subSessionProfile = subSessions[ j ]->Profile(); + if ( &subSessionProfile == &aOldProfile ) + { + MCESRV_DEBUG_DVALUES("update subsession profile, i", i, "j", j ) + MCESRV_DEBUG_DVALUES("oldProfile", (TInt)&aOldProfile, + "newProfile", (TInt)&aNewProfile ) + subSessions[ j ]->SetProfile( aNewProfile ); + } + } + } + MCESRV_DEBUG("CMceSipManager::UpdateProfileToSubSessions, Exit") + }